radiation 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +6 -14
- data/.gitignore +17 -17
- data/.rspec +1 -1
- data/.travis.yml +7 -9
- data/CHANGELOG.md +12 -12
- data/Gemfile +5 -5
- data/LICENSE.txt +22 -22
- data/README.md +45 -45
- data/Rakefile +6 -6
- data/lib/radiation/cli.rb +22 -0
- data/lib/radiation/resource/internal.rb +20 -0
- data/lib/radiation/resource/nucleideorg.rb +43 -0
- data/lib/radiation/resource.rb +14 -0
- data/lib/radiation/source.rb +47 -31
- data/lib/radiation/spectrum.rb +78 -61
- data/lib/radiation/version.rb +3 -3
- data/lib/radiation.rb +10 -7
- data/radiation.gemspec +32 -32
- data/samples/B0-Ra226.xml +4721 -4721
- data/samples/efficiencies.rb +10 -0
- data/spec/radiation_spec.rb +14 -4
- metadata +24 -23
- data/lib/radiation/source/resource/internal.rb +0 -17
- data/lib/radiation/source/resource/nucleideorg.rb +0 -36
- data/lib/radiation/source/resource.rb +0 -25
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
4
|
-
- "1.9.
|
5
|
-
- "
|
6
|
-
|
7
|
-
-
|
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
|
-
[](http://badge.fury.io/rb/radiation)
|
3
|
-
[](https://travis-ci.org/janmayer/radiation)
|
4
|
-
[](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
|
+
[](http://badge.fury.io/rb/radiation)
|
3
|
+
[](https://travis-ci.org/janmayer/radiation)
|
4
|
+
[](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
|
data/lib/radiation/source.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
data/lib/radiation/spectrum.rb
CHANGED
@@ -3,76 +3,93 @@ require "linefit"
|
|
3
3
|
require "plusminus"
|
4
4
|
require "xmlsimple"
|
5
5
|
|
6
|
-
module Radiation
|
7
|
-
class Spectrum
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
22
|
-
if @
|
23
|
-
raise "
|
24
|
-
|
25
|
-
|
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
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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
|
data/lib/radiation/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Radiation
|
2
|
-
VERSION = "0.0
|
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
|
-
|
6
|
-
|
7
|
-
|
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
|