Class: Radiation::Spectrum

Inherits:
Object
  • Object
show all
Defined in:
lib/radiation/spectrum.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Spectrum

Returns a new instance of Spectrum.



11
12
13
14
15
# File 'lib/radiation/spectrum.rb', line 11

def initialize(options={})
	@peaks		= options.key?(:peaks) ? options[:peaks] : []
	@source		= options.key?(:source) ? options[:source] : nil
	@calibration= options.key?(:calibration) ? options[:calibration] : [0, 1]
end

Instance Attribute Details

#calibrationObject

Returns the value of attribute calibration.



9
10
11
# File 'lib/radiation/spectrum.rb', line 9

def calibration
  @calibration
end

#peaksObject

Returns the value of attribute peaks.



9
10
11
# File 'lib/radiation/spectrum.rb', line 9

def peaks
  @peaks
end

#sourceObject

Returns the value of attribute source.



9
10
11
# File 'lib/radiation/spectrum.rb', line 9

def source
  @source
end

Instance Method Details

#calibrateObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/radiation/spectrum.rb', line 17

def calibrate
	if @peaks.empty? or @peaks.select{|p| p.key?(:channel)}.empty?
		raise "Nothing to calibrate"
	end
	
	if @peaks.select{|p| p.key?(:channel) and p.key?(:energy)}.empty?
		if @calibration == [0,1] and @source.nil?
			raise "No channel <-> energy associations. Specify a Source or a preliminary calibration to improve"
		else
			self.guess_calibration
		end
		self.match_channels
	end

	@calibration = apply_linefit(@peaks)
	return self
end

#channel_efficiency(peak) ⇒ Object



76
77
78
# File 'lib/radiation/spectrum.rb', line 76

def channel_efficiency(peak)
	peak[:counts]/peak[:intensity]
end

#channel_energy(chn) ⇒ Object



44
45
46
# File 'lib/radiation/spectrum.rb', line 44

def channel_energy(chn)
	@calibration[0] + @calibration[1]*chn
end

#efficiencies(rounding = 4) ⇒ Object



57
58
59
60
61
# File 'lib/radiation/spectrum.rb', line 57

def efficiencies(rounding=4)
	self.match_channels
	@peaks.select{|p| p.key?(:intensity) and p.key?(:counts)}.each{|p| p[:efficiency] = channel_efficiency(p)}
	return self
end

#guess_calibration(energies = @source.energies, rounding = 4) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/radiation/spectrum.rb', line 35

def guess_calibration(energies=@source.energies, rounding=4)
	# Build all possible combinations of known energies and peaks
	arr = [energies, @peaks.collect{|peak| peak[:channel]}].comprehension
	# The approximate value for b in $Energy = a + b * Channel$ will be most frequent for $a \approx 0$
	freq = arr.collect{|a| (a.first.to_f/a.last.to_f).round(rounding) }.flatten.inject(Hash.new(0)) { |h,v| h[v] += 1; h }.sort_by{|k,v| v}
	@calibration = [0, freq.last[0] ]
	return self
end

#match_channels(source = @source, rounding = 4) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/radiation/spectrum.rb', line 63

def match_channels(source=@source, rounding=4)
	@peaks.each do |peak|
		source.transitions.each do |transition|
			if channel_energy(peak[:channel]).to_f.approx_equal?(transition[:energy], rounding)
				peak[:energy] = transition[:energy]
				peak[:intensity] = transition[:intensity] if transition[:intensity] > 0
			end
		end
	end
	return self
end

#parse_hdtv(file) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/radiation/spectrum.rb', line 48

def parse_hdtv(file)
	xml = XmlSimple.xml_in(file, { 'KeyAttr' => 'name' })
	@peaks = xml["fit"].collect{|p| p["peak"]}.flatten.collect{|p| p["uncal"]}.flatten.collect do |p|
		{:channel => p["pos"].first["value"].first.to_f.pm(p["pos"].first["error"].first.to_f),
 		:counts => p["vol"].first["value"].first.to_f.pm(p["vol"].first["error"].first.to_f) } 
	end
	return self
end