diff --git a/lib/avm/image.rb b/lib/avm/image.rb index 1641ef5..5d8fcca 100644 --- a/lib/avm/image.rb +++ b/lib/avm/image.rb @@ -8,17 +8,25 @@ module AVM DUBLIN_CORE_FIELDS = [ :title, :description ] AVM_SINGLE_FIELDS = [ 'Distance.Notes', 'ReferenceURL', 'Credit', 'Date', 'ID', 'Type', 'Image.ProductQuality' ] - attr_reader :creator + attr_reader :creator, :observations def initialize(options = {}) @creator = AVM::Creator.new(self) @options = options + @observations = [] + end + + def create_observation(options) + observation = Observation.new(self, options) + @observations << observation + observation end def to_xml document = AVM::XMP.new creator.add_to_document(document) + Observation.add_to_document(document, observations) document.get_refs do |refs| DUBLIN_CORE_FIELDS.each do |field| diff --git a/lib/avm/observation.rb b/lib/avm/observation.rb new file mode 100644 index 0000000..8b2f1ee --- /dev/null +++ b/lib/avm/observation.rb @@ -0,0 +1,41 @@ +module AVM + class Observation + AVM_SINGLE_FIELDS = %w{Facility Instrument Spectral.ColorAssignment Spectral.Band Spectral.Bandpass Spectral.CentralWavelength Spectral.Notes Temporal.StartTime Temporal.IntegrationTime DatasetID} + AVM_SINGLE_METHODS = [ :facility, :instrument, :color_assignment, :band, :bandpass, :wavelength, :notes, :string_start_time, :integration_time, :dataset_id ] + AVM_SINGLES = AVM_SINGLE_FIELDS.zip(AVM_SINGLE_METHODS) + + attr_reader :image, :options + + def initialize(image, options = {}) + @image, @options = image, options + end + + def method_missing(method) + @options[method] + end + + def start_time + (Time.parse(@options[:start_time]) rescue nil) + end + + def string_start_time + start_time.strftime('%Y-%m-%dT%H:%M') + end + + def self.add_to_document(document, observations) + field_values = {} + AVM_SINGLES.each do |name, method| + observations.each do |observation| + field_values[name] ||= [] + field_values[name] << observation.send(method) + end + end + + document.get_refs do |refs| + field_values.each do |name, value| + refs[:avm].add_child(%{#{value.join(',')}}) + end + end + end + end +end diff --git a/spec/avm/observation_spec.rb b/spec/avm/observation_spec.rb new file mode 100644 index 0000000..ec8025c --- /dev/null +++ b/spec/avm/observation_spec.rb @@ -0,0 +1,131 @@ +require 'spec_helper' +require 'avm/image' +require 'avm/observation' + +describe AVM::Observation do + let(:image) { AVM::Image.new } + let(:observation) { image.create_observation(options) } + + subject { observation } + + let(:facility) { 'HST' } + let(:instrument) { 'ACS' } + let(:color_assignment) { 'Blue' } + let(:band) { 'em.opt' } + let(:bandpass) { 'B' } + let(:wavelength) { 2.5 } + let(:notes) { 'Notes' } + let(:start_time) { '2010-01-01' } + let(:start_time_string) { '2010-01-01T00:00' } + let(:integration_time) { '300' } + let(:dataset_id) { '12345' } + + let(:options) { { + :facility => facility, + :instrument => instrument, + :color_assignment => color_assignment, + :band => band, + :bandpass => bandpass, + :wavelength => wavelength, + :notes => notes, + :start_time => start_time, + :integration_time => integration_time, + :dataset_id => dataset_id, + } } + + context 'defaults' do + its(:facility) { should == facility } + its(:instrument) { should == instrument } + its(:color_assignment) { should == color_assignment } + its(:band) { should == band } + its(:bandpass) { should == bandpass } + its(:wavelength) { should == wavelength } + its(:notes) { should == notes } + its(:start_time) { should == Time.parse(start_time) } + its(:integration_time) { should == integration_time } + its(:dataset_id) { should == dataset_id } + end + + describe '.add_to_document' do + let(:xml) { image.to_xml } + let(:avm) { xml.at_xpath('//rdf:Description[@rdf:about="AVM"]') } + + context 'none' do + it "should not have any observation information" do + %w{Facility Instrument Spectral.ColorAssignment Spectral.Band Spectral.Bandpass Spectral.CentralWavelength Spectral.Notes Temporal.StartTime Temporal.IntegrationTime DatasetID}.each do |name| + avm.at_xpath("//avm:#{name}").should be_nil + end + end + end + + context 'one' do + before { observation } + + it "should have the AVM values" do + { + 'Facility' => facility, + 'Instrument' => instrument, + 'Spectral.ColorAssignment' => color_assignment, + 'Spectral.Band' => band, + 'Spectral.Bandpass' => bandpass, + 'Spectral.CentralWavelength' => wavelength, + 'Spectral.Notes' => notes, + 'Temporal.StartTime' => start_time_string, + 'Temporal.IntegrationTime' => integration_time, + 'DatasetID' => dataset_id + }.each do |name, value| + avm.at_xpath("//avm:#{name}").text.should == value.to_s + end + end + end + + context 'two' do + let(:second_observation) { image.create_observation(second_options) } + + let(:second_facility) { 'Chandra' } + let(:second_instrument) { 'X-Ray' } + let(:second_color_assignment) { 'Green' } + let(:second_band) { 'em.x-ray' } + let(:second_bandpass) { 'C' } + let(:second_wavelength) { nil } + let(:second_notes) { 'More Notes' } + let(:second_start_time) { '2010-01-02' } + let(:second_start_time_string) { '2010-01-02T00:00' } + let(:second_integration_time) { '400' } + let(:second_dataset_id) { '23456' } + + let(:second_options) { { + :facility => second_facility, + :instrument => second_instrument, + :color_assignment => second_color_assignment, + :band => second_band, + :bandpass => second_bandpass, + :wavelength => second_wavelength, + :notes => second_notes, + :start_time => second_start_time, + :integration_time => second_integration_time, + :dataset_id => second_dataset_id, + } } + + before { observation ; second_observation } + + it "should have the AVM values" do + { + 'Facility' => [ facility, second_facility ].join(','), + 'Instrument' => [ instrument, second_instrument ].join(','), + 'Spectral.ColorAssignment' => [ color_assignment, second_color_assignment ].join(','), + 'Spectral.Band' => [ band, second_band ].join(','), + 'Spectral.Bandpass' => [ bandpass, second_bandpass ].join(','), + 'Spectral.CentralWavelength' => [ wavelength, second_wavelength ].join(','), + 'Spectral.Notes' => [ notes, second_notes ].join(','), + 'Temporal.StartTime' => [ start_time_string, second_start_time_string ].join(','), + 'Temporal.IntegrationTime' => [ integration_time, second_integration_time ].join(','), + 'DatasetID' => [ dataset_id, second_dataset_id ].join(',') + }.each do |name, value| + avm.at_xpath("//avm:#{name}").text.should == value.to_s + end + end + + end + end +end