mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
basisUtils2D.hpp
Go to the documentation of this file.
1 /** \file basisUtils2D.hpp
2  * \brief Utilities for a working with a 2D basis set
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup signal_processing_files
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2018 Jared R. Males (jaredmales@gmail.com)
12 //
13 // This file is part of mxlib.
14 //
15 // mxlib is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // mxlib is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
27 //***********************************************************************//
28 
29 #ifndef basisUtils_hpp
30 #define basisUtils_hpp
31 
32 #include "../improc/eigenImage.hpp"
33 #include "../improc/eigenCube.hpp"
34 
35 namespace mx
36 {
37 namespace sigproc
38 {
39 
40 /// Mask a basis set.
41 /** Multiplies each mode in a basis set by a mask.
42  *
43  * \returns 0 on success
44  * \returns -1 on error
45  *
46  * \tparam realT a real floating point type.
47  *
48  * \ingroup signal_processing
49  */
50 template<typename realT>
51 int basisMask( improc::eigenCube<realT> & modes, ///< [in.out] the basis to normalize.
52  improc::eigenImage<realT> & mask ///< [in] 1/0 mask defining the domain of the basis
53  )
54 {
55  for(int i=0; i < modes.planes(); ++i)
56  {
57  modes.image(i) *= mask;
58  }
59 
60  return 0;
61 }
62 
63 /// Mean-subtract a basis set.
64 /** Subtracts the mean of each mode calculated over a domain defined by a mask.
65  *
66  * \returns 0 on success
67  * \returns -1 on error
68  *
69  * \tparam realT a real floating point type.
70  *
71  * \ingroup signal_processing
72  */
73 template<typename realT>
74 int basisMeanSub( improc::eigenCube<realT> & modes, ///< [in.out] the basis to normalize.
75  improc::eigenImage<realT> & mask, ///< [in] 1/0 mask defining the domain of the basis
76  bool postMult = true ///< [in] [optional] if true, then each image is multiplied by the mask after subtraction.
77  )
78 {
79  realT maskSum = mask.sum();
80  for(int i=0; i < modes.planes(); ++i)
81  {
82  float mean = (modes.image(i)*mask).sum()/maskSum;
83 
84  modes.image(i) -= mean;
85 
86  if(postMult) modes.image(i) *= mask;
87  }
88 
89  return 0;
90 }
91 
92 /// Normalize a basis set.
93 /** RMS normalize each mode over a domain defined by a mask.
94  *
95  * \returns 0 on success
96  * \returns -1 on error
97  *
98  * \tparam realT a real floating point type.
99  *
100  * \ingroup signal_processing
101  */
102 template<typename realT>
103 int basisNormalize( improc::eigenCube<realT> & modes, ///< [in.out] the basis to normalize.
104  improc::eigenImage<realT> & mask ///< [in] 1/0 mask defining the domain of the normalization
105  )
106 {
107  realT psum = mask.sum();
108  for(int i=0; i < modes.planes(); ++i)
109  {
110  float norm = (modes.image(i)*mask).square().sum()/psum;
111 
112  modes.image(i)/=sqrt(norm);
113  }
114 
115  return 0;
116 }
117 
118 /// Measure the amplitudes of a set of basis modes fit to an image. Optionally subtract them.
119 /** Mode subtraction occurs one by one, so subtraction will work with non-orthogonal basis sets.
120  *
121  * \returns 0 on success
122  * \returns -1 on error
123  *
124  * \tparam realT the floating point type.
125  *
126  * \ingroup signal_processing
127  */
128 template<typename realT>
129 int basisAmplitudes( std::vector<realT> & amps, ///< [out] the amplitudes of each mode fit to the image (will be resized).
130  improc::eigenImage<realT> & im, ///< [in.out] the image to fit. Is subtracted in place if desired.
131  improc::eigenCube<realT> & modes, ///< [in] the modes to fit.
132  improc::eigenImage<realT> & mask, ///< [in] the 1/0 mask which defines the domain of the fit.
133  bool subtract = false, ///< [in] [optional] if true then the modes are subtracted as they are fit to the image
134  int meanIgnore= 0, ///< [in] [optional] if 1 then the mean, or if 2 the median, value is subtracted before fitting. If subtract is false, this value is added back after the subtraction.
135  int N = -1 ///< [in] [optional] the number of modes to actually fit. If N < 0 then all modes are fit.
136  )
137 {
138  if( N < 0) N = modes.planes();
139  amps.resize(N);
140 
141  realT apertureNPix = mask.sum();
142 
143  realT mean;
144  if(meanIgnore)
145  {
146  if(meanIgnore == 2) mean = improc::imageMedian(im,&mask);
147  else mean = (im*mask).sum()/apertureNPix;
148 
149  im -= mean;
150  }
151 
152  for(int i=0; i<N; ++i)
153  {
154  amps[i] = (im*modes.image(i)*mask).sum()/ apertureNPix;
155 
156  if(subtract)
157  {
158  im -= amps[i]*modes.image(i);
159  }
160  }
161 
162  if(meanIgnore && !subtract)
163  {
164  im += mean;
165  }
166 
167  return 0;
168 }
169 
170 
171 } //namespace sigproc
172 } //namespace mx
173 
174 #endif //basisUtils_hpp
175 
176 
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
Definition: eigenImage.hpp:44
@ imageMedian
The median of each image (within the search region) is subtracted from itself.
int basisNormalize(improc::eigenCube< realT > &modes, improc::eigenImage< realT > &mask)
Normalize a basis set.
int basisMeanSub(improc::eigenCube< realT > &modes, improc::eigenImage< realT > &mask, bool postMult=true)
Mean-subtract a basis set.
int basisAmplitudes(std::vector< realT > &amps, improc::eigenImage< realT > &im, improc::eigenCube< realT > &modes, improc::eigenImage< realT > &mask, bool subtract=false, int meanIgnore=0, int N=-1)
Measure the amplitudes of a set of basis modes fit to an image. Optionally subtract them.
int basisMask(improc::eigenCube< realT > &modes, improc::eigenImage< realT > &mask)
Mask a basis set.
The mxlib c++ namespace.
Definition: mxError.hpp:107