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
16
17
18
# 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]
	@livetime	= options.key?(:livetime) ? options[:livetime] : 1
	@activity	= options.key?(:activity) ? options[:activity] : 1
	@count_correction = options.key?(:count_correction) ? options[:count_correction] : 1
end

Instance Attribute Details

#activityObject

Returns the value of attribute activity.



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

def activity
  @activity
end

#calibrationObject

Returns the value of attribute calibration.



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

def calibration
  @calibration
end

#count_correctionObject

Returns the value of attribute count_correction.



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

def count_correction
  @count_correction
end

#livetimeObject

Returns the value of attribute livetime.



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

def livetime
  @livetime
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



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

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



79
80
81
# File 'lib/radiation/spectrum.rb', line 79

def channel_efficiency(peak)
	peak[:counts]*@count_correction/(peak[:intensity]*@livetime*@activity)
end

#channel_energy(chn) ⇒ Object



47
48
49
# File 'lib/radiation/spectrum.rb', line 47

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

#efficiencies(rounding = 4) ⇒ Object



60
61
62
63
64
# File 'lib/radiation/spectrum.rb', line 60

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



38
39
40
41
42
43
44
45
# File 'lib/radiation/spectrum.rb', line 38

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



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/radiation/spectrum.rb', line 66

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



51
52
53
54
55
56
57
58
# File 'lib/radiation/spectrum.rb', line 51

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