source: trunk/src/SDMath.cc@ 58

Last change on this file since 58 was 48, checked in by mmarquar, 20 years ago

Fixed various defects. Added averaging of multiple scans, rms, and reworked baseline fitting.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 KB
Line 
1//#---------------------------------------------------------------------------
2//# SDMath.cc: A collection of single dish mathematical operations
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2004
5//# Malte Marquarding, ATNF
6//#
7//# This program is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU General Public License as published by the Free
9//# Software Foundation; either version 2 of the License, or (at your option)
10//# any later version.
11//#
12//# This program is distributed in the hope that it will be useful, but
13//# WITHOUT ANY WARRANTY; without even the implied warranty of
14//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15//# Public License for more details.
16//#
17//# You should have received a copy of the GNU General Public License along
18//# with this program; if not, write to the Free Software Foundation, Inc.,
19//# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning this software should be addressed as follows:
22//# Internet email: Malte.Marquarding@csiro.au
23//# Postal address: Malte Marquarding,
24//# Australia Telescope National Facility,
25//# P.O. Box 76,
26//# Epping, NSW, 2121,
27//# AUSTRALIA
28//#
29//# $Id:
30//#---------------------------------------------------------------------------
31#include <vector>
32
33#include <aips/aips.h>
34#include <aips/Utilities/String.h>
35#include <aips/Arrays/IPosition.h>
36#include <aips/Arrays/Array.h>
37#include <aips/Arrays/ArrayAccessor.h>
38#include <aips/Arrays/Slice.h>
39#include <aips/Arrays/ArrayMath.h>
40#include <aips/Arrays/ArrayLogical.h>
41#include <aips/Arrays/MaskedArray.h>
42#include <aips/Arrays/MaskArrMath.h>
43#include <aips/Arrays/MaskArrLogi.h>
44
45#include <aips/Tables/Table.h>
46#include <aips/Tables/ScalarColumn.h>
47#include <aips/Tables/ArrayColumn.h>
48
49#include <aips/Fitting.h>
50#include <trial/Fitting/LinearFit.h>
51#include <trial/Functionals/CompiledFunction.h>
52#include <trial/Images/ImageUtilities.h>
53#include <trial/Coordinates/SpectralCoordinate.h>
54#include <aips/Mathematics/AutoDiff.h>
55#include <aips/Mathematics/AutoDiffMath.h>
56
57#include "MathUtils.h"
58#include "SDContainer.h"
59#include "SDMemTable.h"
60
61#include "SDMath.h"
62
63using namespace atnf_sd;
64
65static CountedPtr<SDMemTable> SDMath::average(const CountedPtr<SDMemTable>& in) {
66 Table t = in->table();
67 ROArrayColumn<Float> tsys(t, "TSYS");
68 ROScalarColumn<Double> mjd(t, "TIME");
69 ROScalarColumn<String> srcn(t, "SRCNAME");
70 ROScalarColumn<Double> integr(t, "INTERVAL");
71 ROArrayColumn<uInt> freqidc(t, "FREQID");
72 IPosition ip = in->rowAsMaskedArray(0).shape();
73 Array<Float> outarr(ip); outarr =0.0;
74 Array<Float> narr(ip);narr = 0.0;
75 Array<Float> narrinc(ip);narrinc = 1.0;
76
77 Array<Float> tsarr(tsys.shape(0));
78 Array<Float> outtsarr(tsys.shape(0));
79 outtsarr =0.0;
80 tsys.get(0, tsarr);// this is probably unneccessary as tsys should
81 Double tme = 0.0;
82 Double inttime = 0.0;
83
84 for (uInt i=0; i < t.nrow(); i++) {
85 // data stuff
86 MaskedArray<Float> marr(in->rowAsMaskedArray(i));
87 outarr += marr;
88 MaskedArray<Float> n(narrinc,marr.getMask());
89 narr += n;
90 // get
91 tsys.get(i, tsarr);// this is probably unneccessary as tsys should
92 outtsarr += tsarr; // be constant
93 Double tmp;
94 mjd.get(i,tmp);
95 tme += tmp;// average time
96 integr.get(i,tmp);
97 inttime += tmp;
98 }
99 // averaging using mask
100 MaskedArray<Float> nma(narr,(narr > Float(0)));
101 outarr /= nma;
102 Array<Bool> outflagsb = !(nma.getMask());
103 Array<uChar> outflags(outflagsb.shape());
104 convertArray(outflags,outflagsb);
105 SDContainer sc = in->getSDContainer();
106 Int n = t.nrow();
107 outtsarr /= Float(n);
108 sc.timestamp = tme/Double(n);
109 sc.interval = inttime;
110 String tstr; srcn.getScalar(0,tstr);// get sourcename of "mid" point
111 sc.sourcename = tstr;
112 Vector<uInt> tvec;
113 freqidc.get(0,tvec);
114 sc.putFreqMap(tvec);
115 sc.putTsys(outtsarr);
116 sc.scanid = 0;
117 sc.putSpectrum(outarr);
118 sc.putFlags(outflags);
119 SDMemTable* sdmt = new SDMemTable(*in,True);
120 sdmt->putSDContainer(sc);
121 return CountedPtr<SDMemTable>(sdmt);
122}
123
124static CountedPtr<SDMemTable>
125SDMath::quotient(const CountedPtr<SDMemTable>& on,
126 const CountedPtr<SDMemTable>& off) {
127
128 Table ton = on->table();
129 Table toff = off->table();
130 ROArrayColumn<Float> tsys(toff, "TSYS");
131 ROScalarColumn<Double> mjd(ton, "TIME");
132 ROScalarColumn<Double> integr(ton, "INTERVAL");
133 ROScalarColumn<String> srcn(ton, "SRCNAME");
134 ROArrayColumn<uInt> freqidc(ton, "FREQID");
135
136 MaskedArray<Float> mon(on->rowAsMaskedArray(0));
137 MaskedArray<Float> moff(off->rowAsMaskedArray(0));
138 IPosition ipon = mon.shape();
139 IPosition ipoff = moff.shape();
140 Array<Float> tsarr;//(tsys.shape(0));
141 tsys.get(0, tsarr);
142 if (ipon != ipoff && ipon != tsarr.shape())
143 cerr << "on/off not conformant" << endl;
144
145 MaskedArray<Float> tmp = (mon-moff);
146 Array<Float> out(tmp.getArray());
147 out /= moff;
148 out *= tsarr;
149 Array<Bool> outflagsb = !(mon.getMask() && moff.getMask());
150 Array<uChar> outflags(outflagsb.shape());
151 convertArray(outflags,outflagsb);
152 SDContainer sc = on->getSDContainer();
153 sc.putTsys(tsarr);
154 sc.scanid = 0;
155 sc.putSpectrum(out);
156 sc.putFlags(outflags);
157 SDMemTable* sdmt = new SDMemTable(*on, True);
158 sdmt->putSDContainer(sc);
159 return CountedPtr<SDMemTable>(sdmt);
160}
161
162static CountedPtr<SDMemTable>
163SDMath::multiply(const CountedPtr<SDMemTable>& in, Float factor) {
164 SDMemTable* sdmt = new SDMemTable(*in);
165 Table t = sdmt->table();
166 ArrayColumn<Float> spec(t,"SPECTRA");
167
168 for (uInt i=0; i < t.nrow(); i++) {
169 // data stuff
170 MaskedArray<Float> marr(sdmt->rowAsMaskedArray(i));
171 marr *= factor;
172 spec.put(i, marr.getArray());
173 }
174 return CountedPtr<SDMemTable>(sdmt);
175}
176
177static bool SDMath::fit(Vector<Float>& thefit, const Vector<Float>& data,
178 const Vector<Bool>& mask,
179 const std::string& fitexpr) {
180
181 LinearFit<Float> fitter;
182 Vector<Float> x(data.nelements());
183 indgen(x);
184 CompiledFunction<AutoDiff<Float> > fn;
185 fn.setFunction(String(fitexpr));
186 fitter.setFunction(fn);
187 Vector<Float> out,out1;
188 out = fitter.fit(x,data,&mask);
189 thefit = data;
190 fitter.residual(thefit, x);
191 cout << "Parameter solution = " << out << endl;
192 return True;
193}
194
195static CountedPtr<SDMemTable>
196SDMath::baseline(const CountedPtr<SDMemTable>& in,
197 const std::string& fitexpr,
198 const std::vector<bool>& mask) {
199
200 IPosition ip = in->rowAsMaskedArray(0).shape();
201 SDContainer sc = in->getSDContainer();
202 String sname(in->getSourceName());
203 String stim(in->getTime());
204 cout << "Fitting: " << String(fitexpr) << " to "
205 << sname << " [" << stim << "]" << ":" <<endl;
206 MaskedArray<Float> marr(in->rowAsMaskedArray(0));
207 Vector<Bool> inmask(mask);
208 Array<Float> arr = marr.getArray();
209 Array<Bool> barr = marr.getMask();
210 for (uInt i=0; i<in->nBeam();++i) {
211 for (uInt j=0; j<in->nIF();++j) {
212 for (uInt k=0; k<in->nPol();++k) {
213 IPosition start(4,i,j,k,0);
214 IPosition end(4,i,j,k,in->nChan()-1);
215 Array<Float> subArr(arr(start,end));
216 Array<Bool> subMask(barr(start,end));
217 Vector<Float> outv;
218 Vector<Float> v(subArr.nonDegenerate());
219 Vector<Bool> m(subMask.nonDegenerate());
220 cout << "\t Polarisation " << k << "\t";
221 SDMath::fit(outv, v, m&&inmask, fitexpr);
222 ArrayAccessor<Float, Axis<0> > aa0(outv);
223 for (ArrayAccessor<Float, Axis<3> > aa(subArr); aa != aa.end();++aa) {
224 (*aa) = (*aa0);
225 aa0++;
226 }
227 }
228 }
229 }
230 Array<uChar> outflags(barr.shape());
231 convertArray(outflags,!barr);
232 sc.putSpectrum(arr);
233 sc.putFlags(outflags);
234 SDMemTable* sdmt = new SDMemTable(*in,True);
235 sdmt->putSDContainer(sc);
236 return CountedPtr<SDMemTable>(sdmt);
237}
238
239
240static CountedPtr<SDMemTable>
241SDMath::hanning(const CountedPtr<SDMemTable>& in) {
242
243 IPosition ip = in->rowAsMaskedArray(0).shape();
244 MaskedArray<Float> marr(in->rowAsMaskedArray(0));
245
246 Array<Float> arr = marr.getArray();
247 Array<Bool> barr = marr.getMask();
248 for (uInt i=0; i<in->nBeam();++i) {
249 for (uInt j=0; j<in->nIF();++j) {
250 for (uInt k=0; k<in->nPol();++k) {
251 IPosition start(4,i,j,k,0);
252 IPosition end(4,i,j,k,in->nChan()-1);
253 Array<Float> subArr(arr(start,end));
254 Array<Bool> subMask(barr(start,end));
255 Vector<Float> outv;
256 Vector<Bool> outm;
257 Vector<Float> v(subArr.nonDegenerate());
258 Vector<Bool> m(subMask.nonDegenerate());
259 ::hanning(outv,outm,v,m);
260 ArrayAccessor<Float, Axis<0> > aa0(outv);
261 ArrayAccessor<Bool, Axis<0> > ba0(outm);
262 ArrayAccessor<Bool, Axis<3> > ba(subMask);
263 for (ArrayAccessor<Float, Axis<3> > aa(subArr); aa != aa.end();++aa) {
264 (*aa) = (*aa0);
265 (*ba) = (*ba0);
266 aa0++;
267 ba0++;
268 ba++;
269 }
270 }
271 }
272 }
273 Array<uChar> outflags(barr.shape());
274 convertArray(outflags,!barr);
275 SDContainer sc = in->getSDContainer();
276 sc.putSpectrum(arr);
277 sc.putFlags(outflags);
278 SDMemTable* sdmt = new SDMemTable(*in,True);
279 sdmt->putSDContainer(sc);
280 return CountedPtr<SDMemTable>(sdmt);
281}
282
283static CountedPtr<SDMemTable>
284SDMath::averages(const Block<CountedPtr<SDMemTable> >& in,
285 const Vector<Bool>& mask) {
286 IPosition ip = in[0]->rowAsMaskedArray(0).shape();
287 Array<Float> arr(ip);
288 Array<Bool> barr(ip);
289 Double inttime = 0.0;
290
291 uInt n = in[0]->nChan();
292 for (uInt i=0; i<in[0]->nBeam();++i) {
293 for (uInt j=0; j<in[0]->nIF();++j) {
294 for (uInt k=0; k<in[0]->nPol();++k) {
295 Float stdevsqsum = 0.0;
296 Vector<Float> initvec(n);initvec = 0.0;
297 Vector<Bool> initmask(n);initmask = True;
298 MaskedArray<Float> outmarr(initvec,initmask);
299 for (uInt bi=0; bi< in.nelements(); ++bi) {
300 MaskedArray<Float> marr(in[bi]->rowAsMaskedArray(0));
301 inttime += in[bi]->getInterval();
302 Array<Float> arr = marr.getArray();
303 Array<Bool> barr = marr.getMask();
304 IPosition start(4,i,j,k,0);
305 IPosition end(4,i,j,k,n-1);
306 Array<Float> subArr(arr(start,end));
307 Array<Bool> subMask(barr(start,end));
308 Vector<Float> outv;
309 Vector<Bool> outm;
310 Vector<Float> v(subArr.nonDegenerate());
311 Vector<Bool> m(subMask.nonDegenerate());
312 MaskedArray<Float> tmparr(v,m);
313 MaskedArray<Float> tmparr2(tmparr(mask));
314 Float stdvsq = pow(stddev(tmparr2),2);
315 stdevsqsum+=1.0/stdvsq;
316 tmparr /= stdvsq;
317 outmarr += tmparr;
318 }
319 outmarr /= stdevsqsum;
320 Array<Float> tarr(outmarr.getArray());
321 Array<Bool> tbarr(outmarr.getMask());
322 IPosition start(4,i,j,k,0);
323 IPosition end(4,i,j,k,n-1);
324 Array<Float> subArr(arr(start,end));
325 Array<Bool> subMask(barr(start,end));
326 ArrayAccessor<Float, Axis<0> > aa0(tarr);
327 ArrayAccessor<Bool, Axis<0> > ba0(tbarr);
328 ArrayAccessor<Bool, Axis<3> > ba(subMask);
329 for (ArrayAccessor<Float, Axis<3> > aa(subArr); aa != aa.end();++aa) {
330 (*aa) = (*aa0);
331 (*ba) = (*ba0);
332 aa0++;
333 ba0++;
334 ba++;
335 }
336 }
337 }
338 }
339 Array<uChar> outflags(barr.shape());
340 convertArray(outflags,!barr);
341 SDContainer sc = in[0]->getSDContainer();
342 sc.putSpectrum(arr);
343 sc.putFlags(outflags);
344 sc.interval = inttime;
345 SDMemTable* sdmt = new SDMemTable(*in[0],True);
346 sdmt->putSDContainer(sc);
347 return CountedPtr<SDMemTable>(sdmt);
348}
349
350static CountedPtr<SDMemTable>
351SDMath::averagePol(const CountedPtr<SDMemTable>& in,
352 const Vector<Bool>& mask) {
353 MaskedArray<Float> marr(in->rowAsMaskedArray(0));
354 uInt n = in->nChan();
355 IPosition ip = marr.shape();
356 Array<Float> arr = marr.getArray();
357 Array<Bool> barr = marr.getMask();
358 for (uInt i=0; i<in->nBeam();++i) {
359 for (uInt j=0; j<in->nIF();++j) {
360 Float stdevsqsum = 0.0;
361 Vector<Float> initvec(n);initvec = 0.0;
362 Vector<Bool> initmask(n);initmask = True;
363 MaskedArray<Float> outmarr(initvec,initmask);
364 for (uInt k=0; k<in->nPol();++k) {
365 IPosition start(4,i,j,k,0);
366 IPosition end(4,i,j,k,in->nChan()-1);
367 Array<Float> subArr(arr(start,end));
368 Array<Bool> subMask(barr(start,end));
369 Vector<Float> outv;
370 Vector<Bool> outm;
371 Vector<Float> v(subArr.nonDegenerate());
372 Vector<Bool> m(subMask.nonDegenerate());
373 MaskedArray<Float> tmparr(v,m);
374 MaskedArray<Float> tmparr2(tmparr(mask));
375 Float stdvsq = pow(stddev(tmparr2),2);
376 stdevsqsum+=1.0/stdvsq;
377 tmparr /= stdvsq;
378 outmarr += tmparr;
379 }
380 outmarr /= stdevsqsum;
381 Array<Float> tarr(outmarr.getArray());
382 Array<Bool> tbarr(outmarr.getMask());
383 // write averaged pol into all pols - fix up to refrom array
384 for (uInt k=0; k<in->nPol();++k) {
385 IPosition start(4,i,j,k,0);
386 IPosition end(4,i,j,k,n-1);
387 Array<Float> subArr(arr(start,end));
388 Array<Bool> subMask(barr(start,end));
389 ArrayAccessor<Float, Axis<0> > aa0(tarr);
390 ArrayAccessor<Bool, Axis<0> > ba0(tbarr);
391 ArrayAccessor<Bool, Axis<3> > ba(subMask);
392 for (ArrayAccessor<Float, Axis<3> > aa(subArr); aa != aa.end();++aa) {
393 (*aa) = (*aa0);
394 (*ba) = (*ba0);
395 aa0++;
396 ba0++;
397 ba++;
398 }
399 }
400 }
401 }
402
403 Array<uChar> outflags(barr.shape());
404 convertArray(outflags,!barr);
405 SDContainer sc = in->getSDContainer();
406 sc.putSpectrum(arr);
407 sc.putFlags(outflags);
408 SDMemTable* sdmt = new SDMemTable(*in,True);
409 sdmt->putSDContainer(sc);
410 return CountedPtr<SDMemTable>(sdmt);
411}
412
413
414static Float SDMath::rms(const CountedPtr<SDMemTable>& in,
415 const std::vector<bool>& mask) {
416 Float rmsval;
417 Vector<Bool> msk(mask);
418 IPosition ip = in->rowAsMaskedArray(0).shape();
419 MaskedArray<Float> marr(in->rowAsMaskedArray(0));
420
421 Array<Float> arr = marr.getArray();
422 Array<Bool> barr = marr.getMask();
423 uInt i,j,k;
424 i = in->getBeam();
425 j = in->getIF();
426 k = in->getPol();
427 IPosition start(4,i,j,k,0);
428 IPosition end(4,i,j,k,in->nChan()-1);
429 Array<Float> subArr(arr(start,end));
430 Array<Bool> subMask(barr(start,end));
431 Array<Float> v(subArr.nonDegenerate());
432 Array<Bool> m(subMask.nonDegenerate());
433 MaskedArray<Float> tmp;
434 if (msk.nelements() == m.nelements() ) {
435 tmp.setData(v,m&&msk);
436 } else {
437 tmp.setData(v,m);
438 }
439 rmsval = stddev(tmp);
440 return rmsval;
441}
442
443static CountedPtr<SDMemTable> SDMath::bin(const CountedPtr<SDMemTable>& in,
444 Int width) {
445
446 MaskedArray<Float> marr(in->rowAsMaskedArray(0));
447 SpectralCoordinate coord(in->getCoordinate(0));
448 SDContainer sc = in->getSDContainer();
449 Array<Float> arr = marr.getArray();
450 Array<Bool> barr = marr.getMask();
451 SpectralCoordinate outcoord,outcoord2;
452 MaskedArray<Float> marrout;
453 ImageUtilities::bin(marrout, outcoord, marr, coord, 3, width);
454 IPosition ip = marrout.shape();
455 sc.resize(ip);
456 sc.putSpectrum(marrout.getArray());
457 Array<uChar> outflags(ip);
458 convertArray(outflags,!(marrout.getMask()));
459 sc.putFlags(outflags);
460 MaskedArray<Float> tsys,tsysout;
461 Array<Bool> dummy(ip);dummy = True;
462 tsys.setData(sc.getTsys(),dummy);
463 ImageUtilities::bin(tsysout, outcoord2, marr, outcoord, 3, width);
464 sc.putTsys(tsysout.getArray());
465 SDHeader sh = in->getSDHeader();
466 sh.nchan = ip(3);
467 SDMemTable* sdmt = new SDMemTable(*in,True);
468 sdmt->setCoordinate(outcoord,0);
469 sdmt->putSDContainer(sc);
470 sdmt->putSDHeader(sh);
471 return CountedPtr<SDMemTable>(sdmt);
472}
Note: See TracBrowser for help on using the repository browser.