Changeset 130
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/SDMath.cc
r125 r130 35 35 #include <casa/Arrays/IPosition.h> 36 36 #include <casa/Arrays/Array.h> 37 #include <casa/Arrays/Array Accessor.h>38 #include <casa/Arrays/ Slice.h>37 #include <casa/Arrays/ArrayIter.h> 38 #include <casa/Arrays/VectorIter.h> 39 39 #include <casa/Arrays/ArrayMath.h> 40 40 #include <casa/Arrays/ArrayLogical.h> … … 42 42 #include <casa/Arrays/MaskArrMath.h> 43 43 #include <casa/Arrays/MaskArrLogi.h> 44 #include <casa/ Arrays/VectorIter.h>44 #include <casa/Exceptions.h> 45 45 46 46 #include <tables/Tables/Table.h> … … 48 48 #include <tables/Tables/ArrayColumn.h> 49 49 50 #include <scimath/Fitting.h> 51 #include <scimath/Fitting/LinearFit.h> 52 #include <scimath/Functionals/CompiledFunction.h> 53 #include <images/Images/ImageUtilities.h> 50 #include <lattices/Lattices/LatticeUtilities.h> 51 #include <lattices/Lattices/RebinLattice.h> 54 52 #include <coordinates/Coordinates/SpectralCoordinate.h> 55 #include < scimath/Mathematics/AutoDiff.h>56 #include < scimath/Mathematics/AutoDiffMath.h>53 #include <coordinates/Coordinates/CoordinateSystem.h> 54 #include <coordinates/Coordinates/CoordinateUtil.h> 57 55 58 56 #include "MathUtils.h" … … 66 64 //using namespace asap::SDMath; 67 65 68 CountedPtr<SDMemTable> SDMath::average(const CountedPtr<SDMemTable>& in) { 66 CountedPtr<SDMemTable> SDMath::average(const CountedPtr<SDMemTable>& in) 67 // 68 // Average all rows in Table in time 69 // 70 { 69 71 Table t = in->table(); 70 72 ROArrayColumn<Float> tsys(t, "TSYS"); … … 85 87 Double inttime = 0.0; 86 88 89 // Loop over rows 90 87 91 for (uInt i=0; i < t.nrow(); i++) { 88 // data stuff 92 93 // Get data and accumulate sums 94 89 95 MaskedArray<Float> marr(in->rowAsMaskedArray(i)); 90 96 outarr += marr; 91 97 MaskedArray<Float> n(narrinc,marr.getMask()); 92 98 narr += n; 93 // get 99 100 // Accumulkate Tsys 101 94 102 tsys.get(i, tsarr);// this is probably unneccessary as tsys should 95 103 outtsarr += tsarr; // be constant … … 100 108 inttime += tmp; 101 109 } 102 // averaging using mask 110 111 // Average 112 103 113 MaskedArray<Float> nma(narr,(narr > Float(0))); 104 114 outarr /= nma; 115 116 // Create container and put 117 105 118 Array<Bool> outflagsb = !(nma.getMask()); 106 119 Array<uChar> outflags(outflagsb.shape()); … … 127 140 CountedPtr<SDMemTable> 128 141 SDMath::quotient(const CountedPtr<SDMemTable>& on, 129 const CountedPtr<SDMemTable>& off) { 142 const CountedPtr<SDMemTable>& off) 143 // 144 // Compute quotient spectrum 145 // 146 { 147 const uInt nRows = on->nRow(); 148 if (off->nRow() != nRows) { 149 throw (AipsError("Input Scan Tables must have the same number of rows")); 150 } 151 152 // Input Tables and columns 130 153 131 154 Table ton = on->table(); … … 137 160 ROArrayColumn<uInt> freqidc(ton, "FREQID"); 138 161 139 MaskedArray<Float> mon(on->rowAsMaskedArray(0)); 140 MaskedArray<Float> moff(off->rowAsMaskedArray(0)); 141 IPosition ipon = mon.shape(); 142 IPosition ipoff = moff.shape(); 143 Array<Float> tsarr;//(tsys.shape(0)); 144 tsys.get(0, tsarr); 145 if (ipon != ipoff && ipon != tsarr.shape()) 146 cerr << "on/off not conformant" << endl; 147 148 MaskedArray<Float> tmp = (mon-moff); 149 Array<Float> out(tmp.getArray()); 150 out /= moff; 151 out *= tsarr; 152 Array<Bool> outflagsb = !(mon.getMask() && moff.getMask()); 153 Array<uChar> outflags(outflagsb.shape()); 154 convertArray(outflags,outflagsb); 155 SDContainer sc = on->getSDContainer(); 156 sc.putTsys(tsarr); 157 sc.scanid = 0; 158 sc.putSpectrum(out); 159 sc.putFlags(outflags); 162 // Output Table cloned from input 163 160 164 SDMemTable* sdmt = new SDMemTable(*on, True); 161 sdmt->putSDContainer(sc); 165 166 // Loop over rows 167 168 for (uInt i=0; i<nRows; i++) { 169 MaskedArray<Float> mon(on->rowAsMaskedArray(i)); 170 MaskedArray<Float> moff(off->rowAsMaskedArray(i)); 171 IPosition ipon = mon.shape(); 172 IPosition ipoff = moff.shape(); 173 // 174 Array<Float> tsarr; 175 tsys.get(i, tsarr); 176 if (ipon != ipoff && ipon != tsarr.shape()) { 177 throw(AipsError("on/off not conformant")); 178 } 179 180 // Compute quotient 181 182 MaskedArray<Float> tmp = (mon-moff); 183 Array<Float> out(tmp.getArray()); 184 out /= moff; 185 out *= tsarr; 186 Array<Bool> outflagsb = !(mon.getMask() && moff.getMask()); 187 Array<uChar> outflags(outflagsb.shape()); 188 convertArray(outflags,outflagsb); 189 190 // Fill container for this row 191 192 SDContainer sc = on->getSDContainer(); 193 sc.putTsys(tsarr); 194 sc.scanid = 0; 195 sc.putSpectrum(out); 196 sc.putFlags(outflags); 197 198 // Put new row in output Table 199 200 sdmt->putSDContainer(sc); 201 } 202 // 162 203 return CountedPtr<SDMemTable>(sdmt); 163 204 } 164 205 165 206 CountedPtr<SDMemTable> 166 SDMath::multiply(const CountedPtr<SDMemTable>& in, Float factor) { 207 SDMath::multiply(const CountedPtr<SDMemTable>& in, Float factor) 208 // 209 // Multiply values by factor 210 // 211 { 167 212 SDMemTable* sdmt = new SDMemTable(*in); 168 213 Table t = sdmt->table(); … … 170 215 171 216 for (uInt i=0; i < t.nrow(); i++) { 172 // data stuff173 217 MaskedArray<Float> marr(sdmt->rowAsMaskedArray(i)); 174 218 marr *= factor; … … 179 223 180 224 CountedPtr<SDMemTable> 181 SDMath::add(const CountedPtr<SDMemTable>& in, Float offset) { 225 SDMath::add(const CountedPtr<SDMemTable>& in, Float offset) 226 // 227 // Add offset to values 228 // 229 { 182 230 SDMemTable* sdmt = new SDMemTable(*in); 231 183 232 Table t = sdmt->table(); 184 233 ArrayColumn<Float> spec(t,"SPECTRA"); 185 234 186 235 for (uInt i=0; i < t.nrow(); i++) { 187 // data stuff188 236 MaskedArray<Float> marr(sdmt->rowAsMaskedArray(i)); 189 237 marr += offset; … … 194 242 195 243 196 // Start NEBK197 // SHow how to do above with VectorIterator198 199 // uInt axis = 3;200 // VectorIterator<Float> itData(arr, axis);201 // ReadOnlyVectorIterator<Bool> itMask(barr, axis);202 // Vector<Float> outv;203 // while (!itData.pastEnd()) {204 // SDMath::fit(outv, itData.vector(), itMask.vector()&&inmask, fitexpr); // Should have function205 // itData.vector() = outv; // to do in situ206 // //207 // SDMath::fit(itData.vector(), itData.vector(), itMask.vector()&&inmask, fitexpr); // Or maybe this works208 // //209 // itData.next();210 // itMask.next();211 // }212 213 // End NEBK214 215 244 CountedPtr<SDMemTable> 216 SDMath::hanning(const CountedPtr<SDMemTable>& in) { 217 218 //IPosition ip = in->rowAsMaskedArray(0).shape(); 245 SDMath::hanning(const CountedPtr<SDMemTable>& in) 246 // 247 // Hanning smooth each row 248 // Should Tsys be smoothed ? 249 // 250 { 219 251 SDMemTable* sdmt = new SDMemTable(*in,True); 252 253 // Loop over rows in Table 254 220 255 for (uInt ri=0; ri < in->nRow(); ++ri) { 256 257 // Get data 221 258 222 MaskedArray<Float> marr(in->rowAsMaskedArray(ri)); 223 259 const MaskedArray<Float>& marr(in->rowAsMaskedArray(ri)); 224 260 Array<Float> arr = marr.getArray(); 225 261 Array<Bool> barr = marr.getMask(); 226 for (uInt i=0; i<in->nBeam();++i) { 227 for (uInt j=0; j<in->nIF();++j) { 228 for (uInt k=0; k<in->nPol();++k) { 229 IPosition start(4,i,j,k,0); 230 IPosition end(4,i,j,k,in->nChan()-1); 231 Array<Float> subArr(arr(start,end)); 232 Array<Bool> subMask(barr(start,end)); 233 Vector<Float> outv; 234 Vector<Bool> outm; 235 Vector<Float> v(subArr.nonDegenerate()); 236 Vector<Bool> m(subMask.nonDegenerate()); 237 mathutil::hanning(outv,outm,v,m); 238 ArrayAccessor<Float, Axis<0> > aa0(outv); 239 ArrayAccessor<Bool, Axis<0> > ba0(outm); 240 ArrayAccessor<Bool, Axis<3> > ba(subMask); 241 for (ArrayAccessor<Float, Axis<3> > aa(subArr); 242 aa != aa.end();++aa) { 243 (*aa) = (*aa0); 244 (*ba) = (*ba0); 245 aa0++; 246 ba0++; 247 ba++; 248 } 249 } 250 } 262 263 // Smooth along the channels axis 264 265 uInt axis = 3; 266 VectorIterator<Float> itData(arr, axis); 267 VectorIterator<Bool> itMask(barr, axis); 268 Vector<Float> outv; 269 Vector<Bool> outm; 270 while (!itData.pastEnd()) { 271 mathutil::hanning(outv, outm, itData.vector(), itMask.vector()); 272 itData.vector() = outv; 273 itMask.vector() = outm; 274 // 275 itData.next(); 276 itMask.next(); 251 277 } 252 // 253 254 // uInt axis = 3; 255 // VectorIterator<Float> itData(arr, axis); 256 // VectorIterator<Bool> itMask(barr, axis); 257 // Vector<Float> outv; 258 // Vector<Bool> outm; 259 // while (!itData.pastEnd()) { 260 // ::hanning(outv, outm, itData.vector(), itMask.vector()); 261 // itData.vector() = outv; 262 // itMask.vector() = outm; 263 // // 264 // itData.next(); 265 // itMask.next(); 266 // } 267 268 // End NEBK 269 270 // 278 279 // Create and put back 280 271 281 Array<uChar> outflags(barr.shape()); 272 282 convertArray(outflags,!barr); … … 279 289 } 280 290 281 CountedPtr<SDMemTable> 282 SDMath::averages(const Block<CountedPtr<SDMemTable> >& in, 283 const Vector<Bool>& mask) { 284 IPosition ip = in[0]->rowAsMaskedArray(0).shape(); 285 Array<Float> arr(ip); 286 Array<Bool> barr(ip); 287 Double inttime = 0.0; 288 289 uInt n = in[0]->nChan(); 290 for (uInt i=0; i<in[0]->nBeam();++i) { 291 for (uInt j=0; j<in[0]->nIF();++j) { 292 for (uInt k=0; k<in[0]->nPol();++k) { 293 Float stdevsqsum = 0.0; 294 Vector<Float> initvec(n);initvec = 0.0; 295 Vector<Bool> initmask(n);initmask = True; 296 MaskedArray<Float> outmarr(initvec,initmask); 297 inttime = 0.0; 298 for (uInt bi=0; bi< in.nelements(); ++bi) { 299 MaskedArray<Float> marr(in[bi]->rowAsMaskedArray(0)); 300 inttime += in[bi]->getInterval(); 301 Array<Float> arr = marr.getArray(); 302 Array<Bool> barr = marr.getMask(); 303 IPosition start(4,i,j,k,0); 304 IPosition end(4,i,j,k,n-1); 305 Array<Float> subArr(arr(start,end)); 306 Array<Bool> subMask(barr(start,end)); 307 Vector<Float> outv; 308 Vector<Bool> outm; 309 Vector<Float> v(subArr.nonDegenerate()); 310 Vector<Bool> m(subMask.nonDegenerate()); 311 MaskedArray<Float> tmparr(v,m); 312 MaskedArray<Float> tmparr2(tmparr(mask)); 313 Float stdvsq = pow(stddev(tmparr2),2); 314 stdevsqsum+=1.0/stdvsq; 315 tmparr /= stdvsq; 316 outmarr += tmparr; 291 292 293 CountedPtr<SDMemTable> SDMath::averages(const Block<CountedPtr<SDMemTable> >& in, 294 const Vector<Bool>& mask) 295 // 296 // Noise weighted averaging of spectra from many Tables. Tables can have different 297 // number of rows. 298 // 299 { 300 301 // Setup 302 303 const uInt axis = 3; // Spectral axis 304 IPosition shp = in[0]->rowAsMaskedArray(0).shape(); 305 Array<Float> arr(shp); 306 Array<Bool> barr(shp); 307 Double sumInterval = 0.0; 308 const Bool useMask = (mask.nelements() == shp(axis)); 309 310 // Create data accumulation MaskedArray. We accumulate for each 311 // channel,if,pol,beam 312 313 Array<Float> zero(shp); zero=0.0; 314 Array<Bool> good(shp); good = True; 315 MaskedArray<Float> sum(zero,good); 316 317 // Create accumulation Array for variance. We accumulate for 318 // each if,pol,beam, but average over channel 319 320 const uInt nAxesSub = shp.nelements() - 1; 321 IPosition shp2(nAxesSub); 322 for (uInt i=0,j=0; i<(nAxesSub+1); i++) { 323 if (i!=axis) { 324 shp2(j) = shp(i); 325 j++; 326 } 327 } 328 Array<Float> sumSq(shp2); 329 sumSq = 0.0; 330 IPosition pos2(nAxesSub,0); // FOr indexing 331 // 332 Float fac = 1.0; 333 const uInt nTables = in.nelements(); 334 for (uInt iTab=0; iTab<nTables; iTab++) { 335 const uInt nRows = in[iTab]->nRow(); 336 sumInterval += nRows * in[iTab]->getInterval(); // Sum of time intervals 337 // 338 for (uInt iRow=0; iRow<nRows; iRow++) { 339 340 // Check conforms 341 342 IPosition shp2 = in[iTab]->rowAsMaskedArray(iRow).shape(); 343 if (!shp.isEqual(shp2)) { 344 throw (AipsError("Shapes for all rows must be the same")); 317 345 } 318 outmarr /= stdevsqsum; 319 Array<Float> tarr(outmarr.getArray()); 320 Array<Bool> tbarr(outmarr.getMask()); 321 IPosition start(4,i,j,k,0); 322 IPosition end(4,i,j,k,n-1); 323 Array<Float> subArr(arr(start,end)); 324 Array<Bool> subMask(barr(start,end)); 325 ArrayAccessor<Float, Axis<0> > aa0(tarr); 326 ArrayAccessor<Bool, Axis<0> > ba0(tbarr); 327 ArrayAccessor<Bool, Axis<3> > ba(subMask); 328 for (ArrayAccessor<Float, Axis<3> > aa(subArr); aa != aa.end();++aa) { 329 (*aa) = (*aa0); 330 (*ba) = (*ba0); 331 aa0++; 332 ba0++; 333 ba++; 334 } 335 } 346 347 // Get data and deconstruct 348 349 MaskedArray<Float> marr(in[iTab]->rowAsMaskedArray(iRow)); 350 Array<Float>& arr = marr.getRWArray(); // writable reference 351 const Array<Bool>& barr = marr.getMask(); // RO reference 352 353 // We are going to average the data, weighted by the noise for each 354 // pol, beam and IF. So therefore we need to iterate through by 355 // spectra (axis 3) 356 357 VectorIterator<Float> itData(arr, axis); 358 ReadOnlyVectorIterator<Bool> itMask(barr, axis); 359 while (!itData.pastEnd()) { 360 361 // Make MaskedArray of Vector, optionally apply OTF mask, and find scaling factor 362 363 if (useMask) { 364 MaskedArray<Float> tmp(itData.vector(),mask&&itMask.vector()); 365 fac = 1.0/variance(tmp); 366 } else { 367 MaskedArray<Float> tmp(itData.vector(),itMask.vector()); 368 fac = 1.0/variance(tmp); 369 } 370 371 // Scale data 372 373 itData.vector() *= fac; 374 375 // Accumulate variance per if/pol/beam averaged over spectrum 376 // This method to get pos2 from itData.pos() is only valid 377 // because the spectral axis is the last one (so we can just 378 // copy the first nAXesSub positions out) 379 380 pos2 = itData.pos().getFirst(nAxesSub); 381 sumSq(pos2) += fac; 382 // 383 itData.next(); 384 itMask.next(); 385 } 386 387 // Accumulate sums 388 389 sum += marr; 336 390 } 337 391 } 338 Array<uChar> outflags(barr.shape()); 339 convertArray(outflags,!barr); 340 SDContainer sc = in[0]->getSDContainer(); 341 sc.putSpectrum(arr); 392 393 // Normalize by the sum of the 1/var. 394 395 Array<Float>& data = sum.getRWArray(); 396 VectorIterator<Float> itData(data, axis); 397 while (!itData.pastEnd()) { 398 pos2 = itData.pos().getFirst(nAxesSub); // See comments above 399 itData.vector() /= sumSq(pos2); 400 itData.next(); 401 } 402 403 // Create and fill output 404 405 Array<uChar> outflags(shp); 406 convertArray(outflags,!(sum.getMask())); 407 // 408 SDContainer sc = in[0]->getSDContainer(); // CLone from first container of first Table 409 sc.putSpectrum(data); 342 410 sc.putFlags(outflags); 343 sc.interval = inttime; 344 SDMemTable* sdmt = new SDMemTable(*in[0],True); 411 sc.interval = sumInterval; 412 // 413 SDMemTable* sdmt = new SDMemTable(*in[0],True); // CLone from first Table 345 414 sdmt->putSDContainer(sc); 346 415 return CountedPtr<SDMemTable>(sdmt); 347 416 } 417 348 418 349 419 CountedPtr<SDMemTable> 350 420 SDMath::averagePol(const CountedPtr<SDMemTable>& in, 351 const Vector<Bool>& mask) { 352 MaskedArray<Float> marr(in->rowAsMaskedArray(0)); 353 uInt n = in->nChan(); 354 IPosition ip = marr.shape(); 355 Array<Float> arr = marr.getArray(); 356 Array<Bool> barr = marr.getMask(); 357 for (uInt i=0; i<in->nBeam();++i) { 358 for (uInt j=0; j<in->nIF();++j) { 359 Float stdevsqsum = 0.0; 360 Vector<Float> initvec(n);initvec = 0.0; 361 Vector<Bool> initmask(n);initmask = True; 362 MaskedArray<Float> outmarr(initvec,initmask); 363 for (uInt k=0; k<in->nPol();++k) { 364 IPosition start(4,i,j,k,0); 365 IPosition end(4,i,j,k,in->nChan()-1); 366 Array<Float> subArr(arr(start,end)); 367 Array<Bool> subMask(barr(start,end)); 368 Vector<Float> outv; 369 Vector<Bool> outm; 370 Vector<Float> v(subArr.nonDegenerate()); 371 Vector<Bool> m(subMask.nonDegenerate()); 372 MaskedArray<Float> tmparr(v,m); 373 MaskedArray<Float> tmparr2(tmparr(mask)); 374 Float stdvsq = pow(stddev(tmparr2),2); 375 stdevsqsum+=1.0/stdvsq; 376 tmparr /= stdvsq; 377 outmarr += tmparr; 378 } 379 outmarr /= stdevsqsum; 380 Array<Float> tarr(outmarr.getArray()); 381 Array<Bool> tbarr(outmarr.getMask()); 382 // write averaged pol into all pols - fix up to reform array 383 for (uInt k=0; k<in->nPol();++k) { 384 IPosition start(4,i,j,k,0); 385 IPosition end(4,i,j,k,n-1); 386 Array<Float> subArr(arr(start,end)); 387 Array<Bool> subMask(barr(start,end)); 388 ArrayAccessor<Float, Axis<0> > aa0(tarr); 389 ArrayAccessor<Bool, Axis<0> > ba0(tbarr); 390 ArrayAccessor<Bool, Axis<3> > ba(subMask); 391 for (ArrayAccessor<Float, Axis<3> > aa(subArr); aa != aa.end();++aa) { 392 (*aa) = (*aa0); 393 (*ba) = (*ba0); 394 aa0++; 395 ba0++; 396 ba++; 421 const Vector<Bool>& mask) 422 { 423 const uInt nRows = in->nRow(); 424 const uInt axis = 3; // Spectrum 425 const IPosition axes(2, 2, 3); // pol-channel plane 426 427 // Create output Table 428 429 SDMemTable* sdmt = new SDMemTable(*in, True); 430 431 // Loop over rows 432 433 for (uInt iRow=0; iRow<nRows; iRow++) { 434 435 // Get data for this row 436 437 MaskedArray<Float> marr(in->rowAsMaskedArray(iRow)); 438 Array<Float>& arr = marr.getRWArray(); 439 const Array<Bool>& barr = marr.getMask(); 440 // 441 IPosition shp = marr.shape(); 442 const Bool useMask = (mask.nelements() == shp(axis)); 443 const uInt nChan = shp(axis); 444 445 // Make iterators to iterate by pol-channel planes 446 447 ArrayIterator<Float> itDataPlane(arr, axes); 448 ReadOnlyArrayIterator<Bool> itMaskPlane(barr, axes); 449 450 // Accumulations 451 452 Float fac = 0.0; 453 Vector<Float> vecSum(nChan,0.0); 454 455 // Iterate by plane 456 457 while (!itDataPlane.pastEnd()) { 458 459 // Iterate through pol-channel plane by spectrum 460 461 Vector<Float> t1(nChan); t1 = 0.0; 462 Vector<Bool> t2(nChan); t2 = True; 463 MaskedArray<Float> vecSum(t1,t2); 464 Float varSum = 0.0; 465 { 466 ReadOnlyVectorIterator<Float> itDataVec(itDataPlane.array(), 1); 467 ReadOnlyVectorIterator<Bool> itMaskVec(itMaskPlane.array(), 1); 468 while (!itDataVec.pastEnd()) { 469 470 // Create MA of data & mask (optionally including OTF mask) and get variance 471 472 if (useMask) { 473 const MaskedArray<Float> spec(itDataVec.vector(),mask&&itMaskVec.vector()); 474 fac = 1.0 / variance(spec); 475 } else { 476 const MaskedArray<Float> spec(itDataVec.vector(),itMaskVec.vector()); 477 fac = 1.0 / variance(spec); 478 } 479 480 // Normalize spectrum (without OTF mask) and accumulate 481 482 const MaskedArray<Float> spec(fac*itDataVec.vector(), itMaskVec.vector()); 483 vecSum += spec; 484 varSum += fac; 485 486 // Next 487 488 itDataVec.next(); 489 itMaskVec.next(); 490 } 397 491 } 398 } 399 } 400 } 401 402 Array<uChar> outflags(barr.shape()); 403 convertArray(outflags,!barr); 404 SDContainer sc = in->getSDContainer(); 405 sc.putSpectrum(arr); 406 sc.putFlags(outflags); 407 SDMemTable* sdmt = new SDMemTable(*in,True); 408 sdmt->putSDContainer(sc); 409 return CountedPtr<SDMemTable>(sdmt); 410 } 411 412 413 Float SDMath::rms(const CountedPtr<SDMemTable>& in, 414 const std::vector<bool>& mask) { 415 Float rmsval; 416 Vector<Bool> msk(mask); 417 IPosition ip = in->rowAsMaskedArray(0).shape(); 418 MaskedArray<Float> marr(in->rowAsMaskedArray(0)); 419 420 Array<Float> arr = marr.getArray(); 421 Array<Bool> barr = marr.getMask(); 422 uInt i,j,k; 423 i = in->getBeam(); 424 j = in->getIF(); 425 k = in->getPol(); 426 IPosition start(4,i,j,k,0); 427 IPosition end(4,i,j,k,in->nChan()-1); 428 Array<Float> subArr(arr(start,end)); 429 Array<Bool> subMask(barr(start,end)); 430 Array<Float> v(subArr.nonDegenerate()); 431 Array<Bool> m(subMask.nonDegenerate()); 432 MaskedArray<Float> tmp; 433 if (msk.nelements() == m.nelements() ) { 434 tmp.setData(v,m&&msk); 435 } else { 436 tmp.setData(v,m); 437 } 438 rmsval = stddev(tmp); 439 return rmsval; 440 } 492 493 // Normalize summed spectrum 494 495 vecSum /= varSum; 496 497 // We have formed the weighted averaged spectrum from all polarizations 498 // for this beam and IF. Now replicate the spectrum to all polarizations 499 500 { 501 VectorIterator<Float> itDataVec(itDataPlane.array(), 1); // Writes back into 'arr' 502 const Vector<Float>& vecSumData = vecSum.getArray(); // It *is* a Vector 503 // 504 while (!itDataVec.pastEnd()) { 505 itDataVec.vector() = vecSumData; 506 itDataVec.next(); 507 } 508 } 509 510 // Step to next beam/IF combination 511 512 itDataPlane.next(); 513 itMaskPlane.next(); 514 } 515 516 // Generate output container and write it to output table 517 518 SDContainer sc = in->getSDContainer(); 519 Array<uChar> outflags(barr.shape()); 520 convertArray(outflags,!barr); 521 sc.putSpectrum(arr); 522 sc.putFlags(outflags); 523 sdmt->putSDContainer(sc); 524 } 525 // 526 return CountedPtr<SDMemTable>(sdmt); 527 } 528 441 529 442 530 CountedPtr<SDMemTable> SDMath::bin(const CountedPtr<SDMemTable>& in, 443 Int width) {444 531 Int width) 532 { 445 533 SDHeader sh = in->getSDHeader(); 446 534 SDMemTable* sdmt = new SDMemTable(*in,True); 447 535 448 MaskedArray<Float> tmpmarr(in->rowAsMaskedArray(0)); 449 MaskedArray<Float> tmpmarr2; 450 SpectralCoordinate outcoord;451 IPosition ip;536 // Bin up SpectralCoordinates 537 538 IPosition factors(1); 539 factors(0) = width; 452 540 for (uInt j=0; j<in->nCoordinates(); ++j) { 453 SpectralCoordinate coord(in->getCoordinate(j)); 454 ImageUtilities::bin(tmpmarr2, outcoord, tmpmarr, coord, 3, width); 455 ip = tmpmarr2.shape(); 456 sdmt->setCoordinate(outcoord,j); 457 } 458 sh.nchan = ip(3); 541 CoordinateSystem cSys; 542 cSys.addCoordinate(in->getCoordinate(j)); 543 CoordinateSystem cSysBin = 544 CoordinateUtil::makeBinnedCoordinateSystem (factors, cSys, False); 545 // 546 SpectralCoordinate sCBin = cSysBin.spectralCoordinate(0); 547 sdmt->setCoordinate(sCBin, j); 548 } 549 550 // Use RebinLattice to find shape 551 552 IPosition shapeIn(1,sh.nchan); 553 IPosition shapeOut = RebinLattice<Float>::rebinShape (shapeIn, factors); 554 sh.nchan = shapeOut(0); 459 555 sdmt->putSDHeader(sh); 460 556 461 SpectralCoordinate tmpcoord2,tmpcoord; 557 558 // Loop over rows and bin along channel axis 559 560 const uInt axis = 3; 462 561 for (uInt i=0; i < in->nRow(); ++i) { 562 SDContainer sc = in->getSDContainer(i); 563 // 564 Array<Float> tSys(sc.getTsys()); // Get it out before sc changes shape 565 566 // Bin up spectrum 567 463 568 MaskedArray<Float> marr(in->rowAsMaskedArray(i)); 464 SDContainer sc = in->getSDContainer(i);465 Array<Float> arr = marr.getArray();466 Array<Bool> barr = marr.getMask();467 569 MaskedArray<Float> marrout; 468 ImageUtilities::bin(marrout, tmpcoord2, marr, tmpcoord, 3, width); 570 LatticeUtilities::bin(marrout, marr, axis, width); 571 572 // Put back the binned data and flags 573 469 574 IPosition ip2 = marrout.shape(); 470 575 sc.resize(ip2); 471 576 sc.putSpectrum(marrout.getArray()); 577 // 472 578 Array<uChar> outflags(ip2); 473 579 convertArray(outflags,!(marrout.getMask())); 474 580 sc.putFlags(outflags); 475 MaskedArray<Float> tsys,tsysout; 476 Array<Bool> dummy(ip);dummy = True; 477 tsys.setData(sc.getTsys(),dummy); 478 ImageUtilities::bin(tsysout, tmpcoord2, marr, tmpcoord, 3, width); 479 sc.putTsys(tsysout.getArray()); 581 582 // Bin up Tsys. 583 584 Array<Bool> allGood(tSys.shape(),True); 585 MaskedArray<Float> tSysIn(tSys, allGood, True); 586 // 587 MaskedArray<Float> tSysOut; 588 LatticeUtilities::bin(tSysOut, tSysIn, axis, width); 589 sc.putTsys(tSysOut.getArray()); 480 590 sdmt->putSDContainer(sc); 481 591 } 482 592 return CountedPtr<SDMemTable>(sdmt); 483 593 } 594 595 596 597 std::vector<float> SDMath::statistic (const CountedPtr<SDMemTable>& in, 598 const std::vector<bool>& mask, 599 const std::string& which) 600 // 601 // Perhaps iteration over pol/beam/if should be in here 602 // and inside the nrow iteration ? 603 // 604 { 605 const uInt nRow = in->nRow(); 606 std::vector<float> result(nRow); 607 Vector<Bool> msk(mask); 608 609 // Specify cursor location 610 611 uInt i = in->getBeam(); 612 uInt j = in->getIF(); 613 uInt k = in->getPol(); 614 IPosition start(4,i,j,k,0); 615 IPosition end(4,i,j,k,in->nChan()-1); 616 617 // Loop over rows 618 619 const uInt nEl = msk.nelements(); 620 for (uInt ii=0; ii < in->nRow(); ++ii) { 621 622 // Get row and deconstruct 623 624 MaskedArray<Float> marr(in->rowAsMaskedArray(ii)); 625 Array<Float> arr = marr.getArray(); 626 Array<Bool> barr = marr.getMask(); 627 628 // Access desired piece of data 629 630 Array<Float> v((arr(start,end)).nonDegenerate()); 631 Array<Bool> m((barr(start,end)).nonDegenerate()); 632 633 // Apply OTF mask 634 635 MaskedArray<Float> tmp; 636 if (m.nelements()==nEl) { 637 tmp.setData(v,m&&msk); 638 } else { 639 tmp.setData(v,m); 640 } 641 642 // Get statistic 643 644 result[ii] = SDMath::theStatistic(which, tmp); 645 } 646 // 647 return result; 648 } 649 650 651 float SDMath::theStatistic(const std::string& which, const casa::MaskedArray<Float>& data) 652 { 653 String str(which); 654 str.upcase(); 655 if (str.contains(String("MIN"))) { 656 return min(data); 657 } else if (str.contains(String("MAX"))) { 658 return max(data); 659 } else if (str.contains(String("SUMSQ"))) { 660 return sumsquares(data); 661 } else if (str.contains(String("SUM"))) { 662 return sum(data); 663 } else if (str.contains(String("MEAN"))) { 664 return mean(data); 665 } else if (str.contains(String("VAR"))) { 666 return variance(data); 667 } else if (str.contains(String("STDDEV"))) { 668 return stddev(data); 669 } else if (str.contains(String("AVDEV"))) { 670 return avdev(data); 671 } else if (str.contains(String("RMS"))) { 672 uInt n = data.nelementsValid(); 673 return sqrt(sumsquares(data)/n); 674 } else if (str.contains(String("MED"))) { 675 return median(data); 676 } 677 } -
trunk/src/SDMath.h
r125 r130 34 34 #include <string> 35 35 #include <vector> 36 #include <casa/aips.h> 36 37 #include <casa/Utilities/CountedPtr.h> 37 38 … … 59 60 averagePol(const casa::CountedPtr<SDMemTable>& in, const casa::Vector<casa::Bool>& mask); 60 61 61 casa::Float rms(const casa::CountedPtr<SDMemTable>& in,62 const std::vector<bool>& mask);62 std::vector<float> statistic(const casa::CountedPtr<SDMemTable>& in, 63 const std::vector<bool>& mask, const std::string& which); 63 64 64 65 casa::CountedPtr<SDMemTable> bin(const casa::CountedPtr<SDMemTable>& in, 65 66 casa::Int width); 67 68 // private (not actually...) 69 70 float theStatistic(const std::string& which, const casa::MaskedArray<casa::Float>& data); 71 66 72 }; 67 73
Note:
See TracChangeset
for help on using the changeset viewer.