class Bones::Species
The species class contains ‘algorithm classes’, or ‘species’. Individual species contain a number of input and output structures and possibly a prefix.
Examples of species are found below:
0:9|element -> 0:0|shared 0:31,0:31|neighbourhood(-1:1,-1:1) -> 0:31,0:31|element unordered 0:99,0:9|chunk(0:0,0:9) -> 0:99|element
Naming conventions¶ ↑
The species class uses several naming conventions within functions. They are as follows for the example species ‘0:31,0:15|neighbourhood(-1:1,-1:1) ^ 0:31,0:15|element -> 0:31,0:15|element’:
- input
-
‘0:31,0:15|neighbourhood(-1:1,-1:1) ^ 0:31,0:15|element’
- output
-
‘0:31,0:15|element’
- structures
-
[‘0:31,0:15|neighbourhood(-1:1,-1:1)’, ‘0:31,0:15|element’, ‘0:31,0:15|element’]
- structure
-
‘0:31,0:15|neighbourhood(-1:1,-1:1)’ or ‘0:31,0:15|element’ (twice)
- pattern
-
‘neighbourhood’ or ‘element’
- ranges
-
[‘0:31’, ‘0:15’] or [‘-1:1’, ‘-1:1’]
- range
-
‘0:31’ or ‘0:15’ or ‘-1:1’
- from
-
‘0’ or ‘-1’
- to
-
‘31’ or ‘15’ or ‘1’
- sum
-
‘32’ or ‘16’ or ‘3’
Attributes
Public Class Methods
Initializes the species with a prefix, inputs and out- puts. It additionally verifies the correctness of the provided raw data.
# File lib/bones/species.rb 35 def initialize(prefix, input, output) 36 @prefix = prefix 37 @name = (input+' '+ARROW+' '+output) 38 @inputs = set_structures(input) 39 @outputs = set_structures(output) 40 @skeleton_name = nil 41 @settings = nil 42 self.verify_species 43 end
Public Instance Methods
Method to return an array of structures for both direc- tions.
# File lib/bones/species.rb 59 def all_structures 60 @inputs + @outputs 61 end
This method implements the match between a species’ structure and a structure found in the mapping file. It is called from the match_species
method. It first checks for a pattern match, followed by a match of the dimensions. The method returns either true or false. TODO: Complete the matching (N-dimensional).
# File lib/bones/species.rb 136 def match?(file,search) 137 if (file =~ /#{search.pattern}/) 138 condition = true 139 140 # Check for parameters 141 if file.split('(').length == 2 142 parameters = file.split('(')[1].split(')')[0] 143 if (parameters == 'D') || 144 ((parameters == 'N') && (search.parameters.length == 1)) || 145 ((parameters == 'N,N') && (search.parameters.length == 2)) || 146 ((parameters == 'N,1') && (search.parameters.length == 2) && simplify(sum(search.parameters[1])) == '1') || 147 ((parameters == '1,N') && (search.parameters.length == 2) && simplify(sum(search.parameters[0])) == '1') || 148 ((parameters == search.parameters.map { |r| simplify(sum(r)) }.join(','))) 149 condition = condition && true 150 else 151 condition = false 152 end 153 end 154 155 # Check for dimensions 156 dimensions = file.split(PIPE)[0].strip 157 if (dimensions == 'D') || 158 ((dimensions == 'N') && (search.dimensions.length == 1)) || 159 ((dimensions == 'N,N') && (search.dimensions.length == 2)) || 160 ((dimensions == search.dimensions.map { |r| simplify(sum(r)) }.join(','))) 161 condition = condition && true 162 else 163 condition = false 164 end 165 166 # Return 167 return true if condition == true 168 end 169 return false 170 end
This method is called by the set_skeleton
method. It performs a match between the current species and the species found in the mapping file. The matching is based on a fixed order of patterns. The method returns either true or false.
# File lib/bones/species.rb 110 def match_species?(file_data) 111 DIRECTIONS.each_with_index do |direction,num_direction| 112 file_structures = file_data[num_direction].split(WEDGE) 113 counter = 0 114 search_structures = ordered(direction,['chunk','neighbourhood','element','shared','void']) 115 search_structures.each do |search_structure| 116 if !match?(file_structures[counter],search_structure) 117 if (counter != 0) && (file_structures[counter-1] =~ /\+/) && match?(file_structures[counter-1],search_structure) 118 counter = counter - 1 119 else 120 return false 121 end 122 end 123 counter = counter + 1 124 end 125 return false if counter != file_structures.length 126 end 127 return true 128 end
Method to return an ordered array of structures in a given direction. The order is specified by an argument which contains a list of pattern names.
# File lib/bones/species.rb 66 def ordered(direction,order) 67 ordered = [] 68 order.each do |pattern_name| 69 self.structures(direction).each do |structure| 70 ordered.push(structure) if structure.pattern == pattern_name 71 end 72 end 73 74 # Remove structures with a duplicate name (for matching only - and only if names are given) 75 if ordered.all? { |s| s.name != "" } 76 names = [] 77 ordered.each do |structure| 78 ordered.delete(structure) if names.include?(structure.name) 79 names.push(structure.name) 80 end 81 end 82 return ordered 83 end
This method maps an algorithm species to a skeleton. This is done based on a mapping file provided as part of the skeleton library. If multiple skeletons match the current species, the first found match is taken. This method does not return any values, but instead sets the class variables skeleton_name
and settings
.
# File lib/bones/species.rb 91 def set_skeleton(mapping_file) 92 matches = [] 93 File.read(mapping_file).each_line do |line| 94 next if line =~ /^#/ 95 data = line.split(/\s:/) 96 matches.push(data) if match_species?(data[0].split(ARROW)) 97 end 98 puts MESSAGE+'Multiple matches in skeleton file, selecting the first listed' if matches.length > 1 99 if matches.length != 0 100 @skeleton_name = matches[0][1].delete(':').strip 101 @settings = matches[0][2].delete(':').strip 102 end 103 end
This method splits the raw data (a string) into seperate structures. The method returns an array of structures.
# File lib/bones/species.rb 47 def set_structures(raw_data) 48 raw_data.split(WEDGE).map { |structure| Structure.new(structure) } 49 end
Method to return an array of structures in a given di- rection.
# File lib/bones/species.rb 53 def structures(direction) 54 (direction == INPUT) ? @inputs : @outputs 55 end
This method verifies if the species dimensions match with its parameters in terms of number of dimensions.
# File lib/bones/species.rb 181 def verify_species 182 DIRECTIONS.each do |direction| 183 structures(direction).each do |structure| 184 if (structure.has_parameter?) && (structure.dimensions.length != structure.parameters.length) 185 puts WARNING+'Parameter dimension mismatch: '+structure.parameters.inspect+' versus '+structure.dimensions.inspect 186 end 187 structure.dimensions.each do |dimension| 188 puts WARNING+'Negative range given: '+dimension.inspect if (simplify(sum(dimension)).to_i < 1) && !(sum(dimension) =~ /[a-zA-Z]/) 189 end 190 end 191 end 192 end