comparison m-toolbox/classes/@ao/bin_data.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % BIN_DATA rebins aos data, on logarithmic scale, linear scale, or arbitrarly chosen.
2 % The rebinning is done taking the mean of the bins included in the range
3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 %
5 % DESCRIPTION: BIN_DATA rebins aos data, on logarithmic scale, linear scale, or arbitrarly chosen.
6 % The rebinning is done taking the mean of the bins included in the range
7 %
8 % CALL: bs = bin_data(a1,a2,a3,...,pl)
9 % bs = bin_data(as,pl)
10 % bs = as.bin_data(pl)
11 %
12 % INPUTS: aN - input analysis objects
13 % as - input analysis objects array
14 % pl - input parameter list
15 %
16 % OUTPUTS: bs - array of analysis objects, one for each input
17 %
18 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'bin_data')">Parameters Description</a>
19 %
20 % The code is inherited from D Nicolodi, UniTN
21 %
22 % VERSION: $Id: bin_data.m,v 1.20 2011/05/10 16:46:48 mauro Exp $
23 %
24 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25
26
27
28 function varargout = bin_data(varargin)
29
30 % Check if this is a call for parameters
31 if utils.helper.isinfocall(varargin{:})
32 varargout{1} = getInfo(varargin{3});
33 return
34 end
35
36 import utils.const.*
37 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
38
39 % Collect input variable names
40 in_names = cell(size(varargin));
41 for ii = 1:nargin,in_names{ii} = inputname(ii);end
42
43 % Collect all AOs
44 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
45
46 % Decide on a deep copy or a modify
47 bs = copy(as, nargout);
48
49 % Apply defaults to plist
50 usepl = applyDefaults(getDefaultPlist(), varargin{:});
51
52 x_scale = find(usepl, 'x_scale', find(usepl, 'xscale'));
53 x_vals = find(usepl, 'x_vals', find(usepl, 'xvals'));
54 resolution = find(usepl, 'resolution');
55 range = find(usepl, 'range');
56 method = lower(find(usepl, 'method'));
57 inherit_dy = utils.prog.yes2true(find(usepl, 'inherit-dy', find(usepl, 'inherit_dy')));
58
59 % Loop over input AOs
60 for jj = 1:numel(bs)
61
62 % check input data
63 if isa(bs(jj).data, 'data2D')
64
65 w = find(usepl, 'weights');
66
67 if isa(w, 'ao')
68 w = w.y;
69 end
70
71 if isempty(w)
72 w = 1./(bs(jj).dy).^2;
73 end
74
75 if isempty(x_vals)
76 if isempty(x_scale) || isempty(resolution)
77 error('### Please specify a scale and density for binning, OR the list of the values to bin around');
78 else
79
80 switch lower(x_scale)
81 case {'lin', 'linear'}
82 % Case of linear binning
83 % number of bins in the rebinned data set
84 N = resolution;
85
86 % maximum and minimum x
87 if ~isempty(range) && isfinite(range(1))
88 xmin = range(1);
89 else
90 xmin = min(bs(jj).x);
91 end
92
93 if ~isempty(range) && isfinite(range(2))
94 xmax = range(2);
95 else
96 xmax = max(bs(jj).x);
97 end
98
99 dx = (xmax - xmin)/N;
100
101 x_min = bs(jj).x(1) + dx*(0:(N-1))';
102 x_max = bs(jj).x(1) + dx*(1:N)';
103
104 case {'log', 'logarithmic'}
105 % Case of log-based binning
106
107 % maximum and minimum x
108 if ~isempty(range) && isfinite(range(1))
109 xmin = range(1);
110 else
111 xmin = min(bs(jj).x(bs(jj).x > 0));
112 end
113
114 if ~isempty(range) && isfinite(range(2))
115 xmax = range(2);
116 else
117 xmax = max(bs(jj).x);
118 end
119
120 alph = 10^(1/resolution);
121
122 % number of bins in the rebinned data set
123 N = ceil(log10(xmax/xmin) * resolution);
124
125 % maximum and minimum x-value for each bin
126 x_min = xmin*alph.^(0:(N-1))';
127 x_max = xmin*alph.^(1:N)';
128 otherwise
129 error(['### Unknown scaling option ' x_scale '. Please choose between ''lin'' and ''log']);
130 end
131 end
132 else
133 % number of bins in the rebinned data set
134 % If the x-scale is an AO, then take the x values
135 if isa(x_vals, 'ao')
136 if eq(x_vals.xunits, bs(jj).xunits)
137 x_vals = x_vals.x;
138 else
139 error('x_vals AO and data AO have different x-units');
140 end
141 elseif ~isnumeric(x_vals)
142 error('Unsupported x_vals object');
143 end
144 N = length(x_vals) - 1;
145 x_min = x_vals(1:N);
146 x_max = x_vals(2:N+1);
147 end
148
149 x = bs(jj).x;
150 y = bs(jj).y;
151 dy = bs(jj).dy;
152
153 % preallocate output vectors
154 xr = zeros(N, 1);
155 yr = zeros(N, size(y, 2));
156 if strcmpi(method, 'mean') || strcmpi(method, 'wmean')
157 dyr = zeros(N, size(y, 2));
158 else
159 dyr = [];
160 end
161 nr = zeros(N, 1);
162
163 % compute the averages
164 for kk = 1:N
165 in = x >= x_min(kk) & x < x_max(kk);
166 if any(in)
167 nr(kk) = sum(in); % number of points averaged in this bin
168
169 switch method
170 case {'mean', 'median', 'max', 'min', 'rms'}
171 xr(kk) = feval(method, x(in)); % rebinned x bins;
172 yr(kk) = feval(method, y(in)); % rebinned y bins;
173 if strcmpi(method, 'mean')
174 dyr(kk) = std(y(in), 0)/sqrt(nr(kk));
175 % check for zeros in the uncertainty and replace it with the individual point uncertainty
176 if dyr(kk) == 0
177 if inherit_dy && ~isempty(dy)
178 dyr(kk) = mean(dy(in));
179 else
180 dyr(kk) = Inf;
181 end
182 end
183 end
184 case {'wmean'}
185 xr(kk) = mean(x(in)); % rebinned x bins;
186 yr(kk) = sum(y(in).*w(in))./sum(w(in)); % rebinned y bins;
187 dyr(kk) = 1./sqrt(sum(w(in))); % rebinned dy bins;
188 otherwise
189 error(['### Unsupported method ' method]);
190 end
191 end
192 end
193
194 % remove bins where we do not have nothing to average
195 in = nr ~= 0;
196 nr = nr(in);
197 xr = xr(in);
198 yr = yr(in,:);
199 if strcmpi(method, 'mean') || strcmpi(method, 'wmean')
200 dyr = dyr(in,:);
201 end
202
203 % set the new object data
204 bs(jj).setXY(xr, yr);
205 bs(jj).setDy(dyr);
206
207 % nr goes into the procinfo
208 bs(jj).procinfo = plist('navs', nr);
209
210 % set name
211 bs(jj).name = sprintf('bin_data(%s)', ao_invars{jj});
212 % Add history
213 bs(jj).addHistory(getInfo('None'), usepl, ao_invars(jj), bs(jj).hist);
214 else
215 warning('### Ignoring input AO number %d (%s); it is not a 2D data object.', jj, bs(jj).name)
216 end
217 end % loop over analysis objects
218
219 % Set output
220 varargout = utils.helper.setoutputs(nargout, bs);
221 end
222
223 %--------------------------------------------------------------------------
224 % Get Info Object
225 %--------------------------------------------------------------------------
226 function ii = getInfo(varargin)
227 if nargin == 1 && strcmpi(varargin{1}, 'None')
228 sets = {};
229 pl = [];
230 else
231 sets = {'Default'};
232 pl = getDefaultPlist();
233 end
234 % Build info object
235 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: bin_data.m,v 1.20 2011/05/10 16:46:48 mauro Exp $', sets, pl);
236 end
237
238 %--------------------------------------------------------------------------
239 % Get Default Plist
240 %--------------------------------------------------------------------------
241
242 function plout = getDefaultPlist()
243 persistent pl;
244 if ~exist('pl', 'var') || isempty(pl)
245 pl = buildplist();
246 end
247 plout = pl;
248 end
249
250 function pl = buildplist()
251
252 pl = plist();
253
254 % method
255 p = param({'method',['method for binning. Choose from:<ul>', ...
256 '<li>mean</li>', ...
257 '<li>median</li>', ...
258 '<li>max</li>', ...
259 '<li>min</li>', ...
260 '<li>rms</li>', ...
261 '<li>weighted mean (weights can be input or are taken from data dy)</li></ul>']}, ...
262 {1, {'MEAN', 'MEDIAN', 'MAX', 'MIN', 'RMS', 'WMEAN'}, paramValue.SINGLE});
263 pl.append(p);
264
265 % x-scale
266 p = param({'xscale',['scaling of binning. Choose from:<ul>', ...
267 '<li>log - logaritmic</li>', ...
268 '<li>lin - linear</li></ul>']}, {1, {'LOG', 'LIN'}, paramValue.SINGLE});
269 pl.append(p);
270
271 % resolution
272 p = param({'resolution',['When setting logaritmic x scale, it sets the number of points per decade.<br>' ...
273 'When setting linear x scale, it sets the number of points.']}, paramValue.DOUBLE_VALUE(10));
274 pl.append(p);
275
276 % x_vals
277 p = param({'xvals',['List of x values to evaluate the binning between.<br>', ...
278 'It may be a vector or an ao, in which case it will take the x field']}, paramValue.DOUBLE_VALUE([]));
279 pl.append(p);
280
281 % weights
282 p = param({'weights', ['List of weights for the case of weighted mean.<br>', ...
283 'If empty, weights will be taken from object(s) dy field as w = 1/dy^2']}, paramValue.DOUBLE_VALUE([]));
284 pl.append(p);
285
286 % range
287 p = param({'range', ['Range of x where to operate.<br>', ...
288 'If empty, the whole data set will be used']}, paramValue.DOUBLE_VALUE([]));
289 pl.append(p);
290
291 % inherit_dy
292 p = param({'inherit_dy', ['Choose what to do in the case of mean, and bins with only one point. Choose from:<ul>', ...
293 '<li>''yes'' - take the uncertainty from the original data, if defined</li>', ...
294 '<li>''no'' - set it to Inf so it weighs 0 in averaged means</li></ul>' ...
295 ]}, paramValue.YES_NO);
296 pl.append(p);
297 end
298 % END