radiation 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YjYxM2U4YjVkYWQxNzM2YTM0MjBiNWQwYTMzNDAwYzU5MTdhYzNkNg==
5
- data.tar.gz: !binary |-
6
- NjE0ZTlkNGM1OTg4ZjU5YjVlZWFhZGM5NTBlODcyMjA4OTYwMTBiMA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MjdjZTVkYmUwZDljOGM0MWVjYjEyMzBiYzVmZjc1YjE1ZTYxYzQ0OGUzNjhl
10
- Yjc4OWZjOWI2NmM1OGY2NjZmYzg2YTlhNzdjYzFjMjllMzVhZjJjMGFmNmNl
11
- OGZjMDZmM2FkZmM3Njg0MjJhOWZiOWJhYTk4ZTdiYzk4N2U4MjE=
12
- data.tar.gz: !binary |-
13
- MTk2ZTFhY2E0ZWVkZGExYzUxN2U4MTc5NWQ2MjAyMGY0ZGEyNTQ5NTA0ZDEy
14
- MjkwMzk5ZDdkMWYzNjM4NDZjNzU2NzFmN2YxYzE1NzVjOTI4ZTIyMGQ3YTkw
15
- MWM4MzkxNzgyYjY4ODliYzc2ZDQ1M2M2NGUyYTY2MTU0NGFjYWI=
2
+ SHA1:
3
+ metadata.gz: f4777bfcdb25af513bc85c5a8a87a9402d2c7116
4
+ data.tar.gz: 8e38aeb601be484f3d3b9642d873ce7f95247881
5
+ SHA512:
6
+ metadata.gz: 3c36ef60bbad784228d316ba6a7253b8db45cb4c442ae3613d722cabdfe67ab8f13b119f23e56120ae1348b5a46ab53efc58f1e0c30df51f9cac44ebed237fca
7
+ data.tar.gz: ba9770278d22456442c173032169457978bab3f12fd6f38088afc36ae6c8cb445699963d0e3ccf30fa7f5e65046c214d5cf8ea8623706fca68794bc8e626009e
data/.gitignore CHANGED
@@ -1,17 +1,17 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec CHANGED
@@ -1 +1 @@
1
- #--color
1
+ #--color
data/.travis.yml CHANGED
@@ -1,9 +1,7 @@
1
- language: ruby
2
- rvm:
3
- #- "1.8.7"
4
- - "1.9.2"
5
- - "1.9.3"
6
- #- jruby-18mode # JRuby in 1.8 mode
7
- - jruby-19mode # JRuby in 1.9 mode
8
- #- rbx-18mode
9
- - rbx-19mode
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
5
+ - "2.0.0"
6
+ - jruby-19mode # JRuby in 1.9 mode
7
+ - rbx-19mode
data/CHANGELOG.md CHANGED
@@ -1,12 +1,12 @@
1
- ## v0.0.3
2
-
3
- * Added basic parsing for hdtv xml files
4
- * Changed dependency for linefit
5
-
6
- ## v0.0.2
7
-
8
- * Added spectrum class with energy calibration options
9
-
10
- ## v0.0.1
11
-
12
- * initial release
1
+ ## v0.0.3
2
+
3
+ * Added basic parsing for hdtv xml files
4
+ * Changed dependency for linefit
5
+
6
+ ## v0.0.2
7
+
8
+ * Added spectrum class with energy calibration options
9
+
10
+ ## v0.0.1
11
+
12
+ * initial release
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
- source 'https://rubygems.org'
2
-
3
- #gem "linefit", git: "https://github.com/janmayer/linefit.git"
4
- # Specify your gem's dependencies in radiation.gemspec
5
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ #gem "linefit", git: "https://github.com/janmayer/linefit.git"
4
+ # Specify your gem's dependencies in radiation.gemspec
5
+ gemspec
data/LICENSE.txt CHANGED
@@ -1,22 +1,22 @@
1
- Copyright (c) 2013 Jan Mayer
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2013 Jan Mayer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,45 +1,45 @@
1
- # Radiation
2
- [![Gem Version](https://badge.fury.io/rb/radiation.png)](http://badge.fury.io/rb/radiation)
3
- [![Build Status](https://travis-ci.org/janmayer/radiation.png?branch=master)](https://travis-ci.org/janmayer/radiation)
4
- [![Code Climate](https://codeclimate.com/github/janmayer/radiation.png)](https://codeclimate.com/github/janmayer/radiation)
5
-
6
- This gem provides easy access to energies and intensities from the decay of radioactive nuclei.
7
- Currently two data sources are accessible: Internal (see bib files in `./data/`) and recommended values
8
- by [Laboratoire National Henri Becquerel](http://www.nucleide.org/DDEP_WG/DDEPdata.htm).
9
-
10
- ## Example Usage
11
-
12
- ### Command line interface
13
-
14
- $> radiation
15
-
16
- ### In your ruby files:
17
-
18
- require "radiation"
19
- Radiation::Source.new(nuclide: "Ra-226").energies.collect{|e| e.value}
20
-
21
- See also files in `./samples/`.
22
-
23
- ## Planned features
24
-
25
- * Efficiency calibration for given peaks or spectra
26
- * Better access to resources
27
-
28
-
29
- ## Installation
30
-
31
- Requirement is a (local) ruby with rubygems. Using rvm is recommended
32
-
33
- $ \curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3
34
-
35
- Add this line to your application's Gemfile:
36
-
37
- gem 'radiation'
38
-
39
- And then execute:
40
-
41
- $ bundle
42
-
43
- Or install it yourself as:
44
-
45
- $ gem install radiation
1
+ # Radiation
2
+ [![Gem Version](https://badge.fury.io/rb/radiation.png)](http://badge.fury.io/rb/radiation)
3
+ [![Build Status](https://travis-ci.org/janmayer/radiation.png?branch=master)](https://travis-ci.org/janmayer/radiation)
4
+ [![Code Climate](https://codeclimate.com/github/janmayer/radiation.png)](https://codeclimate.com/github/janmayer/radiation)
5
+
6
+ This gem provides easy access to energies and intensities from the decay of radioactive nuclei.
7
+ Currently two data sources are accessible: Internal (see bib files in `./data/`) and recommended values
8
+ by [Laboratoire National Henri Becquerel](http://www.nucleide.org/DDEP_WG/DDEPdata.htm).
9
+
10
+ ## Example Usage
11
+
12
+ ### Command line interface
13
+
14
+ $> radiation
15
+
16
+ ### In your ruby files:
17
+
18
+ require "radiation"
19
+ Radiation::Source.new(nuclide: "Ra-226").energies.collect{|e| e.value}
20
+
21
+ See also files in `./samples/`.
22
+
23
+ ## Planned features
24
+
25
+ * Efficiency calibration for given peaks or spectra
26
+ * Better access to resources
27
+
28
+
29
+ ## Installation
30
+
31
+ Requirement is a (local) ruby with rubygems. Using rvm is recommended
32
+
33
+ $ \curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3
34
+
35
+ Add this line to your application's Gemfile:
36
+
37
+ gem 'radiation'
38
+
39
+ And then execute:
40
+
41
+ $ bundle
42
+
43
+ Or install it yourself as:
44
+
45
+ $ gem install radiation
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task default: :spec
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/lib/radiation/cli.rb CHANGED
@@ -34,5 +34,27 @@ class CLI < Thor
34
34
  spectrum.calibrate.calibration.each{|c| puts c}
35
35
  end
36
36
 
37
+ option :resource
38
+ option :mini
39
+ desc "efficiency NUCLIDE SPECTRUM.xml", "calculate efficiencies for a spectrum"
40
+ long_desc <<-LONGDESC
41
+ Calculates relative full-peak efficiencies for a spectrum that has been analysed with HDTV. Stored peak fits in HDTV can be stored with hdtv>fit write filname.xml
42
+ Example: \n
43
+ $>radiation efficiency Ra-226 Ge00.xml
44
+ With --resource=nucleide.org more decay radiation sources are available.
45
+ With --mini=value transitions with small intensities can be supressed (default 0.3)
46
+ LONGDESC
47
+ def efficiency(nuclide, file)
48
+ resource = options[:resource] ? options[:resource] : "internal"
49
+ mini = options[:mini] ? options[:mini] : 0.3
50
+ source = Radiation::Source.new(nuclide: nuclide, resource: resource)
51
+ spectrum = Radiation::Spectrum.new(source: source ).parse_hdtv(file)
52
+ puts ["E_ɣ", "I_ɣ", "ΔI_ɣ", "e", "Δe"].join("\t")
53
+ spectrum.calibrate.efficiencies.select{|p| p[:intensity] > mini}.sort_by{|k| k[:energy]}.each do |p|
54
+ puts [ p[:energy].to_f.round(1), p[:intensity].value, p[:intensity].delta, p[:efficiency].value.round(1), p[:efficiency].delta.round(1) ].join("\t")
55
+ end
56
+ end
57
+
58
+
37
59
  end
38
60
  end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require 'csv'
3
+
4
+ module Radiation::Resource
5
+ class Internal < Base
6
+
7
+ def fetch(nuclide)
8
+ @nuclide = nuclide
9
+ begin
10
+ path = File.join(File.dirname(__FILE__), "../../../data")
11
+ @data[:nuclide] = @nuclide.to_s
12
+ @data[:transitions] = CSV.read("#{path}/#{@nuclide}.csv", {col_sep: ';', converters: :numeric}).collect{|row| {:energy => row[0].pm(0), :intensity => row[1].pm(row[2])} }
13
+ rescue
14
+ raise "No Data for #{nuclide}"
15
+ end
16
+ self
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ require 'plusminus'
3
+ require 'open-uri'
4
+ require 'open-uri/cached'
5
+ require 'tmpdir'
6
+
7
+
8
+ module Radiation::Resource
9
+ class Nucleideorg < Base
10
+
11
+ def fetch(nuclide)
12
+ @nuclide = nuclide
13
+ @nuclide = "Ra-226D" if @nuclide == "Ra-226" #Ra-226 in equilibrium with daughters
14
+ begin
15
+ @data[:nuclide] = @nuclide.to_s
16
+
17
+ @data[:reference] = "A. Pluquet et al. (2013). Recommended data for #{@nuclide} by the Decay Data Evaluation Project working group. Decay Data Evaluation Project, Laboratoire National Henri Becquerel, C.E. Saclay. Retrieved from http://www.nucleide.org/DDEP_WG/Nuclides/#{@nuclide}.lara.txt"
18
+
19
+ OpenURI::Cache.cache_path = "#{Dir.tmpdir}/radiation/"
20
+ uri = open("http://www.nucleide.org/DDEP_WG/Nuclides/#{@nuclide}.lara.txt").readlines
21
+ start = 0
22
+ uri.each_with_index do |line, lineno|
23
+ if line.start_with?("Half-life (s)")
24
+ row = line.split(' ; ')
25
+ @data[:halflife] = row[1].to_f.pm(row[2].to_f)
26
+ end
27
+ if line.start_with?("------")
28
+ start = lineno + 2
29
+ break
30
+ end
31
+ end
32
+ return @data[:transitions] = [] if start == 0 or uri.count < start
33
+ @data[:transitions] = uri[start...-1].collect{|line| line.split(' ; ')}.select!{|row| row[4] == "g"}.collect do |row|
34
+ {:energy => row[0].to_f.pm(row[1].to_f), :intensity => row[2].to_f.pm(row[3].to_f)}
35
+ end
36
+ rescue
37
+ raise "No Data for #{@nuclide}"
38
+ end
39
+ self
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module Radiation
4
+ module Resource
5
+ class Base
6
+ attr_reader :data
7
+
8
+ def initialize()
9
+ @data = {}
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -1,37 +1,53 @@
1
1
  # encoding: utf-8
2
- require 'radiation/source/resource'
3
2
  require 'combinatorics'
4
3
 
5
-
6
4
  module Radiation
7
- class Source
8
- attr_reader :data
9
-
10
- def initialize(options={})
11
- @resource = options.key?(:resource) ? options[:resource].to_s : "internal"
12
- fetch(options[:nuclide].to_s) if options.key?(:nuclide)
13
- end
14
-
15
- def fetch(nuclide)
16
- raise "Nuclide :#{nuclide} is not valid." unless is_nuclide?(nuclide)
17
- @data = Resource.new(@resource).data(nuclide)
5
+ class Source
6
+ attr_reader :resource, :nuclide, :halflife, :reference, :description, :transitions
7
+
8
+ def initialize(options={})
9
+ @resource = options.key?(:resource) ? options[:resource].to_s : "internal"
10
+ @nuclide = options[:nuclide].to_s if options.key?(:nuclide)
11
+ fetch if @resource and @nuclide
12
+ end
13
+
14
+ def fetch(options={})
15
+ @resource = options[:resource].to_s if options.key?(:resource)
16
+ @nuclide = options[:nuclide].to_s if options.key?(:nuclide)
17
+ raise "Nuclide: #{@nuclide} is not valid." unless is_nuclide?(@nuclide)
18
+ data = case @resource
19
+ when "internal" then Radiation::Resource::Internal.new.fetch(@nuclide).data
20
+ when "nucleide.org" then Radiation::Resource::Nucleideorg.new.fetch(@nuclide).data
21
+ else raise "Unknown Datasource"
22
+ end
23
+ build(data)
24
+ return self
25
+ end
26
+
27
+ def read(options={})
28
+ @resource = "external"
29
+ build(options)
30
+ return self
31
+ end
32
+
33
+ def energies
34
+ self.transitions.collect{|line| line[:energy]}
35
+ end
36
+
37
+ def intensities
38
+ self.transitions.select{|line| line[:intensity] > 0}.collect{|line| {:energy => line[:energy], :intensity => line[:intensity]} }
39
+ end
40
+
41
+ def is_nuclide?(nuclide)
42
+ !!(nuclide =~ /\A[a-zA-Z]{1,2}-\d{1,3}\z/)
43
+ end
44
+
45
+ private
46
+ def build(data)
47
+ [:nuclide, :halflife, :reference, :description, :transitions].each do |key|
48
+ instance_variable_set("@#{key}", data[key]) if data.key?(key)
49
+ end
50
+ end
51
+
18
52
  end
19
-
20
- def nuclide
21
- @data[:nuclide]
22
- end
23
-
24
- def energies
25
- @data[:lines].collect{|line| line[:energy]}
26
- end
27
-
28
- def intensities
29
- @data[:lines].select{|line| line[:intensity] > 0}.collect{|line| {:energy => line[:energy], :intensity => line[:intensity]} }
30
- end
31
-
32
- def is_nuclide?(nuclide)
33
- !!(nuclide =~ /\A[a-zA-Z]{1,2}-\d{1,3}\z/)
34
- end
35
-
36
- end
37
53
  end
@@ -3,76 +3,93 @@ require "linefit"
3
3
  require "plusminus"
4
4
  require "xmlsimple"
5
5
 
6
- module Radiation
7
- class Spectrum
8
- attr_accessor :peaks, :source, :calibration
9
-
10
- def initialize(options={})
11
- @peaks = options.key?(:peaks) ? options[:peaks] : []
12
- @source = options.key?(:source) ? options[:source] : nil
13
- @calibration= options.key?(:calibration) ? options[:calibration] : [0, 1]
14
- end
15
-
16
- def calibrate
17
- if @peaks.empty? or @peaks.select{|p| p.key?(:channel)}.empty?
18
- raise "Nothing to calibrate"
6
+ module Radiation
7
+ class Spectrum
8
+ attr_accessor :peaks, :source, :calibration
9
+
10
+ def initialize(options={})
11
+ @peaks = options.key?(:peaks) ? options[:peaks] : []
12
+ @source = options.key?(:source) ? options[:source] : nil
13
+ @calibration= options.key?(:calibration) ? options[:calibration] : [0, 1]
19
14
  end
20
-
21
- if @peaks.select{|p| p.key?(:channel) and p.key?(:energy)}.empty?
22
- if @calibration == [0,1] and @source.nil?
23
- raise "No channel <-> energy associations. Specify a Source or a preleminary calibration to improve"
24
- else
25
- self.guess_calibration
15
+
16
+ def calibrate
17
+ if @peaks.empty? or @peaks.select{|p| p.key?(:channel)}.empty?
18
+ raise "Nothing to calibrate"
19
+ end
20
+
21
+ if @peaks.select{|p| p.key?(:channel) and p.key?(:energy)}.empty?
22
+ if @calibration == [0,1] and @source.nil?
23
+ raise "No channel <-> energy associations. Specify a Source or a preleminary calibration to improve"
24
+ else
25
+ self.guess_calibration
26
+ end
27
+ self.match_channels
26
28
  end
27
- self.match_channels
29
+ #calibrate using linefit
30
+ mpeaks = @peaks.delete_if{|p| p[:energy] == nil}
31
+ x = mpeaks.collect{|p| p[:channel]}
32
+ y = mpeaks.collect{|p| p[:energy]}
33
+ lineFit = LineFit.new
34
+ lineFit.setData(x,y)
35
+ intercept, slope = lineFit.coefficients
36
+ varianceIntercept, varianceSlope = lineFit.varianceOfEstimates
37
+ @calibration = [intercept.pm(Math.sqrt(varianceIntercept)), slope.pm(Math.sqrt(varianceSlope))]
38
+ return self
28
39
  end
29
- #calibrate using linefit
30
- mpeaks = @peaks.delete_if{|p| p[:energy] == nil}
31
- x = mpeaks.collect{|p| p[:channel]}
32
- y = mpeaks.collect{|p| p[:energy]}
33
- lineFit = LineFit.new
34
- lineFit.setData(x,y)
35
- intercept, slope = lineFit.coefficients
36
- varianceIntercept, varianceSlope = lineFit.varianceOfEstimates
37
- @calibration = [intercept.pm(Math.sqrt(varianceIntercept)), slope.pm(Math.sqrt(varianceSlope))]
38
- return self
39
- end
40
-
41
- def match_channels(energies=@source.energies, rounding=4)
42
- @peaks.each do |peak|
43
- energies.each do |energy|
44
- peak[:energy] = energy if channel_energy(peak[:channel]).to_f.approx_equal?(energy, rounding)
40
+
41
+ def match_channels(energies=@source.energies, rounding=4)
42
+ @peaks.each do |peak|
43
+ energies.each do |energy|
44
+ peak[:energy] = energy if channel_energy(peak[:channel]).to_f.approx_equal?(energy, rounding)
45
+ end
45
46
  end
47
+ return self
48
+ end
49
+
50
+ def guess_calibration(energies=@source.energies, rounding=4)
51
+ # Build all possible combinations of known energies and peaks
52
+ arr = [energies, @peaks.collect{|peak| peak[:channel]}].comprehension
53
+ # The approximate value for b in $Energy = a + b * Channel$ will be most frequent for $a \approx 0$
54
+ 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}
55
+ @calibration = [0, freq.last[0] ]
56
+ return self
57
+ end
58
+
59
+ def channel_energy(chn)
60
+ @calibration[0] + @calibration[1]*chn
61
+ end
62
+
63
+ def parse_hdtv(file)
64
+ xml = XmlSimple.xml_in(file, { 'KeyAttr' => 'name' })
65
+ @peaks = xml["fit"].collect{|p| p["peak"]}.flatten.collect{|p| p["uncal"]}.flatten.collect do |p|
66
+ {:channel => p["pos"].first["value"].first.to_f.pm(p["pos"].first["error"].first.to_f),
67
+ :counts => p["vol"].first["value"].first.to_f.pm(p["vol"].first["error"].first.to_f) }
68
+ end
69
+ return self
70
+ end
71
+
72
+ def efficiencies(rounding=4)
73
+ @peaks.each do |peak|
74
+ @source.transitions.each do |transition|
75
+ if channel_energy(peak[:channel]).to_f.approx_equal?(transition[:energy], rounding)
76
+ peak[:energy] = transition[:energy]
77
+ peak[:intensity] = transition[:intensity] if transition[:intensity] > 0
78
+ end
79
+ end
80
+ end
81
+ @peaks.select{|p| p.key?(:intensity) and p.key?(:counts)}.each{|p| p[:efficiency] = channel_efficiency(p)}
46
82
  end
47
- return self
48
- end
49
-
50
- def guess_calibration(energies=@source.energies, rounding=4)
51
- # Build all possible combinations of known energies and peaks
52
- arr = [energies, @peaks.collect{|peak| peak[:channel]}].comprehension
53
- # The approximate value for b in $Energy = a + b * Channel$ will be most frequent for $a \approx 0$
54
- 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}
55
- @calibration = [0, freq.last[0] ]
56
- return self
57
- end
58
-
59
- def channel_energy(chn)
60
- @calibration[0] + @calibration[1]*chn
61
- end
62
83
 
63
- def parse_hdtv(file)
64
- xml = XmlSimple.xml_in(file, { 'KeyAttr' => 'name' })
65
- @peaks = xml["fit"].collect{|p| p["peak"]}.flatten.collect{|p| p["uncal"]}.flatten.collect do |p|
66
- {:channel => p["pos"].first["value"].first.to_f.pm(p["pos"].first["error"].first.to_f),
67
- :counts => p["vol"].first["value"].first.to_f.pm(p["vol"].first["error"].first.to_f) }
84
+ private
85
+ def channel_efficiency(peak)
86
+ peak[:counts]/peak[:intensity]
68
87
  end
69
- return self
70
- end
71
88
 
89
+ end
72
90
  end
73
- end
74
-
75
-
91
+
92
+
76
93
  class Float
77
94
  def approx_equal?(other,threshold=0.5)
78
95
  if (self-other).abs < threshold # "<" not exact either
@@ -1,3 +1,3 @@
1
- module Radiation
2
- VERSION = "0.0.4"
3
- end
1
+ module Radiation
2
+ VERSION = "0.1.0"
3
+ end
data/lib/radiation.rb CHANGED
@@ -1,7 +1,10 @@
1
- require "radiation/version"
2
- require "radiation/source"
3
- require "radiation/spectrum"
4
-
5
- module Radiation
6
- # Your code goes here...
7
- end
1
+ require "radiation/version"
2
+ require "radiation/source"
3
+ require "radiation/spectrum"
4
+ require "radiation/resource"
5
+ require 'radiation/resource/internal'
6
+ require 'radiation/resource/nucleideorg'
7
+
8
+ module Radiation
9
+ # Your code goes here...
10
+ end