Class: AMEE::DataAbstraction::OngoingCalculation

Inherits:
Calculation
  • Object
show all
Defined in:
lib/amee-data-abstraction/ongoing_calculation.rb

Overview

Instances of the OngoingCalculation class represent actual calculations made via the AMEE platform.

The class inherits from the Calculation class and is therefore primarly characterised by the label, name, and path attributes, as well as an associated instance of the TermsList class which represents each of the values (input, outputs, metdata) involved in the calculation.

Instances of OngoingCalcualtion are typically instantiated from an instance of PrototypeCalculation using the #begin_calculation method, e.g.

my_prototype.begin_calculation       #=> <AMEE::DataAbstraction::OngoingCalculation ...>

In this case, the new instance inherits all of the attributes and terms defined on the PrototypeCalculation template.

In contrast to instances of PrototypeCalculation, instances of the OngoingCalculation class will typically have their term values explicitly set according to the specific calculation scenario being represented. Other term attributes, e.g. units, may also be modified on a calculation-by-calculation basis. These values and other attributes form (at least some of) the data which is passed to the AMEE platform in order to make caluclations.

Instance Attribute Summary collapse

Attributes inherited from Calculation

#contents

Instance Method Summary collapse

Methods inherited from Calculation

#[], #amee_ivds, #amee_usages, #current_usage, #discover_url, #explorer_url, #initialize_copy, #inspect, #terms

Constructor Details

#initializeOngoingCalculation

Construct an Ongoing Calculation. Should be called only via PrototypeCalculation#begin_calculation. Not intended for external use.



55
56
57
58
59
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 55

def initialize
  super
  dirty!
  reset_invalidity_messages
end

Instance Attribute Details

#invalidity_messagesObject

Hash of invalidity messages. Keys are represent the labels of terms assocaited with self. Values are string error message reports associated with the keyed term.



49
50
51
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 49

def invalidity_messages
  @invalidity_messages
end

#profile_item_uidObject

String representing the AMEE platform profile item UID assocaited with self



43
44
45
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 43

def profile_item_uid
  @profile_item_uid
end

#profile_uidObject

String representing the AMEE platform profile UID assocaited with self



40
41
42
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 40

def profile_uid
  @profile_uid
end

Instance Method Details

#==(other_calc) ⇒ Object



243
244
245
246
247
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 243

def ==(other_calc)
  !terms.inject(false) do |boolean,term|
    boolean || term != other_calc[term.label]
  end && label == other_calc.label
end

#amee_drill(options = {}) ⇒ Object

Instantiate an AMEE::Data::DrillDown object representing the drill down sequence defined by the drill terms associated with self. As with #drill_options, An optional hash argument can be provided, with the key :before in order to specify the drill down choice to which the representation is required, e.g.

my_calc.amee_drill(:before => :size)


547
548
549
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 547

def amee_drill(options={})
  AMEE::Data::DrillDown.get(connection,"/data#{path}/drill?#{drill_options(options)}")
end

#autodrillObject

Automatically set the value of a drill term if there is only one choice



520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 520

def autodrill
  
  picks=amee_drill.selections
  picks.each do |path,value|
    # If drill term does not exist, initialize a dummy instance.
    # 
    # This is useful in those cases where some drills selections are unecessary
    # (i.e. not all choices require selection for data items to be uniquely
    # identified) and removes the need to explicitly specify the blank drills
    # in configuration. This doesn't matter if calculations are auto configured.
    #
    if drill = drill_by_path(path)
      drill.value value
    else
      drills << Drill.new {path path; value value}
    end
  end
end

#calculate!Object

Synchonizes the current term values and attributes with the AMEE platform if self is dirty?, and subsequently calls clean! on self



198
199
200
201
202
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 198

def calculate!
  return unless dirty?
  syncronize_with_amee
  clean!
end

#choose(choice) ⇒ Object

Similar to #choose! but returns false if any term attributes are invalid, rather than raising an exception. Returns true if validation is successful.



185
186
187
188
189
190
191
192
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 185

def choose(choice)
  begin
    choose!(choice)
    return true
  rescue AMEE::DataAbstraction::Exceptions::ChoiceValidation
    return false
  end
end

#choose!(choice) ⇒ Object

Similar to #choose_without_validation! but performs validation on the modified input terms and raises a ChoiceValidation exception if any of the values supplied is invalid



174
175
176
177
178
179
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 174

def choose!(choice)
  choose_without_validation!(choice)
  validate!
  raise AMEE::DataAbstraction::Exceptions::ChoiceValidation.new(invalidity_messages) unless
    invalidity_messages.empty?
end

#choose_without_validation!(choice) ⇒ Object

Mass assignment of (one or more) term attributes (value, unit, per_unit) based on data defined in choice. choice should be a hash with keys representing the labels of terms which are to be updated. Hash values can represent either the the value to be assigned explicitly, or, alternatively, a hash representing any or all of the term value, unit and per_unit attributes (keyed as :value, :unit and :per_unit).

Unit attributes can be represented by any form which is accepted by the Quantify::Unit#for method (either an instance of Quantify::Unit::Base (or subclass) or a symbolized or string representation of the a unit symbol, name or label).

Nil values are ignored. Term attributes can be intentionally blanked by passing a blank string as the respective hash value.

Examples of options hash which modify only term values:

options = { :type => 'van' }

options = { :type => 'van',
            :distance => 100 }

options = { :type => 'van',
            :distance => "" }

Examples of options hash which modify other term attributes:

options = { :type => 'van',
            :distance => { :value => 100 }}

options = { :type => 'van',
            :distance => { :value => 100,
                           :unit => :mi }}

options = { :type => 'van',
            :distance => { :value => 100,
                           :unit => 'feet' }}

my_distance_unit = <Quantify::Unit::NonSI:0xb71cac48 @label="mi" ... >
my_time_unit     = <Quantify::Unit::NonSI:0xb71c67b0 @label="h" ... >

options = { :type => 'van',
            :distance => { :value => 100,
                           :unit => my_unit,
                           :per_unit => my_time_unit }}

my_calculation.choose_without_validation!(options)

Do not attempt to check that the values specified are acceptable.



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
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 144

def choose_without_validation!(choice)
  # Make sure choice keys are symbols since they are mapped to term labels
  # Uses extension methods for Hash defined in /core_extensions
  choice = choice.recursive_symbolize_keys

  new_profile_uid= choice.delete(:profile_uid)
  self.profile_uid=new_profile_uid if new_profile_uid
  new_profile_item_uid= choice.delete(:profile_item_uid)
  self.profile_item_uid=new_profile_item_uid if new_profile_item_uid
  choice.each do |k,v|
    next unless self[k]
    if v.is_a? Hash
      # <tt>if has_key?</tt> clause included so that single attributes can
      # be updated without nullifying others if their values are not
      # explicitly passed. Intentional blanking of values is enabled by
      # passing nil or "".
      #
      self[k].value v[:value] if v.has_key?(:value)
      self[k].unit v[:unit] if v.has_key?(:unit)
      self[k].per_unit v[:per_unit] if v.has_key?(:per_unit)
    else
      self[k].value v
    end
  end
end

#clean!Object

Declare that the calculation is not dirty, and need not be sent to AMEE for results to be valid.



81
82
83
84
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 81

def clean!
  inputs.each{|i| i.clean!}
  @dirty=false
end

#clear_invalid_terms!Object

Set the values of any invalid terms to nil. Can be called following any of the #choose... methods so that invalid terms resulting from modification of a previously valid calculation can be cleared. This is particularly useful in cases where drill down choices have been changed thus invalidating the choices for subsequent drills.



230
231
232
233
234
235
236
237
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 230

def clear_invalid_terms!
  terms.select do |term|
    invalidity_messages.keys.include?(term.label)
  end.each do |term|
    term.value nil
  end
  reset_invalidity_messages
end

#clear_outputsObject



239
240
241
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 239

def clear_outputs
  outputs.each {|output| output.value nil }
end

#dirty!Object

Declare that the calculation is dirty, i.e. that changes to term values have been made since self was last synchronized with the AMEE platform, in which case a synchonization with with AMEE must occur for self to be valid.



74
75
76
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 74

def dirty!
  @dirty=true
end

#dirty?Boolean

Returns true if the value of a term associated with self has been changed since the calculation was last synchronized with the AMEE platform. Otherwise, return false.

Returns:

  • (Boolean)


65
66
67
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 65

def dirty?
  @dirty
end

#invalid(label, message) ⇒ Object

Declare that the term labelled by label has an unnaceptable value and load the message into the invalidity_messages hash.



220
221
222
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 220

def invalid(label,message)
  @invalidity_messages[label]=message
end

#satisfied?Boolean

Returns true if all compulsory terms are set, i.e. ahve non-nil values. This inidicates that self is ready to be sent to the AMEE platform for outputs to be calculated

Returns:

  • (Boolean)


90
91
92
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 90

def satisfied?
  inputs.compulsory.unset.empty?
end

#validate!Object

Check that the values set for all terms are acceptable, and raise a ChoiceValidation exception if not. Error messages are available via the self.invalidity_messages hash.



208
209
210
211
212
213
214
215
# File 'lib/amee-data-abstraction/ongoing_calculation.rb', line 208

def validate!
  return unless dirty?
  reset_invalidity_messages
  inputs.each do |d|
    d.validate! unless d.unset?
  end
  autodrill
end