Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions lib/atlas/exporter/graph_exporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ def to_h

private

PRECISION = 14

# Internal: Recursively rounds all Float values in a hash to PRECISION decimal places.
def round_floats(value)
case value
when Float
value.round(PRECISION)
when Hash
value.transform_values { |v| round_floats(v) }
when Array
value.map { |v| round_floats(v) }
else
value
end
end

# Internal: Given an array of +nodes+, creates a hash containing all
# of the node demands and attributes.
#
Expand Down Expand Up @@ -73,7 +89,7 @@ def nodes_hash(nodes)

attributes.delete(:queries)

hash[node.key] = attributes
hash[node.key] = round_floats(attributes)
end
end

Expand All @@ -96,14 +112,14 @@ def edges_hash(edges)

attributes.delete(:queries)

hash[model.key] = attributes
hash[model.key] = round_floats(attributes)
end

# Yay coupling carrier special cases!
EnergyEdge.all.each do |edge|
if edge.carrier == :coupling_carrier
data[edge.key] = edge.to_hash
data[edge.key][:share] = edge.child_share
data[edge.key] = round_floats(edge.to_hash)
data[edge.key][:share] = edge.child_share.to_f.round(PRECISION)
end
end

Expand All @@ -122,7 +138,7 @@ def slots_hash(slots)
if slot.get(:model).is_a?(Atlas::Slot::Elastic)
hash[slot.carrier] = :elastic
else
hash[slot.carrier] = slot.share.to_f
hash[slot.carrier] = slot.share.to_f.round(PRECISION)
end
end

Expand Down
21 changes: 19 additions & 2 deletions lib/atlas/graph_values.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def initialize(derived_dataset)
@derived_dataset = derived_dataset
end

PRECISION = 14

def values
@values ||= YAML.load_file(graph_values_path)
end
Expand All @@ -59,7 +61,7 @@ def for(element, attribute = nil)

def set(element_key, attribute, value)
values[element_key.to_s] ||= {}
values[element_key.to_s].deep_merge!(Hash[attribute.to_s, value])
values[element_key.to_s].deep_merge!(Hash[attribute.to_s, round_all_floats(value)])
end

alias_method :to_h, :values
Expand All @@ -69,12 +71,27 @@ def create!
save("--- {}")
end

def save(yaml = values.to_yaml)
def save(yaml = nil)
yaml ||= round_all_floats(values).to_yaml
File.write(graph_values_path, yaml)
end

private

# Internal: Recursively rounds all Float values to PRECISION decimal places.
def round_all_floats(value)
case value
when Float
value.round(PRECISION)
when Hash
value.transform_values { |v| round_all_floats(v) }
when Array
value.map { |v| round_all_floats(v) }
else
value
end
end

def validate_presence_of_init_keys
values.each_pair do |_, values|
next if values.blank?
Expand Down
2 changes: 1 addition & 1 deletion spec/atlas/exporter/graph_exporter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
mother.set(:max_demand, 50)
mother.get(:model).max_demand = 50.0

expect(nodes[:mother][:max_demand]).to eq(50)
expect(nodes[:mother][:max_demand]).to be_within(1e-13).of(50)
end

it 'is not exported when not specified in the document' do
Expand Down
4 changes: 2 additions & 2 deletions spec/atlas/graph_values_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module Atlas; describe GraphValues do
graph_values.set(node.key.to_s, :demand, 50.0)
graph_values.save

expect(graph_values.to_h['bar']['demand']).to eq(50.0)
expect(graph_values.to_h['bar']['demand']).to be_within(1e-13).of(50.0)
end
end

Expand All @@ -66,7 +66,7 @@ module Atlas; describe GraphValues do
graph_values.set(node.key.to_s, :demand, 50.0)
graph_values.save

expect(graph_values.to_h['bar']['demand']).to eq(50.0)
expect(graph_values.to_h['bar']['demand']).to be_within(1e-13).of(50.0)
end
end

Expand Down