radiation 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NjYzYWE2MzQ4NTIyY2EyOTcyODg3N2E0OGE4ZGQ1NmEyMTdlNjI4Mw==
4
+ ZGQ3OGQyOWMzYWFjMGFjMjMzNTE4OGM0YTMxNmQ1MjdjZGNmOGZmZA==
5
5
  data.tar.gz: !binary |-
6
- YTM5MmIxOGRmYzU0Zjc3MmU0NmI1MTEyYTMwZGY4MWUwMDYyY2NmOA==
6
+ YTliN2YzZGYwNmEzODgwMDdkOTRiOWQ5NTkyNzIxMjYwZjhlMThlNw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OTFlYmNlNWQ3ZDgwMTBlMzc5ZTI1N2Q4YjhiMWMyOTBlZDA2YjJjZjNhYWZk
10
- MDU0ZjQ2YTJkOWVkYjExMTliYjYyYjZjM2Q3MTJmMGRjNDM5MDdhYTNmY2U0
11
- MWFlNzM2NDI1ZTZlNzVmNTY4NTJjMGI1MDhkNGYzYTZkZDViM2E=
9
+ ZjI5NmZjMGRkMDMzMjQyMzBkYWRhODU3ZTNjMTYwYzY0YTcwOWM4N2JiMTJi
10
+ NWYxMWRjMmViNGJhNTY0MzJiMzMyYTIwODU3ZGM1ZmU3MjFlMTk1OThkMjQ2
11
+ MTkwZTg2MWMxMjZmZDBlNjdlNWNiNDEzOWYyYTg5Mzg4MzM1M2U=
12
12
  data.tar.gz: !binary |-
13
- NzI5MDE3OGY2YmI1NDhiZGNmMWY1YTIwODQ4ZTQ4N2ZiYThiMzU4YmE3ZmQx
14
- ZjZhMzQwNjE1MjRmOTc3NmUzYzg4MzM4NWFkOWFlNThkMDA3N2Q0OTQ1YTEx
15
- YWJhZjlhMTliZTNjNTI2NTY4YmFhYjg1YzRjYWFiZTYxMTg0ZGU=
13
+ NDMwNjczZWQyMjM2YmIyYjFhODRlY2FmMDUzNDE3ZGZjNzI1ZDQwNWU2NTVk
14
+ ODM5MTI2ODUyOWIzOTlkNWExZTA5OWZlOGM2NDdlYzE3NDEyNDhhMTMyMjkz
15
+ YWM2ZjU4Nzg2MTAwM2U2ODEwOTI0ZGJjZWU5NWQwZmEzN2NjMmQ=
data/.travis.yml CHANGED
@@ -1,2 +1,9 @@
1
+ language: ruby
1
2
  rvm:
2
- - 1.9
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
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## v0.0.2
2
+
3
+ * Added spectrum class with energy calibration options
4
+
1
5
  ## v0.0.1
2
6
 
3
7
  * initial release
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem "linefit", git: "https://github.com/janmayer/linefit.git"
3
4
  # Specify your gem's dependencies in radiation.gemspec
4
5
  gemspec
data/README.md CHANGED
@@ -1,17 +1,21 @@
1
- # Radiation
1
+ # Radiation [![Build Status](https://travis-ci.org/janmayer/radiation.png?branch=master)](https://travis-ci.org/janmayer/radiation)
2
2
 
3
3
  This gem provides easy access to energies and intensities from the decay of radioactive nuclei.
4
4
  Currently two data sources are accessible: Internal (see bib files in `./data/`) and recommended values
5
- by [Laboratoire National Henri Becquerel](http://www.nucleide.org/DDEP_WG/DDEPdata.htm)
5
+ by [Laboratoire National Henri Becquerel](http://www.nucleide.org/DDEP_WG/DDEPdata.htm).
6
6
 
7
7
  ## Example Usage
8
8
 
9
9
  Radiation::Source.new(nuclide: "Ra-226").energies.collect{|e| e.value}
10
10
 
11
+ See also files in `./samples/`.
12
+
11
13
 
12
14
  ## Planned features
13
15
 
14
- Energy and efficiency calibration for given peaks or spectra.
16
+ * Efficiency calibration for given peaks or spectra
17
+ * CLI
18
+ * Better access to resources
15
19
 
16
20
 
17
21
  ## Installation
@@ -11,7 +11,7 @@ class Radiation::Source
11
11
 
12
12
  private
13
13
  def datasource_nukleideorg(nuclide)
14
- nuclide = "Ra-226D" if nuclide == "Ra-226" #Ra-226 in equlibrium with daughters
14
+ nuclide = "Ra-226D" if nuclide == "Ra-226" #Ra-226 in equilibrium with daughters
15
15
  begin
16
16
  @data[:nuclide] = nuclide.to_s
17
17
  OpenURI::Cache.cache_path = "#{Dir.tmpdir}/radiation/"
@@ -1,5 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'radiation/source/resource'
3
+ require 'combinatorics'
4
+
3
5
 
4
6
  class Radiation::Source
5
7
  attr_reader :data
@@ -29,4 +31,5 @@ class Radiation::Source
29
31
  def is_nuclide?(nuclide)
30
32
  !!(nuclide =~ /\A[a-zA-Z]{1,2}-\d{1,3}\z/)
31
33
  end
34
+
32
35
  end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ require "linefit"
3
+ require "plusminus"
4
+
5
+ class Radiation::Spectrum
6
+ attr_accessor :peaks, :source, :calibration
7
+
8
+ def initialize(options={})
9
+ @peaks = options.key?(:peaks) ? options[:peaks] : []
10
+ @source = options.key?(:source) ? options[:source] : nil
11
+ @calibration= options.key?(:calibration) ? options[:calibration] : [0, 1]
12
+ end
13
+
14
+ def calibrate
15
+ if @peaks.empty? or @peaks.select{|p| p.key?(:channel)}.empty?
16
+ raise "Nothing to calibrate"
17
+ end
18
+
19
+ if @peaks.select{|p| p.key?(:channel) and p.key?(:energy)}.empty?
20
+ if @calibration == [0,1] and @source.nil?
21
+ raise "No channel <-> energy associations. Specify a Source or a preleminary calibration to improve"
22
+ else
23
+ self.guess_calibration
24
+ end
25
+ self.match_channels
26
+ end
27
+ #calibrate using linefit
28
+ mpeaks = @peaks.delete_if{|p| p[:energy] == nil}
29
+ x = mpeaks.collect{|p| p[:channel]}
30
+ y = mpeaks.collect{|p| p[:energy]}
31
+ lineFit = LineFit.new
32
+ lineFit.setData(x,y)
33
+ intercept, slope = lineFit.coefficients
34
+ varianceIntercept, varianceSlope = lineFit.varianceOfEstimates
35
+ @calibration = [intercept.pm(Math.sqrt(varianceIntercept)), slope.pm(Math.sqrt(varianceSlope))]
36
+ return self
37
+ end
38
+
39
+ def match_channels(energies=@source.energies, rounding=4)
40
+ @peaks.each do |peak|
41
+ energies.each do |energy|
42
+ peak[:energy] = energy if channel_energy(peak[:channel]).approx_equal?(energy, rounding)
43
+ end
44
+ end
45
+ return self
46
+ end
47
+
48
+ def guess_calibration(energies=@source.energies, rounding=3)
49
+ # Build all possible combinations of known energies and peaks
50
+ arr = [energies, @peaks.collect{|peak| peak[:channel]}].comprehension
51
+ # The approximate value for b in $Energy = a + b * Channel$ will be most frequent for $a \approx 0$
52
+ 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}
53
+ @calibration = [0, freq.last[0] ]
54
+ return self
55
+ end
56
+
57
+ def channel_energy(chn)
58
+ @calibration[0] + @calibration[1]*chn
59
+ end
60
+
61
+ end
62
+
63
+
64
+
65
+ class Float
66
+ def approx_equal?(other,threshold=0.5)
67
+ if (self-other).abs < threshold # "<" not exact either
68
+ return true
69
+ else
70
+ return false
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module Radiation
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/radiation.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "radiation/version"
2
2
  require "radiation/source"
3
+ require "radiation/spectrum"
3
4
 
4
5
  module Radiation
5
6
  # Your code goes here...
data/radiation.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["jan.mayer@ikp.uni-koeln.de"]
11
11
  spec.description = %q{Decay Radiation}
12
12
  spec.summary = %q{This gem provides easy access to energies and intensities from the decay of radioactive nuclei}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/janmayer/radiation"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -20,6 +20,9 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "plusminus"
22
22
  spec.add_dependency "open-uri-cached"
23
+ spec.add_dependency "combinatorics"
24
+ spec.add_dependency "linefit", "~> 0.3.1"
25
+
23
26
 
24
27
  spec.add_development_dependency "bundler", "~> 1.3"
25
28
  spec.add_development_dependency "rake"
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ require 'radiation'
3
+
4
+ channels = [512.9592, 668.6611, 715.773, 759.483, 817.0175, 975.0220, 1075.977, 1124.82, 1261.666, 1281.123, 1333.194, 1351.650, 1417.69, 1481.380, 1610.736, 1691.9637, 1848.412, 1953.350, 2000.193, 2135.6125, 2184.578, 2241.203, 2332.889, 2595.4352, 2678.202, 3112.7327, 3209.900, 3440.820, 3560.182, 3829.513, 3850.791, 3895.915, 3913.953, 4196.125, 4621.221, 4811.183, 4908.2438, 5139.402, 5895.042, 6133.533, 6811.046]
5
+ peaks = channels.collect{|a| {channel: a} }
6
+ source = Radiation::Source.new(nuclide: "Ra-226")
7
+ spectrum = Radiation::Spectrum.new(peaks: peaks, source: source )
8
+
9
+ puts spectrum.calibrate.calibration.to_s
10
+
11
+ puts "\n"
12
+
13
+ puts spectrum.peaks.collect{|p| [ p[:channel], p[:energy] ].join("\t") }
@@ -3,54 +3,64 @@ require 'spec_helper'
3
3
 
4
4
  describe Radiation do
5
5
  describe Radiation::Source do
6
+ name = "Ra-226"
7
+ source = Radiation::Source.new(nuclide: name)
6
8
 
7
- describe "Features" do
8
- name = "Ra-226"
9
- source = Radiation::Source.new(nuclide: name)
10
-
11
-
12
- it "provides information about itself" do
13
- source.nuclide.should eq(name)
14
- #source.reference.should be_a_kind_of(String)
15
- #source.halflive.should be_a_kind_of(Plusminus::PlusminusFloat)
16
- end
17
-
18
- it "returns an array with gamma-ray energies for a given source" do
19
- source.energies.should be_a_kind_of(Array)
20
- source.energies.length.should be > 0
21
- source.energies[0].should be_a_kind_of(Plusminus::PlusminusFloat)
22
- end
23
-
24
- it "returns intensities for energies" do
25
- source.intensities.should be_a_kind_of(Array)
26
- source.intensities.first.should be_a_kind_of(Hash)
27
- source.intensities.length.should be > 0
28
- end
29
-
30
- it "can access different data resources" do
31
- expect { Radiation::Source.new(nuclide: "Ra-226") }.to_not raise_error
32
- expect { Radiation::Source.new(nuclide: "Ra-226", resource: "nucleide.org") }.to_not raise_error
33
- end
34
-
35
- end
36
-
37
- describe "Errors" do
38
- it "cheks for valid nuclei" do
39
- Radiation::Source.new.is_nuclide?("Nukular9000").should be false
40
- Radiation::Source.new.is_nuclide?("226Ra-226").should be false
41
- Radiation::Source.new.is_nuclide?("Ra-226").should be true
42
- Radiation::Source.new.is_nuclide?("C-14").should be true
43
- Radiation::Source.new.is_nuclide?("H-1").should be true
44
- expect { Radiation::Source.new(nuclide: "Nukular9000") }.to raise_error
45
- expect { Radiation::Source.new(nuclide: "Ra-226") }.to_not raise_error
46
- end
47
-
48
- it "gives an error if no record is found" do
49
- expect { Radiation::Source.new(nuclide: "Ra-15") }.to raise_error
50
- expect { Radiation::Source.new(nuclide: "Ra-15", resource: "nucleide.org") }.to raise_error
51
- end
9
+ it "provides information about itself" do
10
+ source.nuclide.should eq(name)
11
+ #source.reference.should be_a_kind_of(String)
12
+ #source.halflive.should be_a_kind_of(Plusminus::PlusminusFloat)
13
+ end
14
+
15
+ it "returns an array with gamma-ray energies for a given source" do
16
+ source.energies.should be_a_kind_of(Array)
17
+ source.energies.length.should be > 0
18
+ source.energies[0].should be_a_kind_of(Plusminus::PlusminusFloat)
19
+ end
20
+
21
+ it "returns intensities for energies" do
22
+ source.intensities.should be_a_kind_of(Array)
23
+ source.intensities.first.should be_a_kind_of(Hash)
24
+ source.intensities.length.should be > 0
25
+ end
26
+ it "can access different data resources" do
27
+ expect { Radiation::Source.new(nuclide: "Ra-226") }.to_not raise_error
28
+ expect { Radiation::Source.new(nuclide: "Ra-226", resource: "nucleide.org") }.to_not raise_error
29
+ end
30
+
31
+ it "cheks for valid nuclei" do
32
+ Radiation::Source.new.is_nuclide?("Nukular9000").should be false
33
+ Radiation::Source.new.is_nuclide?("226Ra-226").should be false
34
+ Radiation::Source.new.is_nuclide?("Ra-226").should be true
35
+ Radiation::Source.new.is_nuclide?("C-14").should be true
36
+ Radiation::Source.new.is_nuclide?("H-1").should be true
37
+ expect { Radiation::Source.new(nuclide: "Nukular9000") }.to raise_error
38
+ expect { Radiation::Source.new(nuclide: "Ra-226") }.to_not raise_error
39
+ end
40
+ it "gives an error if no record is found" do
41
+ expect { Radiation::Source.new(nuclide: "Ra-15") }.to raise_error
42
+ expect { Radiation::Source.new(nuclide: "Ra-15", resource: "nucleide.org") }.to raise_error
43
+ end
44
+ end
45
+
46
+ describe Radiation::Spectrum do
47
+ channels = [512.9592, 668.6611, 715.773, 759.483, 817.0175, 975.0220, 1075.977, 1124.82, 1261.666, 1281.123, 1333.194, 1351.650, 1417.69, 1481.380, 1610.736, 1691.9637, 1848.412, 1953.350, 2000.193, 2135.6125, 2184.578, 2241.203, 2332.889, 2595.4352, 2678.202, 3112.7327, 3209.900, 3440.820, 3560.182, 3829.513, 3850.791, 3895.915, 3913.953, 4196.125, 4621.221, 4811.183, 4908.2438, 5139.402, 5895.042, 6133.533, 6811.046]
48
+ peaks = channels.collect{|a| {channel: a} }
49
+ source = Radiation::Source.new(nuclide: "Ra-226")
50
+
51
+ it "can guess a inital energy calibration based on adc values" do
52
+ Radiation::Spectrum.new(peaks: peaks, source: source).guess_calibration.calibration.should be == [0, 0.36]
53
+ end
54
+
55
+ it "can match channels to given energies by using a calibration" do
56
+ Radiation::Spectrum.new(peaks: peaks, source: source ).guess_calibration.match_channels.peaks[0][:energy].should be == 186.2
57
+ end
52
58
 
59
+ it "can calibrate a spectrum" do
60
+ expect { Radiation::Spectrum.new(peaks: peaks, source: source ).calibrate }.to_not raise_error
61
+ Radiation::Spectrum.new(peaks: peaks, source: source ).calibrate.calibration[0].should be_a_kind_of(Plusminus::PlusminusFloat)
53
62
  end
54
63
 
55
64
  end
65
+
56
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-03 00:00:00.000000000 Z
11
+ date: 2013-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: plusminus
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: combinatorics
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: linefit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.1
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: bundler
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -104,12 +132,14 @@ files:
104
132
  - lib/radiation/source/resource.rb
105
133
  - lib/radiation/source/resource/internal.rb
106
134
  - lib/radiation/source/resource/nucleideorg.rb
135
+ - lib/radiation/spectrum.rb
107
136
  - lib/radiation/version.rb
108
137
  - radiation.gemspec
138
+ - samples/calibrate_a_spectrum.rb
109
139
  - samples/get_some_data.rb
110
140
  - spec/radiation_spec.rb
111
141
  - spec/spec_helper.rb
112
- homepage: ''
142
+ homepage: https://github.com/janmayer/radiation
113
143
  licenses:
114
144
  - MIT
115
145
  metadata: {}