- Timestamp:
- 03/15/13 18:23:04 (12 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/STSideBandSep.cpp
r2726 r2794 26 26 27 27 // asap 28 #include "STGrid.h" 29 #include "STMath.h" 30 #include "MathUtils.h" 28 31 #include "STSideBandSep.h" 29 32 … … 32 35 using namespace asap ; 33 36 34 #ifndef KS_DEBUG35 #define KS_DEBUG36 #endif37 // #ifndef KS_DEBUG 38 // #define KS_DEBUG 39 // #endif 37 40 38 41 namespace asap { … … 78 81 79 82 init(); 83 tp_ = intabList_[0]->table().tableType(); 80 84 81 85 os << ntable_ << " tables are set." << LogIO::POST; … … 92 96 { 93 97 // frequency setup 94 sigIfno_= 0;98 sigIfno_= -1; 95 99 ftol_ = -1; 96 100 solFrame_ = MFrequency::N_Types; … … 109 113 // Default LO frame is TOPO 110 114 loFrame_ = MFrequency::TOPO; 115 // scantable storage 116 tp_ = Table::Memory; 111 117 }; 112 118 … … 130 136 131 137 // IFNO 132 sigIfno_ = ifno;138 sigIfno_ = (int) ifno; 133 139 134 140 // Frequency tolerance … … 219 225 if (i != imgShift_.size()-1) os << " , "; 220 226 } 221 os << " ) [channel ]" << LogIO::POST;227 os << " ) [channels]" << LogIO::POST; 222 228 } 223 229 }; … … 227 233 LogIO os(LogOrigin("STSideBandSep","setThreshold()", WHERE)); 228 234 if (limit < 0) 229 throw( AipsError("Rejection limit should be positive number.") );235 throw( AipsError("Rejection limit should be a positive number.") ); 230 236 231 237 rejlimit_ = limit; 232 os << "Rejection limit is set to " << rejlimit_; 233 }; 234 235 // Temporal function to set scantable of image sideband 236 void STSideBandSep::setImageTable(const ScantableWrapper &s) 237 { 238 #ifdef KS_DEBUG 239 cout << "STSideBandSep::setImageTable" << endl; 240 cout << "got image table nrow = " << s.nrow() << endl; 241 #endif 242 imgTab_p = s.getCP(); 243 AlwaysAssert(!imgTab_p.null(),AipsError); 244 245 }; 246 247 // 248 void STSideBandSep::setLO1(const double lo1, const string frame, 238 os << "Rejection limit is set to " << rejlimit_ << LogIO::POST; 239 }; 240 241 void STSideBandSep::separate(string outname) 242 { 243 #ifdef KS_DEBUG 244 cout << "STSideBandSep::separate" << endl; 245 #endif 246 LogIO os(LogOrigin("STSideBandSep","separate()", WHERE)); 247 if (outname.empty()) 248 outname = "sbseparated.asap"; 249 250 // Set up a goup of IFNOs in the list of scantables within 251 // the frequency tolerance and make them a list. 252 nshift_ = setupShift(); 253 if (nshift_ < 2) 254 throw( AipsError("At least 2 IFs are necessary for convolution.") ); 255 // Grid scantable and generate output tables 256 ScantableWrapper gridst = gridTable(); 257 sigTab_p = gridst.getCP(); 258 if (doboth_) 259 imgTab_p = gridst.copy().getCP(); 260 vector<unsigned int> remRowIds; 261 remRowIds.resize(0); 262 Matrix<float> specMat(nchan_, nshift_); 263 vector<float> sigSpec(nchan_), imgSpec(nchan_); 264 vector<uInt> tabIdvec; 265 266 //Generate FFTServer 267 fftsf.resize(IPosition(1, nchan_), FFTEnums::REALTOCOMPLEX); 268 fftsi.resize(IPosition(1, nchan_), FFTEnums::COMPLEXTOREAL); 269 270 /// Loop over sigTab_p and separate sideband 271 for (int irow = 0; irow < sigTab_p->nrow(); irow++){ 272 tabIdvec.resize(0); 273 const int polId = sigTab_p->getPol(irow); 274 const int beamId = sigTab_p->getBeam(irow); 275 const vector<double> dir = sigTab_p->getDirectionVector(irow); 276 // Get a set of spectra to solve 277 if (!getSpectraToSolve(polId, beamId, dir[0], dir[1], 278 specMat, tabIdvec)){ 279 remRowIds.push_back(irow); 280 #ifdef KS_DEBUG 281 cout << "no matching row found. skipping row = " << irow << endl; 282 #endif 283 continue; 284 } 285 // Solve signal sideband 286 sigSpec = solve(specMat, tabIdvec, true); 287 sigTab_p->setSpectrum(sigSpec, irow); 288 289 // Solve image sideband 290 if (doboth_) { 291 imgSpec = solve(specMat, tabIdvec, false); 292 imgTab_p->setSpectrum(imgSpec, irow); 293 } 294 } // end of row loop 295 296 // Remove or flag rows without relevant data from gridded tables 297 if (remRowIds.size() > 0) { 298 const size_t nrem = remRowIds.size(); 299 if ( sigTab_p->table().canRemoveRow() ) { 300 sigTab_p->table().removeRow(remRowIds); 301 os << "Removing " << nrem << " rows from the signal band table" 302 << LogIO::POST; 303 } else { 304 sigTab_p->flagRow(remRowIds, false); 305 os << "Cannot remove rows from the signal band table. Flagging " 306 << nrem << " rows" << LogIO::POST; 307 } 308 309 if (doboth_) { 310 if ( imgTab_p->table().canRemoveRow() ) { 311 imgTab_p->table().removeRow(remRowIds); 312 os << "Removing " << nrem << " rows from the image band table" 313 << LogIO::POST; 314 } else { 315 imgTab_p->flagRow(remRowIds, false); 316 os << "Cannot remove rows from the image band table. Flagging " 317 << nrem << " rows" << LogIO::POST; 318 } 319 } 320 } 321 322 // Finally, save tables on disk 323 if (outname.size() ==0) 324 outname = "sbseparated.asap"; 325 const string sigName = outname + ".signalband"; 326 os << "Saving SIGNAL sideband table: " << sigName << LogIO::POST; 327 sigTab_p->makePersistent(sigName); 328 if (doboth_) { 329 solveImageFrequency(); 330 const string imgName = outname + ".imageband"; 331 os << "Saving IMAGE sideband table: " << sigName << LogIO::POST; 332 imgTab_p->makePersistent(imgName); 333 } 334 335 }; 336 337 unsigned int STSideBandSep::setupShift() 338 { 339 LogIO os(LogOrigin("STSideBandSep","setupShift()", WHERE)); 340 if (infileList_.size() == 0 && intabList_.size() == 0) 341 throw( AipsError("No scantable has been set. Set a list of scantables first.") ); 342 343 const bool byname = (intabList_.size() == 0); 344 // Make sure sigIfno_ exists in the first table. 345 CountedPtr<Scantable> stab; 346 vector<string> coordsav; 347 vector<string> coordtmp(3); 348 os << "Checking IFNO in the first table." << LogIO::POST; 349 if (byname) { 350 if (!checkFile(infileList_[0], "d")) 351 os << LogIO::SEVERE << "Could not find scantable '" << infileList_[0] 352 << "'" << LogIO::EXCEPTION; 353 stab = CountedPtr<Scantable>(new Scantable(infileList_[0])); 354 } else { 355 stab = intabList_[0]; 356 } 357 if (sigIfno_ < 0) { 358 sigIfno_ = (int) stab->getIF(0); 359 os << "IFNO to process has not been set. Using the first IF = " 360 << sigIfno_ << LogIO::POST; 361 } 362 363 unsigned int basench; 364 double basech0, baseinc, ftolval, inctolval; 365 coordsav = stab->getCoordInfo(); 366 const string stfframe = coordsav[1]; 367 coordtmp[0] = "Hz"; 368 coordtmp[1] = ( (solFrame_ == MFrequency::N_Types) ? 369 stfframe : 370 MFrequency::showType(solFrame_) ); 371 coordtmp[2] = coordsav[2]; 372 stab->setCoordInfo(coordtmp); 373 if (!getFreqInfo(stab, (unsigned int) sigIfno_, basech0, baseinc, basench)) { 374 os << LogIO::SEVERE << "No data with IFNO=" << sigIfno_ 375 << " found in the first table." << LogIO::EXCEPTION; 376 } 377 else { 378 os << "Found IFNO = " << sigIfno_ 379 << " in the first table." << LogIO::POST; 380 } 381 if (ftol_.getUnit().empty()) { 382 // tolerance in unit of channels 383 ftolval = ftol_.getValue() * baseinc; 384 } 385 else { 386 ftolval = ftol_.getValue("Hz"); 387 } 388 inctolval = abs(baseinc/(double) basench); 389 const string poltype0 = stab->getPolType(); 390 391 // Initialize shift values 392 initshift(); 393 394 const bool setImg = ( doboth_ && (imgShift_.size() == 0) ); 395 // Select IFs 396 for (unsigned int itab = 0; itab < ntable_; itab++ ){ 397 os << "Table " << itab << LogIO::POST; 398 if (itab > 0) { 399 if (byname) { 400 if (!checkFile(infileList_[itab], "d")) 401 os << LogIO::SEVERE << "Could not find scantable '" 402 << infileList_[itab] << "'" << LogIO::EXCEPTION; 403 stab = CountedPtr<Scantable>(new Scantable(infileList_[itab])); 404 } else { 405 stab = intabList_[itab]; 406 } 407 //POLTYPE should be the same. 408 if (stab->getPolType() != poltype0 ) { 409 os << LogIO::WARN << "POLTYPE differs from the first table." 410 << " Skipping the table" << LogIO::POST; 411 continue; 412 } 413 // Multi beam data may not handled properly 414 if (stab->nbeam() > 1) 415 os << LogIO::WARN << "Table contains multiple beams. " 416 << "It may not be handled properly." << LogIO::POST; 417 418 coordsav = stab->getCoordInfo(); 419 coordtmp[2] = coordsav[2]; 420 stab->setCoordInfo(coordtmp); 421 } 422 bool selected = false; 423 vector<uint> ifnos = stab->getIFNos(); 424 vector<uint>::iterator iter; 425 const STSelector& basesel = stab->getSelection(); 426 for (iter = ifnos.begin(); iter != ifnos.end(); iter++){ 427 unsigned int nch; 428 double freq0, incr; 429 if ( getFreqInfo(stab, *iter, freq0, incr, nch) ){ 430 if ( (nch == basench) && (abs(freq0-basech0) < ftolval) 431 && (abs(incr-baseinc) < inctolval) ){ 432 //Found 433 STSelector sel(basesel); 434 sel.setIFs(vector<int>(1,(int) *iter)); 435 stab->setSelection(sel); 436 CountedPtr<Scantable> seltab = ( new Scantable(*stab, false) ); 437 stab->setSelection(basesel); 438 seltab->setCoordInfo(coordsav); 439 const double chShift = (freq0 - basech0) / baseinc; 440 tableList_.push_back(seltab); 441 sigShift_.push_back(chShift); 442 if (setImg) 443 imgShift_.push_back(-chShift); 444 445 selected = true; 446 os << "- IF" << *iter << " selected: sideband shift = " 447 << chShift << " channels" << LogIO::POST; 448 } 449 } 450 } // ifno loop 451 stab->setCoordInfo(coordsav); 452 if (!selected) 453 os << LogIO::WARN << "No data selected in Table " 454 << itab << LogIO::POST; 455 } // table loop 456 nchan_ = basench; 457 458 os << "Total number of IFs selected = " << tableList_.size() 459 << LogIO::POST; 460 if ( setImg && (sigShift_.size() != imgShift_.size()) ){ 461 os << LogIO::SEVERE 462 << "User defined channel shift of image sideband has " 463 << imgShift_.size() 464 << " elements, while selected IFNOs are " << sigShift_.size() 465 << "\nThe frequency tolerance (freqtol) may be too small." 466 << LogIO::EXCEPTION; 467 } 468 469 return tableList_.size(); 470 }; 471 472 bool STSideBandSep::getFreqInfo(const CountedPtr<Scantable> &stab, 473 const unsigned int &ifno, 474 double &freq0, double &incr, 475 unsigned int &nchan) 476 { 477 vector<uint> ifnos = stab->getIFNos(); 478 bool found = false; 479 vector<uint>::iterator iter; 480 for (iter = ifnos.begin(); iter != ifnos.end(); iter++){ 481 if (*iter == ifno) { 482 found = true; 483 break; 484 } 485 } 486 if (!found) 487 return false; 488 489 const STSelector& basesel = stab->getSelection(); 490 STSelector sel(basesel); 491 sel.setIFs(vector<int>(1,(int) ifno)); 492 stab->setSelection(sel); 493 vector<double> freqs; 494 freqs = stab->getAbcissa(0); 495 freq0 = freqs[0]; 496 incr = freqs[1] - freqs[0]; 497 nchan = freqs.size(); 498 stab->setSelection(basesel); 499 return true; 500 }; 501 502 ScantableWrapper STSideBandSep::gridTable() 503 { 504 LogIO os(LogOrigin("STSideBandSep","gridTable()", WHERE)); 505 if (tableList_.size() == 0) 506 throw( AipsError("Internal error. No scantable has been set to grid.") ); 507 Double xmin, xmax, ymin, ymax; 508 mapExtent(tableList_, xmin, xmax, ymin, ymax); 509 const Double centx = 0.5 * (xmin + xmax); 510 const Double centy = 0.5 * (ymin + ymax); 511 const int nx = max(1, (int) ceil( (xmax - xmin) * cos(centy) /xtol_ ) ); 512 const int ny = max(1, (int) ceil( (ymax - ymin) / ytol_ ) ); 513 514 string scellx, scelly; 515 { 516 ostringstream oss; 517 oss << xtol_ << "rad" ; 518 scellx = oss.str(); 519 } 520 { 521 ostringstream oss; 522 oss << ytol_ << "rad" ; 523 scelly = oss.str(); 524 } 525 526 ScantableWrapper stab0; 527 if (intabList_.size() > 0) 528 stab0 = ScantableWrapper(intabList_[0]); 529 else 530 stab0 = ScantableWrapper(infileList_[0]); 531 532 string scenter; 533 { 534 ostringstream oss; 535 oss << stab0.getCP()->getDirectionRefString() << " " 536 << centx << "rad" << " " << centy << "rad"; 537 scenter = oss.str(); 538 } 539 540 STGrid2 gridder = STGrid2(stab0); 541 gridder.setIF(sigIfno_); 542 gridder.defineImage(nx, ny, scellx, scelly, scenter); 543 gridder.setFunc("box", 1); 544 gridder.setWeight("uniform"); 545 #ifdef KS_DEBUG 546 cout << "Grid parameter summary: " << endl; 547 cout << "- IF = " << sigIfno_ << endl; 548 cout << "- center = " << scenter << ")\n" 549 << "- npix = (" << nx << ", " << ny << ")\n" 550 << "- cell = (" << scellx << ", " << scelly << endl; 551 #endif 552 gridder.grid(); 553 const int itp = (tp_ == Table::Memory ? 0 : 1); 554 ScantableWrapper gtab = gridder.getResultAsScantable(itp); 555 return gtab; 556 }; 557 558 void STSideBandSep::mapExtent(vector< CountedPtr<Scantable> > &tablist, 559 Double &xmin, Double &xmax, 560 Double &ymin, Double &ymax) 561 { 562 ROArrayColumn<Double> dirCol_; 563 dirCol_.attach( tablist[0]->table(), "DIRECTION" ); 564 Matrix<Double> direction = dirCol_.getColumn(); 565 Vector<Double> ra( direction.row(0) ); 566 mathutil::rotateRA(ra); 567 minMax( xmin, xmax, ra ); 568 minMax( ymin, ymax, direction.row(1) ); 569 Double amin, amax, bmin, bmax; 570 const uInt ntab = tablist.size(); 571 for ( uInt i = 1 ; i < ntab ; i++ ) { 572 dirCol_.attach( tablist[i]->table(), "DIRECTION" ); 573 direction.assign( dirCol_.getColumn() ); 574 ra.assign( direction.row(0) ); 575 mathutil::rotateRA(ra); 576 minMax( amin, amax, ra ); 577 minMax( bmin, bmax, direction.row(1) ); 578 xmin = min(xmin, amin); 579 xmax = max(xmax, amax); 580 ymin = min(ymin, bmin); 581 ymax = max(ymax, bmax); 582 } 583 }; 584 585 bool STSideBandSep::getSpectraToSolve(const int polId, const int beamId, 586 const double dirX, const double dirY, 587 Matrix<float> &specMat, vector<uInt> &tabIdvec) 588 { 589 LogIO os(LogOrigin("STSideBandSep","getSpectraToSolve()", WHERE)); 590 591 tabIdvec.resize(0); 592 specMat.resize(nchan_, nshift_); 593 Vector<float> spec; 594 uInt nspec = 0; 595 STMath stm(false); // insitu has no effect for average. 596 for (uInt itab = 0 ; itab < nshift_ ; itab++) { 597 CountedPtr<Scantable> currtab_p = tableList_[itab]; 598 // Selection by POLNO and BEAMNO 599 const STSelector& basesel = currtab_p->getSelection(); 600 STSelector sel(basesel); 601 sel.setPolarizations(vector<int>(1, polId)); 602 sel.setBeams(vector<int>(1, beamId)); 603 try { 604 currtab_p->setSelection(sel); 605 } catch (...) { 606 #ifdef KS_DEBUG 607 cout << "Table " << itab << " - No spectrum found. skipping the table." 608 << endl; 609 #endif 610 continue; 611 } 612 // Selection by direction; 613 vector<int> selrow(0); 614 vector<double> currDir(2, 0.); 615 const int nselrow = currtab_p->nrow(); 616 for (int irow = 0 ; irow < nselrow ; irow++) { 617 currDir = currtab_p->getDirectionVector(irow); 618 if ( (abs(currDir[0]-dirX) > xtol_) || 619 (abs(currDir[1]-dirY) > ytol_) ) 620 continue; 621 // within direction tolerance 622 selrow.push_back(irow); 623 } // end of row loop 624 625 if (selrow.size() < 1) { 626 currtab_p->setSelection(basesel); 627 628 #ifdef KS_DEBUG 629 cout << "Table " << itab << " - No spectrum found. skipping the table." 630 << endl; 631 #endif 632 633 continue; 634 } 635 636 // At least a spectrum is selected in this table 637 CountedPtr<Scantable> seltab_p = ( new Scantable(*currtab_p, false) ); 638 currtab_p->setSelection(basesel); 639 STSelector sel2(seltab_p->getSelection()); 640 sel2.setRows(selrow); 641 seltab_p->setSelection(sel2); 642 CountedPtr<Scantable> avetab_p; 643 vector<bool> mask; 644 if (seltab_p->nrow() > 1) { 645 avetab_p = stm.average(vector< CountedPtr<Scantable> >(1, seltab_p), 646 vector<bool>(), "TINTSYS", "NONE"); 647 #ifdef KS_DEBUG 648 cout << "Table " << itab << " - more than a spectrum is selected. averaging rows..." 649 << endl; 650 #endif 651 if (avetab_p->nrow() > 1) 652 throw( AipsError("Averaged table has more than a row. Somethigs went wrong.") ); 653 } else { 654 avetab_p = seltab_p; 655 } 656 spec.reference(specMat.column(nspec)); 657 spec = avetab_p->getSpectrum(0); 658 tabIdvec.push_back((uInt) itab); 659 nspec++; 660 } // end of table loop 661 if (nspec != nshift_){ 662 //shiftSpecmat.resize(nchan_, nspec, true); 663 #ifdef KS_DEBUG 664 cout << "Could not find corresponding rows in some tables." 665 << endl; 666 cout << "Number of spectra selected = " << nspec << endl; 667 #endif 668 } 669 if (nspec < 2) { 670 #ifdef KS_DEBUG 671 cout << "At least 2 spectra are necessary for convolution" 672 << endl; 673 #endif 674 return false; 675 } 676 return true; 677 }; 678 679 vector<float> STSideBandSep::solve(const Matrix<float> &specmat, 680 const vector<uInt> &tabIdvec, 681 const bool signal) 682 { 683 LogIO os(LogOrigin("STSideBandSep","solve()", WHERE)); 684 if (tabIdvec.size() == 0) 685 throw(AipsError("Internal error. Table index is not defined.")); 686 if (specmat.ncolumn() != tabIdvec.size()) 687 throw(AipsError("Internal error. The row number of input matrix is not conformant.")); 688 if (specmat.nrow() != nchan_) 689 throw(AipsError("Internal error. The channel size of input matrix is not conformant.")); 690 691 692 #ifdef KS_DEBUG 693 cout << "Solving " << (signal ? "SIGNAL" : "IMAGE") << " sideband." 694 << endl; 695 #endif 696 697 const size_t nspec = tabIdvec.size(); 698 vector<double> *thisShift, *otherShift; 699 if (signal == otherside_) { 700 // (solve signal && solveother = T) OR (solve image && solveother = F) 701 thisShift = &imgShift_; 702 otherShift = &sigShift_; 703 #ifdef KS_DEBUG 704 cout << "Image sideband will be deconvolved." << endl; 705 #endif 706 } else { 707 // (solve signal && solveother = F) OR (solve image && solveother = T) 708 thisShift = &sigShift_; 709 otherShift = &imgShift_; 710 #ifdef KS_DEBUG 711 cout << "Signal sideband will be deconvolved." << endl; 712 #endif 713 } 714 715 vector<double> spshift(nspec); 716 Matrix<float> shiftSpecmat(nchan_, nspec, 0.); 717 double tempshift; 718 Vector<float> shiftspvec; 719 for (uInt i = 0 ; i < nspec; i++) { 720 spshift[i] = otherShift->at(i) - thisShift->at(i); 721 tempshift = - thisShift->at(i); 722 shiftspvec.reference(shiftSpecmat.column(i)); 723 shiftSpectrum(specmat.column(i), tempshift, shiftspvec); 724 } 725 726 Matrix<float> convmat(nchan_, nspec*(nspec-1)/2, 0.); 727 vector<float> thisvec(nchan_, 0.); 728 729 float minval, maxval; 730 minMax(minval, maxval, shiftSpecmat); 731 #ifdef KS_DEBUG 732 cout << "Max/Min of input Matrix = (max: " << maxval << ", min: " << minval << ")" << endl; 733 #endif 734 735 #ifdef KS_DEBUG 736 cout << "starting deconvolution" << endl; 737 #endif 738 deconvolve(shiftSpecmat, spshift, rejlimit_, convmat); 739 #ifdef KS_DEBUG 740 cout << "finished deconvolution" << endl; 741 #endif 742 743 minMax(minval, maxval, convmat); 744 #ifdef KS_DEBUG 745 cout << "Max/Min of output Matrix = (max: " << maxval << ", min: " << minval << ")" << endl; 746 #endif 747 748 aggregateMat(convmat, thisvec); 749 750 if (!otherside_) return thisvec; 751 752 // subtract from the other side band. 753 vector<float> othervec(nchan_, 0.); 754 subtractFromOther(shiftSpecmat, thisvec, spshift, othervec); 755 return othervec; 756 }; 757 758 759 void STSideBandSep::shiftSpectrum(const Vector<float> &invec, 760 double shift, 761 Vector<float> &outvec) 762 { 763 LogIO os(LogOrigin("STSideBandSep","shiftSpectrum()", WHERE)); 764 if (invec.size() != nchan_) 765 throw(AipsError("Internal error. The length of input vector differs from nchan_")); 766 if (outvec.size() != nchan_) 767 throw(AipsError("Internal error. The length of output vector differs from nchan_")); 768 769 #ifdef KS_DEBUG 770 cout << "Start shifting spectrum for " << shift << "channels" << endl; 771 #endif 772 773 // tweak shift to be in 0 ~ nchan_-1 774 if ( fabs(shift) > nchan_ ) shift = fmod(shift, nchan_); 775 if (shift < 0.) shift += nchan_; 776 double rweight = fmod(shift, 1.); 777 if (rweight < 0.) rweight += 1.; 778 double lweight = 1. - rweight; 779 uInt lchan, rchan; 780 781 outvec = 0; 782 for (uInt i = 0 ; i < nchan_ ; i++) { 783 lchan = uInt( floor( fmod( (i + shift), nchan_ ) ) ); 784 if (lchan < 0.) lchan += nchan_; 785 rchan = ( (lchan + 1) % nchan_ ); 786 outvec(lchan) += invec(i) * lweight; 787 outvec(rchan) += invec(i) * rweight; 788 } 789 }; 790 791 void STSideBandSep::deconvolve(Matrix<float> &specmat, 792 const vector<double> shiftvec, 793 const double threshold, 794 Matrix<float> &outmat) 795 { 796 LogIO os(LogOrigin("STSideBandSep","deconvolve()", WHERE)); 797 if (specmat.nrow() != nchan_) 798 throw(AipsError("Internal error. The length of input matrix differs from nchan_")); 799 if (specmat.ncolumn() != shiftvec.size()) 800 throw(AipsError("Internal error. The number of input shifts and spectrum differs.")); 801 802 float minval, maxval; 803 #ifdef KS_DEBUG 804 minMax(minval, maxval, specmat); 805 cout << "Max/Min of input Matrix = (max: " << maxval << ", min: " << minval << ")" << endl; 806 #endif 807 808 uInt ninsp = shiftvec.size(); 809 outmat.resize(nchan_, ninsp*(ninsp-1)/2, 0.); 810 Matrix<Complex> fftspmat(nchan_/2+1, ninsp, 0.); 811 Vector<float> rvecref(nchan_, 0.); 812 Vector<Complex> cvecref(nchan_/2+1, 0.); 813 uInt icol = 0; 814 unsigned int nreject = 0; 815 816 #ifdef KS_DEBUG 817 cout << "Starting initial FFT. The number of input spectra = " << ninsp << endl; 818 cout << "out matrix has ncolumn = " << outmat.ncolumn() << endl; 819 #endif 820 821 for (uInt isp = 0 ; isp < ninsp ; isp++) { 822 rvecref.reference( specmat.column(isp) ); 823 cvecref.reference( fftspmat.column(isp) ); 824 825 #ifdef KS_DEBUG 826 minMax(minval, maxval, rvecref); 827 cout << "Max/Min of inv FFTed Matrix = (max: " << maxval << ", min: " << minval << ")" << endl; 828 #endif 829 830 fftsf.fft0(cvecref, rvecref, true); 831 832 #ifdef KS_DEBUG 833 double maxr=cvecref[0].real(), minr=cvecref[0].real(), 834 maxi=cvecref[0].imag(), mini=cvecref[0].imag(); 835 for (uInt i = 1; i<cvecref.size();i++){ 836 maxr = max(maxr, cvecref[i].real()); 837 maxi = max(maxi, cvecref[i].imag()); 838 minr = min(minr, cvecref[i].real()); 839 mini = min(mini, cvecref[i].imag()); 840 } 841 cout << "Max/Min of inv FFTed Matrix (size=" << cvecref.size() << ") = (max: " << maxr << " + " << maxi << "j , min: " << minr << " + " << mini << "j)" << endl; 842 #endif 843 } 844 845 //Liberate from reference 846 rvecref.unique(); 847 848 Vector<Complex> cspec(nchan_/2+1, 0.); 849 const double PI = 6.0 * asin(0.5); 850 const double nchani = 1. / (float) nchan_; 851 const Complex trans(0., 1.); 852 #ifdef KS_DEBUG 853 cout << "starting actual deconvolution" << endl; 854 #endif 855 for (uInt j = 0 ; j < ninsp ; j++) { 856 for (uInt k = j+1 ; k < ninsp ; k++) { 857 const double dx = (shiftvec[k] - shiftvec[j]) * 2. * PI * nchani; 858 859 #ifdef KS_DEBUG 860 cout << "icol = " << icol << endl; 861 #endif 862 863 for (uInt ichan = 0 ; ichan < cspec.size() ; ichan++){ 864 cspec[ichan] = ( fftspmat(ichan, j) + fftspmat(ichan, k) )*0.5; 865 double phase = dx*ichan; 866 if ( fabs( sin(phase) ) > threshold){ 867 cspec[ichan] += ( fftspmat(ichan, j) - fftspmat(ichan, k) ) * 0.5 868 * trans * sin(phase) / ( 1. - cos(phase) ); 869 } else { 870 nreject++; 871 } 872 } // end of channel loop 873 874 #ifdef KS_DEBUG 875 cout << "done calculation of cspec" << endl; 876 #endif 877 878 Vector<Float> rspec; 879 rspec.reference( outmat.column(icol) ); 880 881 #ifdef KS_DEBUG 882 cout << "Starting inverse FFT. icol = " << icol << endl; 883 //cout << "- size of complex vector = " << cspec.size() << endl; 884 double maxr=cspec[0].real(), minr=cspec[0].real(), 885 maxi=cspec[0].imag(), mini=cspec[0].imag(); 886 for (uInt i = 1; i<cspec.size();i++){ 887 maxr = max(maxr, cspec[i].real()); 888 maxi = max(maxi, cspec[i].imag()); 889 minr = min(minr, cspec[i].real()); 890 mini = min(mini, cspec[i].imag()); 891 } 892 cout << "Max/Min of conv vector (size=" << cspec.size() << ") = (max: " << maxr << " + " << maxi << "j , min: " << minr << " + " << mini << "j)" << endl; 893 #endif 894 895 fftsi.fft0(rspec, cspec, false); 896 897 #ifdef KS_DEBUG 898 //cout << "- size of inversed real vector = " << rspec.size() << endl; 899 minMax(minval, maxval, rspec); 900 cout << "Max/Min of inv FFTed Vector (size=" << rspec.size() << ") = (max: " << maxval << ", min: " << minval << ")" << endl; 901 //cout << "Done inverse FFT. icol = " << icol << endl; 902 #endif 903 904 icol++; 905 } 906 } 907 908 #ifdef KS_DEBUG 909 minMax(minval, maxval, outmat); 910 cout << "Max/Min of inv FFTed Matrix = (max: " << maxval << ", min: " << minval << ")" << endl; 911 #endif 912 913 os << "Threshold = " << threshold << ", Rejected channels = " << nreject << endl; 914 }; 915 916 //////////////////////////////////////////////////////////////////// 917 // void STSideBandSep::cpprfft(std::vector<float> invec) 918 // { 919 // cout << "c++ method cpprfft" << endl; 920 // const unsigned int len = invec.size(); 921 // Vector<Complex> carr(len/2+1, 0.); 922 // Vector<float> inarr = Vector<float>(invec); 923 // Vector <float> outarr(len, 0.); 924 // FFTServer<Float, Complex> fftsf, fftsi; 925 // fftsf.resize(IPosition(1, len), FFTEnums::REALTOCOMPLEX); 926 // fftsi.resize(IPosition(1, invec.size()), FFTEnums::COMPLEXTOREAL); 927 // cout << "Input float array (length = " << len << "):" << endl; 928 // for (uInt i = 0 ; i < len ; i++){ 929 // cout << (i == 0 ? "( " : " ") << inarr[i] << (i == len-1 ? ")" : ","); 930 // } 931 // cout << endl; 932 // cout << "R->C transform" << endl; 933 // fftsf.fft0(carr, inarr, true); 934 // cout << "FFTed complex array (length = " << carr.size() << "):" << endl; 935 // for (uInt i = 0 ; i < carr.size() ; i++){ 936 // cout << (i == 0 ? "( " : " ") << carr[i] << ( (i == carr.size()-1) ? ")" : "," ); 937 // } 938 // cout << endl; 939 // cout << "C->R transform" << endl; 940 // fftsi.fft0(outarr, carr, false); 941 // cout << "invFFTed float array (length = " << outarr.size() << "):" << endl; 942 // for (uInt i = 0 ; i < outarr.size() ; i++){ 943 // cout << (i == 0 ? "( " : " ") << outarr[i] << ( (i == outarr.size()-1) ? ")" : "," ); 944 // } 945 // cout << endl; 946 // }; 947 //////////////////////////////////////////////////////////////////// 948 949 950 void STSideBandSep::aggregateMat(Matrix<float> &inmat, 951 vector<float> &outvec) 952 { 953 LogIO os(LogOrigin("STSideBandSep","aggregateMat()", WHERE)); 954 if (inmat.nrow() != nchan_) 955 throw(AipsError("Internal error. The row numbers of input matrix differs from nchan_")); 956 // if (outvec.size() != nchan_) 957 // throw(AipsError("Internal error. The size of output vector should be equal to nchan_")); 958 959 os << "Averaging " << inmat.ncolumn() << " spectra in the input matrix." 960 << LogIO::POST; 961 962 const uInt nspec = inmat.ncolumn(); 963 const double scale = 1./( (double) nspec ); 964 // initialize values with 0 965 outvec.assign(nchan_, 0); 966 for (uInt isp = 0 ; isp < nspec ; isp++) { 967 for (uInt ich = 0 ; ich < nchan_ ; ich++) { 968 outvec[ich] += inmat(ich, isp); 969 } 970 } 971 972 vector<float>::iterator iter; 973 for (iter = outvec.begin(); iter != outvec.end(); iter++){ 974 *iter *= scale; 975 } 976 }; 977 978 void STSideBandSep::subtractFromOther(const Matrix<float> &shiftmat, 979 const vector<float> &invec, 980 const vector<double> &shift, 981 vector<float> &outvec) 982 { 983 LogIO os(LogOrigin("STSideBandSep","subtractFromOther()", WHERE)); 984 if (shiftmat.nrow() != nchan_) 985 throw(AipsError("Internal error. The row numbers of input matrix differs from nchan_")); 986 if (invec.size() != nchan_) 987 throw(AipsError("Internal error. The length of input vector should be nchan_")); 988 if (shift.size() != shiftmat.ncolumn()) 989 throw(AipsError("Internal error. The column numbers of input matrix != the number of elements in shift")); 990 991 const uInt nspec = shiftmat.ncolumn(); 992 Vector<float> subsp(nchan_, 0.), shiftsub; 993 Matrix<float> submat(nchan_, nspec, 0.); 994 vector<float>::iterator iter; 995 for (uInt isp = 0 ; isp < nspec ; isp++) { 996 for (uInt ich = 0; ich < nchan_ ; ich++) { 997 subsp(ich) = shiftmat(ich, isp) - invec[ich]; 998 } 999 shiftsub.reference(submat.column(isp)); 1000 shiftSpectrum(subsp, shift[isp], shiftsub); 1001 } 1002 1003 aggregateMat(submat, outvec); 1004 }; 1005 1006 1007 void STSideBandSep::setLO1(const string lo1, const string frame, 249 1008 const double reftime, const string refdir) 250 1009 { 251 lo1Freq_ = lo1; 1010 Quantum<Double> qfreq; 1011 readQuantity(qfreq, String(lo1)); 1012 lo1Freq_ = qfreq.getValue("Hz"); 252 1013 MFrequency::getType(loFrame_, frame); 253 1014 loTime_ = reftime; … … 297 1058 }; 298 1059 299 ///// TEMPORAL FUNCTION!!! ///// 300 void STSideBandSep::setScanTb0(const ScantableWrapper &s){ 301 st0_ = s.getCP(); 302 }; 303 //////////////////////////////// 304 305 void STSideBandSep::solveImageFreqency() 306 { 307 #ifdef KS_DEBUG 308 cout << "STSideBandSep::solveImageFrequency" << endl; 309 #endif 1060 1061 void STSideBandSep::solveImageFrequency() 1062 { 310 1063 LogIO os(LogOrigin("STSideBandSep","solveImageFreqency()", WHERE)); 311 1064 os << "Start calculating frequencies of image side band" << LogIO::POST; … … 383 1136 sigrefval = toloframe(Quantum<Double>(refval, "Hz")).get("Hz").getValue(); 384 1137 385 386 1138 // Check for the availability of LO1 387 1139 if (lo1Freq_ > 0.) { … … 402 1154 // Try getting ASDM name from scantable header 403 1155 os << "Try getting information from scantable header" << LogIO::POST; 404 if (!getLo1FromScanTab( st0_, sigrefval, refpix, increment, nChan)) {1156 if (!getLo1FromScanTab(tableList_[0], sigrefval, refpix, increment, nChan)) { 405 1157 //throw AipsError("Failed to get LO1 frequency from asis table"); 406 1158 os << LogIO::WARN << "Failed to get LO1 frequency using information in scantable." << LogIO::POST; … … 410 1162 } 411 1163 } 1164 412 1165 // LO1 should now be ready. 413 1166 if (lo1Freq_ < 0.) 414 1167 throw(AipsError("Got negative LO1 Frequency")); 415 1168 416 // Print summary (LO1) 417 Vector<Double> dirvec = md.getAngle(Unit(String("rad"))).getValue(); 418 os << "[LO1 settings]" << LogIO::POST; 419 os << "- Frequency: " << lo1Freq_ << " [Hz] (" 420 << MFrequency::showType(loFrame_) << ")" << LogIO::POST; 421 os << "- Reference time: " << me.get(Unit(String("d"))).getValue() 422 << " [day]" << LogIO::POST; 423 os << "- Reference direction: [" << dirvec[0] << ", " << dirvec[1] 424 << "] (" << md.getRefString() << ") " << LogIO::POST; 425 426 //Print summary (signal) 427 os << "[Signal side band]" << LogIO::POST; 428 os << "- IFNO: " << imgTab_p->getIF(0) << " (FREQ_ID = " << freqid << ")" 429 << LogIO::POST; 430 os << "- Reference value: " << refval << " [Hz] (" 431 << MFrequency::showType(tabframe) << ") = " 432 << sigrefval << " [Hz] (" << MFrequency::showType(loFrame_) 433 << ")" << LogIO::POST; 434 os << "- Reference pixel: " << refpix << LogIO::POST; 435 os << "- Increment: " << increment << " [Hz]" << LogIO::POST; 1169 // Print summary 1170 { 1171 // LO1 1172 Vector<Double> dirvec = md.getAngle(Unit(String("rad"))).getValue(); 1173 os << "[LO1 settings]" << LogIO::POST; 1174 os << "- Frequency: " << lo1Freq_ << " [Hz] (" 1175 << MFrequency::showType(loFrame_) << ")" << LogIO::POST; 1176 os << "- Reference time: " << me.get(Unit(String("d"))).getValue() 1177 << " [day]" << LogIO::POST; 1178 os << "- Reference direction: [" << dirvec[0] << ", " << dirvec[1] 1179 << "] (" << md.getRefString() << ") " << LogIO::POST; 1180 1181 // signal sideband 1182 os << "[Signal side band]" << LogIO::POST; 1183 os << "- IFNO: " << imgTab_p->getIF(0) << " (FREQ_ID = " << freqid << ")" 1184 << LogIO::POST; 1185 os << "- Reference value: " << refval << " [Hz] (" 1186 << MFrequency::showType(tabframe) << ") = " 1187 << sigrefval << " [Hz] (" << MFrequency::showType(loFrame_) 1188 << ")" << LogIO::POST; 1189 os << "- Reference pixel: " << refpix << LogIO::POST; 1190 os << "- Increment: " << increment << " [Hz]" << LogIO::POST; 1191 } 436 1192 437 1193 // Calculate image band incr and refval in loFrame_ … … 447 1203 freqIdVec = fIDnew; 448 1204 449 // Print summary (Image side band) 450 os << "[Image side band]" << LogIO::POST; 451 os << "- IFNO: " << imgTab_p->getIF(0) << " (FREQ_ID = " << freqIdVec(0) 452 << ")" << LogIO::POST; 453 os << "- Reference value: " << imgrefval << " [Hz] (" 454 << MFrequency::showType(tabframe) << ") = " 455 << imgrefval_tab << " [Hz] (" << MFrequency::showType(loFrame_) 456 << ")" << LogIO::POST; 457 os << "- Reference pixel: " << refpix << LogIO::POST; 458 os << "- Increment: " << imgincr << " [Hz]" << LogIO::POST; 1205 // Print summary (Image sideband) 1206 { 1207 os << "[Image side band]" << LogIO::POST; 1208 os << "- IFNO: " << imgTab_p->getIF(0) << " (FREQ_ID = " << freqIdVec(0) 1209 << ")" << LogIO::POST; 1210 os << "- Reference value: " << imgrefval << " [Hz] (" 1211 << MFrequency::showType(tabframe) << ") = " 1212 << imgrefval_tab << " [Hz] (" << MFrequency::showType(loFrame_) 1213 << ")" << LogIO::POST; 1214 os << "- Reference pixel: " << refpix << LogIO::POST; 1215 os << "- Increment: " << imgincr << " [Hz]" << LogIO::POST; 1216 } 459 1217 }; 460 1218 … … 619 1377 }; 620 1378 621 // String STSideBandSep::()622 // {623 624 // };625 626 1379 } //namespace asap -
trunk/src/STSideBandSep.h
r2726 r2794 22 22 #include <coordinates/Coordinates/DirectionCoordinate.h> 23 23 #include <coordinates/Coordinates/SpectralCoordinate.h> 24 #include <scimath/Mathematics/FFTServer.h> 24 25 // asap 25 26 #include "ScantableWrapper.h" … … 40 41 explicit STSideBandSep(const vector<ScantableWrapper> &tables); 41 42 virtual ~STSideBandSep(); 43 44 ///////////// temp functions ////////////////////// 45 //void cpprfft(std::vector<float> invec); 46 ////////////////////////////////////////////////// 47 48 /** 49 * Separate side bands 50 **/ 51 void separate(string outname); 42 52 43 53 /** … … 83 93 * Set additional information to fill frequencies of image sideband 84 94 **/ 85 void setLO1(const doublelo1, const string frame="TOPO",95 void setLO1(const string lo1, const string frame="TOPO", 86 96 const double reftime=-1, string refdir=""); 87 97 void setLO1Root(const string name); 88 89 /**90 * Actual calculation of frequencies of image sideband91 **/92 void solveImageFreqency();93 98 94 99 private: … … 99 104 /** Return if the path exists (optionally, check file type) **/ 100 105 Bool checkFile(const string name, string type=""); 106 107 /** **/ 108 unsigned int setupShift(); 109 bool getFreqInfo(const CountedPtr<Scantable> &stab, const unsigned int &ifno, 110 double &freq0, double &incr, unsigned int &nchan); 111 112 /** Grid scantable **/ 113 ScantableWrapper gridTable(); 114 void mapExtent(vector< CountedPtr<Scantable> > &tablist, 115 Double &xmin, Double &xmax, 116 Double &ymin, Double &ymax); 117 118 /** 119 * Actual calculation of frequencies of image sideband 120 **/ 121 void solveImageFrequency(); 101 122 102 123 /** … … 112 133 const double refval, const double refpix, 113 134 const double increment, const int nChan); 135 bool getSpectraToSolve(const int polId, const int beamId, 136 const double dirX, const double dirY, 137 Matrix<float> &specmat, vector<uInt> &tabIdvec); 138 139 vector<float> solve(const Matrix<float> &specmat, 140 const vector<uInt> &tabIdvec, 141 const bool signal = true); 142 143 void shiftSpectrum(const Vector<float> &invec, double shift, 144 Vector<float> &outvec); 145 146 void deconvolve(Matrix<float> &specmat, const vector<double> shiftvec, 147 const double threshold, Matrix<float> &outmat); 148 149 void aggregateMat(Matrix<float> &inmat, vector<float> &outvec); 150 151 void subtractFromOther(const Matrix<float> &shiftmat, 152 const vector<float> &invec, 153 const vector<double> &shift, 154 vector<float> &outvec); 155 156 114 157 115 158 /** Member variables **/ … … 119 162 unsigned int ntable_; 120 163 // frequency and direction setup to select data. 121 unsignedint sigIfno_;164 int sigIfno_; 122 165 Quantum<Double> ftol_; 123 166 MFrequency::Types solFrame_; … … 130 173 double rejlimit_; 131 174 // LO1 132 double lo1Freq_; 175 double lo1Freq_; // in Hz 133 176 MFrequency::Types loFrame_; 134 177 double loTime_; … … 136 179 string asdmName_, asisName_; 137 180 181 //CountedPtr<Scantable> imgTab_p, sigTab_p; 138 182 CountedPtr<Scantable> imgTab_p, sigTab_p; 183 Table::TableType tp_; 184 FFTServer<Float, Complex> fftsf, fftsi; 139 185 // TEMPORAL member 140 186 CountedPtr<Scantable> st0_; -
trunk/src/python_STSideBandSep.cpp
r2726 r2794 34 34 boost::python::arg("refdir")="") ) 35 35 .def( "set_lo1root", &STSideBandSep::setLO1Root ) 36 // temporal methods 37 .def( "set_imgtable", &STSideBandSep::setImageTable ) 38 .def( "solve_imgfreq", &STSideBandSep::solveImageFreqency ) 39 .def( "_get_asistb_from_scantb", &STSideBandSep::setScanTb0 ) 36 .def( "separate", &STSideBandSep::separate ) 37 //// temporal methods 38 //.def( "_cpprfft", &STSideBandSep::cpprfft ) 39 //.def( "solve_imgfreq", &STSideBandSep::solveImageFreqency ) 40 //.def( "_get_asistb_from_scantb", &STSideBandSep::setScanTb0 ) 40 41 ; 41 42 };
Note:
See TracChangeset
for help on using the changeset viewer.