Coverage for larch/xrf/roi.py: 28%
53 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1"""
2This module defines a region of interest class
3and utility functions.
5Authors/Modifications:
6-----------------------
7* Mark Rivers, GSECARS
8* Modified for Tdl, tpt
9* simplified, modified for larch, M Newville
10"""
12import numpy as np
13from larch import Group
16def split_roiname(name):
17 words = name.split()
18 elem = words[0].title()
19 line = 'ka'
20 if len(words) > 1:
21 line = words[1]
22 line = line.title()
23 if line == 'Ka': line = 'Ka1'
24 if line == 'Kb': line = 'Kb1'
25 if line == 'La': line = 'La1'
26 if line == 'Lb': line = 'Lb1'
27 return elem, line
29class ROI(Group):
30 """
31 Class that defines a Region-Of-Interest (ROI)
33 Attributes:
34 -----------
35 * left # Left channel
36 * right # Right channel
37 * name # Name of the ROI
38 * address # Address of the ROI (PV name, for example)
39 * bgr_width # Number of channels to use for background subtraction
41 # Computed
42 * total # Total counts
43 * net # Net (bgr subtr) counts
44 * center # Centroid
45 * width # Width
46 """
47 def __init__(self, left=0, right=0, name='', bgr_width=3, counts=None,
48 address=''):
49 """
50 Parameters:
51 -----------
52 * left Left limit in index/channels numbers
53 * right Right limit in index/channels numbers
54 * name Name of the ROI
55 * bgr_width Number of channels to use for background subtraction
56 """
57 self.name = name
58 self.address = address
59 self.bgr_width = int(bgr_width)
60 self.total = 0
61 self.net = 0
62 self.set_bounds(left, right)
63 if counts is not None:
64 self.get_counts(counts)
65 Group.__init__(self)
67 def __eq__(self, other):
68 """used for comparisons"""
69 return (self.left == getattr(other, 'left', None) and
70 self.right == getattr(other, 'right', None) and
71 self.bgr_width == getattr(other, 'bgr_width', None) )
73 def __ne__(self, other): return not self.__eq__(other)
74 def __lt__(self, other): return self.left < getattr(other, 'left', None)
75 def __le__(self, other): return self.left <= getattr(other, 'left', None)
76 def __gt__(self, other): return self.left > getattr(other, 'left', None)
77 def __ge__(self, other): return self.left >= getattr(other, 'left', None)
80 def __repr__(self):
81 form = "<ROI(name='%s', left=%i, right=%i, bgr_width=%i)>"
82 return form % (self.name, self.left, self.right, self.bgr_width)
84 def set_bounds(self, left=-1, right=-1):
85 """set ROI bounds"""
86 self.left = int(left)
87 self.right = int(right)
88 self.center = int((self.right + self.left)/2.)
89 self.width = abs((self.right - self.left)/2.)
91 def get_counts(self, data, net=False):
92 """
93 calculate total and net counts for a spectra
95 Parameters:
96 -----------
97 * data: numpy array of spectra
98 * net: bool to set net counts (default=False: total counts returned)
99 """
100 bgr_width = int(self.bgr_width)
101 ilmin = max((self.left - bgr_width), 0)
102 irmax = min((self.right + bgr_width), len(data)-1) + 1
103 bgr_counts = np.concatenate((data[ilmin:self.left],
104 data[self.right+1:irmax])).mean()
106 #total and net cts
107 self.total = data[self.left:self.right+1].sum()
108 self.net = self.total - bgr_counts*(self.right-self.left)
109 out = self.total
110 if net:
111 out = self.net
112 return out
114def create_roi(name, left, right, bgr_width=3, address=''):
115 """create an ROI, a named portion of an MCA spectra defined by index
117 Parameters:
118 ------------
119 name: roi name
120 left: left index
121 right: right index
122 bgr_width (optional) background width (default=3)
123 address (optional) address (PV name) for ROI
125 Returns:
126 ----------
127 an ROI object which has properties
128 name, left, right, center, width, bgr_width
129 and methods
130 set_bounds(left, right)
131 get_counts(data, net=False)
132 """
133 return ROI(name=name, left=left, right=right,
134 bgr_width=bgr_width, address=address)