Ignore:
Timestamp:
01/27/10 18:29:48 (14 years ago)
Author:
Takeshi Nakazato
Message:

New Development: No

JIRA Issue: Yes CAS-1823

Ready to Release: Yes

Interface Changes: Yes

What Interface Changed: The mode parameter is added to scantable.scale() method.

Test Programs: s = sd.scantable('yourfile',False)

factor = []
for i in range(s.nrow()):

factor.append(i)

s2 = s + factor

Put in Release Notes: Yes

Module(s): -

Description: Describe your changes here...

Basic operations (addition, subtraction, multiplication, division)
of scantable with one dimensional list are implemented.
Size of list operand should be equal to either number of spectral channel
or number of row. In the former case, the list is operated as
channel-by-channel manner, while it is operated as row-by-row manner
in the latter case.
If number of spectral channel is equal to number of row, row-by-row
operation will be done.

The user is able to select operation mode (channel-by-channel or row-by-row)
manually by using lower level function, stmath.arrayop().

The scantable.scale() method is updated to allow list scaling factor.
Scaling is done in channel-by-channel manner if mode is set to 'channel',
while in row-by-row manner if mode is set to 'row'.


File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/alma/src/STMath.cpp

    r1675 r1677  
    497497      if ( tsys ) {
    498498        ts += val;
     499        tsysCol.put(i, ts);
     500      }
     501    }
     502  }
     503  return out;
     504}
     505
     506CountedPtr< Scantable > STMath::arrayOperate( const CountedPtr< Scantable >& in,
     507                                              const std::vector<float> val,
     508                                              const std::string& mode,
     509                                              bool tsys,
     510                                              const std::string& op )
     511{
     512  CountedPtr< Scantable > out ;
     513  if ( op == "channel" ) {
     514    out = arrayOperateChannel( in, val, mode, tsys ) ;
     515  }
     516  else if ( op == "row" ) {
     517    out = arrayOperateRow( in, val, mode, tsys ) ;
     518  }
     519  else {
     520    throw( AipsError( "Unknown array operation mode." ) ) ;
     521  }
     522  return out ;
     523}
     524
     525CountedPtr< Scantable > STMath::arrayOperateChannel( const CountedPtr< Scantable >& in,
     526                                                     const std::vector<float> val,
     527                                                     const std::string& mode,
     528                                                     bool tsys )
     529{
     530  // conformity of SPECTRA and TSYS
     531  if ( tsys ) {
     532    TableIterator titer(in->table(), "IFNO");
     533    while ( !titer.pastEnd() ) {
     534      ArrayColumn<Float> specCol( in->table(), "SPECTRA" ) ;
     535      ArrayColumn<Float> tsysCol( in->table(), "TSYS" ) ;
     536      Array<Float> spec = specCol.getColumn() ;
     537      Array<Float> ts = tsysCol.getColumn() ;
     538      if ( !spec.conform( ts ) ) {
     539        throw( AipsError( "SPECTRA and TSYS must conform in shape if you want to apply operation on Tsys." ) ) ;
     540      }
     541      titer.next() ;
     542    }
     543  }
     544
     545  // check if all spectra in the scantable have the same number of channel
     546  vector<uInt> nchans;
     547  vector<uInt> ifnos = in->getIFNos() ;
     548  for ( uInt i = 0 ; i < ifnos.size() ; i++ ) {
     549    nchans.push_back( in->nchan( ifnos[i] ) ) ;
     550  }
     551  Vector<uInt> mchans( nchans ) ;
     552  if ( anyNE( mchans, mchans[0] ) ) {
     553    throw( AipsError("All spectra in the input scantable must have the same number of channel for vector operation." ) ) ;
     554  }
     555
     556  // check if vector size is equal to nchan
     557  Vector<Float> fact( val ) ;
     558  if ( fact.nelements() != mchans[0] ) {
     559    throw( AipsError("Vector size must be same as number of channel.") ) ;
     560  }
     561
     562  // check divided by zero
     563  if ( ( mode == "DIV" ) && anyEQ( fact, (float)0.0 ) ) {
     564    throw( AipsError("Divided by zero is not recommended." ) ) ;
     565  }
     566
     567  CountedPtr< Scantable > out = getScantable(in, false);
     568  Table& tab = out->table();
     569  ArrayColumn<Float> specCol(tab,"SPECTRA");
     570  ArrayColumn<Float> tsysCol(tab,"TSYS");
     571  for (uInt i=0; i<tab.nrow(); ++i) {
     572    Vector<Float> spec;
     573    Vector<Float> ts;
     574    specCol.get(i, spec);
     575    tsysCol.get(i, ts);
     576    if (mode == "MUL" || mode == "DIV") {
     577      if (mode == "DIV") fact = (float)1.0 / fact;
     578      spec *= fact;
     579      specCol.put(i, spec);
     580      if ( tsys ) {
     581        ts *= fact;
     582        tsysCol.put(i, ts);
     583      }
     584    } else if ( mode == "ADD"  || mode == "SUB") {
     585      if (mode == "SUB") fact *= (float)-1.0 ;
     586      spec += fact;
     587      specCol.put(i, spec);
     588      if ( tsys ) {
     589        ts += fact;
     590        tsysCol.put(i, ts);
     591      }
     592    }
     593  }
     594  return out;
     595}
     596
     597CountedPtr< Scantable > STMath::arrayOperateRow( const CountedPtr< Scantable >& in,
     598                                                 const std::vector<float> val,
     599                                                 const std::string& mode,
     600                                                 bool tsys )
     601{
     602  // conformity of SPECTRA and TSYS
     603  if ( tsys ) {
     604    TableIterator titer(in->table(), "IFNO");
     605    while ( !titer.pastEnd() ) {
     606      ArrayColumn<Float> specCol( in->table(), "SPECTRA" ) ;
     607      ArrayColumn<Float> tsysCol( in->table(), "TSYS" ) ;
     608      Array<Float> spec = specCol.getColumn() ;
     609      Array<Float> ts = tsysCol.getColumn() ;
     610      if ( !spec.conform( ts ) ) {
     611        throw( AipsError( "SPECTRA and TSYS must conform in shape if you want to apply operation on Tsys." ) ) ;
     612      }
     613      titer.next() ;
     614    }
     615  }
     616
     617  // check if vector size is equal to nrow
     618  Vector<Float> fact( val ) ;
     619  if ( fact.nelements() != in->nrow() ) {
     620    throw( AipsError("Vector size must be same as number of row.") ) ;
     621  }
     622
     623  // check divided by zero
     624  if ( ( mode == "DIV" ) && anyEQ( fact, (float)0.0 ) ) {
     625    throw( AipsError("Divided by zero is not recommended." ) ) ;
     626  }
     627
     628  CountedPtr< Scantable > out = getScantable(in, false);
     629  Table& tab = out->table();
     630  ArrayColumn<Float> specCol(tab,"SPECTRA");
     631  ArrayColumn<Float> tsysCol(tab,"TSYS");
     632  if (mode == "DIV") fact = (float)1.0 / fact;
     633  if (mode == "SUB") fact *= (float)-1.0 ;
     634  for (uInt i=0; i<tab.nrow(); ++i) {
     635    Vector<Float> spec;
     636    Vector<Float> ts;
     637    specCol.get(i, spec);
     638    tsysCol.get(i, ts);
     639    if (mode == "MUL" || mode == "DIV") {
     640      spec *= fact[i];
     641      specCol.put(i, spec);
     642      if ( tsys ) {
     643        ts *= fact[i];
     644        tsysCol.put(i, ts);
     645      }
     646    } else if ( mode == "ADD"  || mode == "SUB") {
     647      spec += fact[i];
     648      specCol.put(i, spec);
     649      if ( tsys ) {
     650        ts += fact[i];
     651        tsysCol.put(i, ts);
     652      }
     653    }
     654  }
     655  return out;
     656}
     657
     658CountedPtr< Scantable > STMath::array2dOperate( const CountedPtr< Scantable >& in,
     659                                                const std::vector< std::vector<float> > val,
     660                                                const std::string& mode,
     661                                                bool tsys )
     662{
     663  // conformity of SPECTRA and TSYS
     664  if ( tsys ) {
     665    TableIterator titer(in->table(), "IFNO");
     666    while ( !titer.pastEnd() ) {
     667      ArrayColumn<Float> specCol( in->table(), "SPECTRA" ) ;
     668      ArrayColumn<Float> tsysCol( in->table(), "TSYS" ) ;
     669      Array<Float> spec = specCol.getColumn() ;
     670      Array<Float> ts = tsysCol.getColumn() ;
     671      if ( !spec.conform( ts ) ) {
     672        throw( AipsError( "SPECTRA and TSYS must conform in shape if you want to apply operation on Tsys." ) ) ;
     673      }
     674      titer.next() ;
     675    }
     676  }
     677
     678  // some checks
     679  vector<uInt> nchans;
     680  for ( uInt i = 0 ; i < in->nrow() ; i++ ) {
     681    nchans.push_back( (in->getSpectrum( i )).size() ) ;
     682  }
     683  //Vector<uInt> mchans( nchans ) ;
     684  vector< Vector<Float> > facts ;
     685  for ( uInt i = 0 ; i < nchans.size() ; i++ ) {
     686    Vector<Float> tmp( val[i] ) ;
     687    // check divided by zero
     688    if ( ( mode == "DIV" ) && anyEQ( tmp, (float)0.0 ) ) {
     689      throw( AipsError("Divided by zero is not recommended." ) ) ;
     690    }
     691    // conformity check
     692    if ( tmp.nelements() != nchans[i] ) {
     693      stringstream ss ;
     694      ss << "Row " << i << ": Vector size must be same as number of channel." ;
     695      throw( AipsError( ss.str() ) ) ;
     696    }
     697    facts.push_back( tmp ) ;
     698  }
     699
     700
     701  CountedPtr< Scantable > out = getScantable(in, false);
     702  Table& tab = out->table();
     703  ArrayColumn<Float> specCol(tab,"SPECTRA");
     704  ArrayColumn<Float> tsysCol(tab,"TSYS");
     705  for (uInt i=0; i<tab.nrow(); ++i) {
     706    Vector<Float> fact = facts[i] ;
     707    Vector<Float> spec;
     708    Vector<Float> ts;
     709    specCol.get(i, spec);
     710    tsysCol.get(i, ts);
     711    if (mode == "MUL" || mode == "DIV") {
     712      if (mode == "DIV") fact = (float)1.0 / fact;
     713      spec *= fact;
     714      specCol.put(i, spec);
     715      if ( tsys ) {
     716        ts *= fact;
     717        tsysCol.put(i, ts);
     718      }
     719    } else if ( mode == "ADD"  || mode == "SUB") {
     720      if (mode == "SUB") fact *= (float)-1.0 ;
     721      spec += fact;
     722      specCol.put(i, spec);
     723      if ( tsys ) {
     724        ts += fact;
    499725        tsysCol.put(i, ts);
    500726      }
Note: See TracChangeset for help on using the changeset viewer.