source: trunk/src/STGrid.cpp @ 2382

Last change on this file since 2382 was 2382, checked in by Takeshi Nakazato, 13 years ago

New Development: No

JIRA Issue: Yes CAS-2816

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No?

Module(s): Module Names change impacts.

Description: Describe your changes here...

Replaced gridAll() with gridPerPol(), which performs grigging for each
polarization components separately.

nchunk_ is tentatively set to 10000.


File size: 40.3 KB
Line 
1#include <iostream>
2#include <fstream>
3
4#include <casa/BasicSL/String.h>
5#include <casa/Arrays/Vector.h>
6#include <casa/Arrays/Matrix.h>
7#include <casa/Arrays/Cube.h>
8#include <casa/Arrays/ArrayMath.h>
9#include <casa/Arrays/ArrayIter.h>
10#include <casa/Quanta/Quantum.h>
11#include <casa/Quanta/QuantumHolder.h>
12#include <casa/Utilities/CountedPtr.h>
13#include <casa/Logging/LogIO.h>
14
15#include <tables/Tables/Table.h>
16#include <tables/Tables/TableRecord.h>
17#include <tables/Tables/ExprNode.h>
18#include <tables/Tables/ScalarColumn.h>
19#include <tables/Tables/ArrayColumn.h>
20#include <tables/Tables/TableIter.h>
21
22#include <measures/Measures/MDirection.h>
23
24#include <MathUtils.h>
25
26#include "STGrid.h"
27
28using namespace std ;
29using namespace casa ;
30using namespace asap ;
31
32namespace asap {
33
34// constructor
35STGrid::STGrid()
36{
37  init() ;
38}
39
40STGrid::STGrid( const string infile )
41{
42  init() ;
43
44  setFileIn( infile ) ;
45}
46
47void  STGrid::init()
48{
49  ifno_ = -1 ;
50  nx_ = -1 ;
51  ny_ = -1 ;
52  npol_ = 0 ;
53  nchan_ = 0 ;
54  nrow_ = 0 ;
55  cellx_ = 0.0 ;
56  celly_ = 0.0 ;
57  center_ = Vector<Double> ( 2, 0.0 ) ;
58  convType_ = "BOX" ;
59  wtype_ = "UNIFORM" ;
60  convSupport_ = -1 ;
61  userSupport_ = -1 ;
62  convSampling_ = 100 ;
63  nprocessed_ = 0 ;
64  nchunk_ = 0 ;
65}
66
67void STGrid::setFileIn( const string infile )
68{
69  String name( infile ) ;
70  if ( infile_.compare( name ) != 0 ) {
71    infile_ = String( infile ) ;
72    tab_ = Table( infile_ ) ;
73  }
74}
75
76void STGrid::setPolList( vector<unsigned int> pols )
77{
78  pollist_.assign( Vector<uInt>( pols ) ) ;
79  cout << "pollist_ = " << pollist_ << endl ;
80}
81
82void STGrid::setScanList( vector<unsigned int> scans )
83{
84  scanlist_.assign( Vector<uInt>( scans ) ) ;
85  cout << "scanlist_ = " << scanlist_ << endl ;
86}
87
88void STGrid::setWeight( const string wType )
89{
90  wtype_ = String( wType ) ;
91  wtype_.upcase() ;
92  cout << "wtype_ = " << wtype_ << endl ;
93}
94
95void STGrid::defineImage( int nx,
96                          int ny,
97                          string scellx,
98                          string scelly,
99                          string scenter )
100{
101  ROArrayColumn<Double> dirCol( tab_, "DIRECTION" ) ;
102  Matrix<Double> direction = dirCol.getColumn() ;
103  Double rmax, rmin, dmax, dmin ;
104  minMax( rmin, rmax, direction.row( 0 ) ) ;
105  minMax( dmin, dmax, direction.row( 1 ) ) ;
106
107  Int npx = (Int)nx ;
108  Int npy = (Int)ny ;
109  String cellx( scellx ) ;
110  String celly( scelly ) ;
111  String center( scenter ) ;
112  setupGrid( npx, npy,
113             cellx, celly,
114             rmin, rmax,
115             dmin, dmax,
116             center ) ;
117}
118 
119void STGrid::setFunc( string convType,
120                      int convSupport )
121{
122  convType_ = String( convType ) ;
123  convType_.upcase() ;
124  userSupport_ = (Int)convSupport ;
125}
126
127#define NEED_UNDERSCORES
128#if defined(NEED_UNDERSCORES)
129#define ggridsd ggridsd_
130#endif
131extern "C" {
132   void ggridsd(Double*,
133                const Complex*,
134                Int*,
135                Int*,
136                Int*,
137                const Int*,
138                const Int*,
139                const Float*,
140                Int*,
141                Int*,
142                Complex*,
143                Float*,
144                Int*,
145                Int*,
146                Int *,
147                Int *,
148                Int*,
149                Int*,
150                Float*,
151                Int*,
152                Int*,
153                Double*);
154}
155void STGrid::call_ggridsd( Double* xy,
156                           const Complex* values,
157                           Int* nvispol,
158                           Int* nvischan,
159                           const Int* flag,
160                           const Int* rflag,
161                           const Float* weight,
162                           Int* nrow,
163                           Int* irow,
164                           Complex* grid,
165                           Float* wgrid,
166                           Int* nx,
167                           Int* ny,
168                           Int * npol,
169                           Int * nchan,
170                           Int* support,
171                           Int* sampling,
172                           Float* convFunc,
173                           Int *chanMap,
174                           Int *polMap )
175{
176  // parameters for gridding
177  Int idopsf = 0 ;
178  Int len = (*npol)*(*nchan) ;
179  Double *sumw_p = new Double[len] ;
180  {
181    Double *work_p = sumw_p ;
182    for ( Int i = 0 ; i < len ; i++ ) {
183      *work_p = 0.0 ;
184      work_p++ ;
185    }
186  }
187
188  // call ggridsd
189  ggridsd( xy,
190           values,
191           nvispol,
192           nvischan,
193           &idopsf,
194           flag,
195           rflag,
196           weight,
197           nrow,
198           irow,
199           grid,
200           wgrid,
201           nx,
202           ny,
203           npol,
204           nchan,
205           support,
206           sampling,
207           convFunc,
208           chanMap,
209           polMap,
210           sumw_p ) ;
211
212  // finalization
213  delete sumw_p ;
214}
215
216void STGrid::gridPerRow()
217{
218  LogIO os( LogOrigin("STGrid", "gridPerRow", WHERE) ) ;
219  double t0, t1 ;
220
221  // grid parameter
222  os << LogIO::DEBUGGING ;
223  os << "----------" << endl ;
224  os << "Grid parameter summary" << endl ;
225  os << "   (nx,ny) = (" << nx_ << "," << ny_ << ")" << endl ;
226  os << "   (cellx,celly) = (" << cellx_ << "," << celly_ << ")" << endl ;
227  os << "   center = " << center_ << endl ;
228  os << "----------" << LogIO::POST ;
229  os << LogIO::NORMAL ;
230
231  // boolean for getStorage
232  Bool deletePos, deleteData, deleteWgt, deleteFlag, deleteFlagR, deleteConv, deleteDataG, deleteWgtG ;
233
234  // convolution kernel
235  Vector<Float> convFunc ;
236  t0 = mathutil::gettimeofday_sec() ;
237  setConvFunc( convFunc ) ;
238  t1 = mathutil::gettimeofday_sec() ;
239  os << "setConvFunc: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
240  //cout << "convSupport=" << convSupport_ << endl ;
241  //cout << "convFunc=" << convFunc << endl ;
242
243  // grid data
244  Int gnx = nx_ ;
245  Int gny = ny_ ;
246  // Extend grid plane with convSupport_
247//   Int gnx = nx_+convSupport_*2 ;
248//   Int gny = ny_+convSupport_*2 ;
249  IPosition gshape( 4, gnx, gny, npol_, nchan_ ) ;
250  Array<Complex> gdataArrC( gshape, 0.0 ) ;
251  // 2011/12/20 TN
252  // data_ and gwgtArr share storage
253  data_.resize( gshape ) ;
254  data_ = 0.0 ;
255  Array<Float> gwgtArr( data_ ) ;
256
257  // data storage
258  Int irow = -1 ;
259  IPosition cshape( 3, npol_, nchan_, nchunk_ ) ;
260  IPosition mshape( 2, npol_, nchunk_ ) ;
261  IPosition vshape( 1, nchunk_ ) ;
262  IPosition dshape( 2, 2, nchunk_ ) ;
263  IPosition wshape( 2, nchan_, nchunk_ ) ;
264  Array<Complex> spectra( cshape ) ;
265  Array<Double> direction( dshape ) ;
266  Array<Int> flagtra( cshape ) ;
267  Array<Int> rflag( vshape ) ;
268  Array<Float> weight( wshape ) ;
269  Array<Double> xypos( dshape ) ;
270
271  spectraF_.resize( cshape ) ;
272  flagtraUC_.resize( cshape ) ;
273  rflagUI_.resize( vshape ) ;
274
275  // parameters for gridding
276  Int *chanMap = new Int[nchan_] ;
277  {
278    Int *work_p = chanMap ;
279    for ( Int i = 0 ; i < nchan_ ; i++ ) {
280      *work_p = i ;
281      work_p++ ;
282    }
283  }
284  Int *polMap = new Int[npol_] ;
285  {
286    Int *work_p = polMap ;
287    for ( Int i = 0 ; i < npol_ ; i++ ) {
288      *work_p = i ;
289      work_p++ ;
290    }
291  }
292
293  // for performance check
294  double eGetDataChunk = 0.0 ;
295  double eToPixel = 0.0 ;
296  double eGGridSD = 0.0 ;
297  double eToInt = 0.0 ;
298
299  // prepare pointer
300  Float *conv_p = convFunc.getStorage( deleteConv ) ;
301  Complex *gdata_p = gdataArrC.getStorage( deleteDataG ) ;
302  Float *wdata_p = gwgtArr.getStorage( deleteWgtG ) ;
303  const Complex *data_p = spectra.getStorage( deleteData ) ;
304  const Float *wgt_p = weight.getStorage( deleteWgt ) ;
305  const Int *flag_p = flagtra.getStorage( deleteFlag ) ;
306  const Int *rflag_p = rflag.getStorage( deleteFlagR ) ;
307  Double *xypos_p = xypos.getStorage( deletePos ) ;
308
309  while( !pastEnd() ) {
310    // retrieve data
311    t0 = mathutil::gettimeofday_sec() ;
312    Int nrow = getDataChunk( spectra, direction, flagtra, rflag, weight ) ;
313    //os << "nrow = " << nrow << LogIO::POST ;
314    t1 = mathutil::gettimeofday_sec() ;
315    eGetDataChunk += t1-t0 ;
316    eToInt += subtime_ ;
317   
318    // world -> pixel
319    t0 = mathutil::gettimeofday_sec() ;
320    toPixel( direction, xypos ) ;
321    t1 = mathutil::gettimeofday_sec() ;
322    eToPixel += t1-t0 ;
323   
324    // call ggridsd
325    irow = -1 ;
326    t0 = mathutil::gettimeofday_sec() ;
327    call_ggridsd( xypos_p,
328                  data_p,
329                  &npol_,
330                  &nchan_,
331                  flag_p,
332                  rflag_p,
333                  wgt_p,
334                  &nrow,
335                  &irow,
336                  gdata_p,
337                  wdata_p,
338                  &gnx,
339                  &gny,
340                  &npol_,
341                  &nchan_,
342                  &convSupport_,
343                  &convSampling_,
344                  conv_p,
345                  chanMap,
346                  polMap ) ;
347    t1 = mathutil::gettimeofday_sec() ;
348    eGGridSD += t1-t0 ;
349
350  }
351  os << "getDataChunk: elapsed time is " << eGetDataChunk << " sec." << LogIO::POST ;
352  os << "toPixel: elapsed time is " << eToPixel << " sec." << LogIO::POST ;
353  os << "ggridsd: elapsed time is " << eGGridSD << " sec." << LogIO::POST ;
354  os << "toInt: elapsed time is " << eToInt << " sec." << LogIO::POST ;
355
356  // finalization
357  convFunc.putStorage( conv_p, deleteConv ) ;
358  gdataArrC.putStorage( gdata_p, deleteDataG ) ;
359  gwgtArr.putStorage( wdata_p, deleteWgtG ) ;
360  xypos.putStorage( xypos_p, deletePos ) ;
361  spectra.freeStorage( data_p, deleteData ) ;
362  weight.freeStorage( wgt_p, deleteWgt ) ;
363  flagtra.freeStorage( flag_p, deleteFlag ) ;
364  rflag.freeStorage( rflag_p, deleteFlagR ) ;
365  delete polMap ;
366  delete chanMap ;
367
368  // set data
369  setData( gdataArrC, gwgtArr ) ;
370
371}
372
373Bool STGrid::pastEnd()
374{
375  LogIO os( LogOrigin("STGrid","pastEnd",WHERE) ) ;
376  Bool b = nprocessed_ >= nrow_ ;
377  return b ;
378}
379
380void STGrid::grid()
381{
382  // data selection
383  selectData() ;
384  setupArray() ;
385
386  if ( npol_ > 1 ) {
387    LogIO os( LogOrigin("STGrid", "grid", WHERE) ) ;
388    os << LogIO::WARN << "STGrid doesn't support assigning polarization-dependent weight. Use averaged weight over polarization." << LogIO::POST ;
389  }
390 
391  if ( wtype_.compare("UNIFORM") != 0 &&
392       wtype_.compare("TINT") != 0 &&
393       wtype_.compare("TSYS") != 0 &&
394       wtype_.compare("TINTSYS") != 0 ) {
395    LogIO os( LogOrigin("STGrid", "grid", WHERE) ) ;
396    os << LogIO::WARN << "Unsupported weight type '" << wtype_ << "', apply UNIFORM weight" << LogIO::POST ;
397    wtype_ = "UNIFORM" ;
398  }
399
400  Bool doAll = examine() ;
401
402  if ( doAll )
403    gridPerPol() ;
404  else {
405    sortData() ;
406    gridPerRow() ;
407  }
408}
409
410Bool STGrid::examine()
411{
412  // TODO: nchunk_ must be determined from nchan_, npol_, and (nx_,ny_)
413  //       by considering data size to be allocated for ggridsd input/output
414  nchunk_ = 10000 ;
415  Bool b = nchunk_ >= nrow_ ;
416  nchunk_ = min( nchunk_, nrow_ ) ;
417  return b ;
418}
419
420void STGrid::gridPerPol()
421{
422  LogIO os( LogOrigin("STGrid", "gridPerPol", WHERE) ) ;
423  double t0, t1 ;
424
425  // grid parameter
426  os << LogIO::DEBUGGING ;
427  os << "----------" << endl ;
428  os << "Grid parameter summary" << endl ;
429  os << "   (nx,ny) = (" << nx_ << "," << ny_ << ")" << endl ;
430  os << "   (cellx,celly) = (" << cellx_ << "," << celly_ << ")" << endl ;
431  os << "   center = " << center_ << endl ;
432  os << "----------" << LogIO::POST ;
433  os << LogIO::NORMAL ;
434
435  // convolution kernel
436  Vector<Float> convFunc ;
437  t0 = mathutil::gettimeofday_sec() ;
438  setConvFunc( convFunc ) ;
439  t1 = mathutil::gettimeofday_sec() ;
440  os << "setConvFunc: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
441  //cout << "convSupport=" << convSupport_ << endl ;
442  //cout << "convFunc=" << convFunc << endl ;
443
444  // prepare grid data storage
445  Int gnx = nx_ ;
446  Int gny = ny_ ;
447//   // Extend grid plane with convSupport_
448//   Int gnx = nx_+convSupport_*2 ;
449//   Int gny = ny_+convSupport_*2 ;
450  IPosition gshape( 4, gnx, gny, npol_, nchan_ ) ;
451  Array<Complex> gdataArrC( gshape, 0.0 ) ;
452  //Array<Float> gwgtArr( gshape, 0.0 ) ;
453  // 2011/12/20 TN
454  // data_ and weight array shares storage
455  data_.resize( gshape ) ;
456  data_ = 0.0 ;
457  Array<Float> gwgtArr( data_ ) ;
458
459  // to read data from the table
460  IPosition mshape( 2, nchan_, nrow_ ) ;
461  Array<Complex> spectra( mshape ) ;
462  Array<Double> direction( IPosition(2,2,nrow_) ) ;
463  Array<Int> flagtra( mshape ) ;
464  Array<Int> rflag( IPosition(1,nrow_) ) ;
465  Array<Float> weight( mshape ) ;
466
467  // maps
468  Int *chanMap = new Int[nchan_] ;
469  {
470    Int *work_p = chanMap ;
471    for ( Int i = 0 ; i < nchan_ ; i++ ) {
472      *work_p = i ;
473      work_p++ ;
474    }
475  }
476  Int *polMap = new Int[1] ;
477  Int nvispol = 1 ;
478 
479  for ( Int ipol = 0 ; ipol < npol_ ; ipol++ ) {
480    t0 = mathutil::gettimeofday_sec() ;
481    initPol( ipol ) ;
482    t1 = mathutil::gettimeofday_sec() ;
483    os << "initPol: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
484
485    // retrieve data
486    t0 = mathutil::gettimeofday_sec() ;
487    getDataPerPol( spectra, direction, flagtra, rflag, weight ) ;
488    t1 = mathutil::gettimeofday_sec() ;
489    os << "getData: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
490    IPosition sshape = spectra.shape() ;
491   
492    // world -> pixel
493    Array<Double> xypos( direction.shape(), 0.0 ) ;
494    t0 = mathutil::gettimeofday_sec() ;
495    toPixel( direction, xypos ) ; 
496    t1 = mathutil::gettimeofday_sec() ;
497    //os << "xypos=" << xypos << LogIO::POST ;
498    os << "toPixel: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
499   
500    // call ggridsd
501    Bool deletePos, deleteData, deleteWgt, deleteFlag, deleteFlagR, deleteConv, deleteDataG, deleteWgtG ;
502    Double *xypos_p = xypos.getStorage( deletePos ) ;
503    const Complex *data_p = spectra.getStorage( deleteData ) ;
504    const Float *wgt_p = weight.getStorage( deleteWgt ) ;
505    const Int *flag_p = flagtra.getStorage( deleteFlag ) ;
506    const Int *rflag_p = rflag.getStorage( deleteFlagR ) ;
507    Float *conv_p = convFunc.getStorage( deleteConv ) ;
508    Complex *gdata_p = gdataArrC.getStorage( deleteDataG ) ;
509    Float *wdata_p = gwgtArr.getStorage( deleteWgtG ) ;
510    polMap[0] = ipol ;
511    t0 = mathutil::gettimeofday_sec() ;
512    Int irow = -1 ;
513    call_ggridsd( xypos_p,
514                  data_p,
515                  &nvispol,
516                  &nchan_,
517                  flag_p,
518                  rflag_p,
519                  wgt_p,
520                  &nrow_,
521                  &irow,
522                  gdata_p,
523                  wdata_p,
524                  &gnx,
525                  &gny,
526                  &npol_,
527                  &nchan_,
528                  &convSupport_,
529                  &convSampling_,
530                  conv_p,
531                  chanMap,
532                  polMap ) ;
533    t1 = mathutil::gettimeofday_sec() ;
534    os << "ggridsd: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
535    xypos.putStorage( xypos_p, deletePos ) ;
536    spectra.freeStorage( data_p, deleteData ) ;
537    weight.freeStorage( wgt_p, deleteWgt ) ;
538    flagtra.freeStorage( flag_p, deleteFlag ) ;
539    rflag.freeStorage( rflag_p, deleteFlagR ) ;
540    convFunc.putStorage( conv_p, deleteConv ) ;
541    gdataArrC.putStorage( gdata_p, deleteDataG ) ;
542    gwgtArr.putStorage( wdata_p, deleteWgtG ) ;
543  }
544
545  // delete maps
546  delete polMap ;
547  delete chanMap ;
548
549  setData( gdataArrC, gwgtArr ) ;
550//   os << "gdataArr = " << gdataArr << LogIO::POST ;
551//   os << "gwgtArr = " << gwgtArr << LogIO::POST ;
552//   os << "data_ " << data_ << LogIO::POST ;
553}
554
555void STGrid::initPol( Int ipol )
556{
557  ptab_ = tab_( tab_.col("POLNO") == (uInt)ipol ) ;
558
559  attach( ptab_ ) ;
560}
561
562void STGrid::setData( Array<Complex> &gdata,
563                      Array<Float> &gwgt )
564{
565  // 2011/12/20 TN
566  // gwgt and data_ share storage
567  LogIO os( LogOrigin("STGrid","setData",WHERE) ) ;
568  double t0, t1 ;
569  t0 = mathutil::gettimeofday_sec() ;
570  uInt len = data_.nelements() ;
571  const Complex *w1_p ;
572  Float *w2_p ;
573  Bool b1, b2 ;
574  const Complex *gdata_p = gdata.getStorage( b1 ) ;
575  Float *gwgt_p = data_.getStorage( b2 ) ;
576  w1_p = gdata_p ;
577  w2_p = gwgt_p ;
578  for ( uInt i = 0 ; i < len ; i++ ) {
579    if ( *w2_p > 0.0 ) *w2_p = (*w1_p).real() / *w2_p ;
580    w1_p++ ;
581    w2_p++ ;
582  }
583  gdata.freeStorage( gdata_p, b1 ) ;
584  data_.putStorage( gwgt_p, b2 ) ;
585  t1 = mathutil::gettimeofday_sec() ;
586  os << "setData: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
587}
588
589void STGrid::setupGrid( Int &nx,
590                        Int &ny,
591                        String &cellx,
592                        String &celly,
593                        Double &xmin,
594                        Double &xmax,
595                        Double &ymin,
596                        Double &ymax,
597                        String &center )
598{
599  LogIO os( LogOrigin("STGrid","setupGrid",WHERE) ) ;
600  //cout << "nx=" << nx << ", ny=" << ny << endl ;
601
602  // center position
603  if ( center.size() == 0 ) {
604    center_(0) = 0.5 * ( xmin + xmax ) ;
605    center_(1) = 0.5 * ( ymin + ymax ) ;
606  }
607  else {
608    String::size_type pos0 = center.find( " " ) ;
609    if ( pos0 == String::npos ) {
610      throw AipsError( "bad string format in parameter center" ) ;
611    }
612    String::size_type pos1 = center.find( " ", pos0+1 ) ;
613    String typestr, xstr, ystr ;
614    if ( pos1 != String::npos ) {
615      typestr = center.substr( 0, pos0 ) ;
616      xstr = center.substr( pos0+1, pos1-pos0 ) ;
617      ystr = center.substr( pos1+1 ) ;
618      // todo: convert to J2000 (or direction ref for DIRECTION column)
619    }
620    else {
621      typestr = "J2000" ;
622      xstr = center.substr( 0, pos0 ) ;
623      ystr = center.substr( pos0+1 ) ;
624    }
625    QuantumHolder qh ;
626    String err ;
627    qh.fromString( err, xstr ) ;
628    Quantum<Double> xcen = qh.asQuantumDouble() ;
629    qh.fromString( err, ystr ) ;
630    Quantum<Double> ycen = qh.asQuantumDouble() ;
631    center_(0) = xcen.getValue( "rad" ) ;
632    center_(1) = ycen.getValue( "rad" ) ;
633  }
634
635
636  nx_ = nx ;
637  ny_ = ny ;
638  if ( nx < 0 && ny > 0 ) {
639    nx_ = ny ;
640    ny_ = ny ;
641  }
642  if ( ny < 0 && nx > 0 ) {
643    nx_ = nx ;
644    ny_ = nx ;
645  }
646
647  //Double wx = xmax - xmin ;
648  //Double wy = ymax - ymin ;
649  Double wx = max( abs(xmax-center_(0)), abs(xmin-center_(0)) ) * 2 ;
650  Double wy = max( abs(ymax-center_(1)), abs(ymin-center_(1)) ) * 2 ;
651  // take 10% margin
652  wx *= 1.10 ;
653  wy *= 1.10 ;
654
655  Quantum<Double> qcellx ;
656  Quantum<Double> qcelly ;
657  //cout << "nx_ = " << nx_ << ",  ny_ = " << ny_ << endl ;
658  if ( cellx.size() != 0 && celly.size() != 0 ) {
659    readQuantity( qcellx, cellx ) ;
660    readQuantity( qcelly, celly ) ;
661  }
662  else if ( celly.size() != 0 ) {
663    os << "Using celly to x-axis..." << LogIO::POST ;
664    readQuantity( qcelly, celly ) ;
665    qcellx = qcelly ;
666  }
667  else if ( cellx.size() != 0 ) {
668    os << "Using cellx to y-axis..." << LogIO::POST ;
669    readQuantity( qcellx, cellx ) ;
670    qcelly = qcellx ;
671  }
672  else {
673    if ( nx_ < 0 ) {
674      os << "No user preference in grid setting. Using default..." << LogIO::POST ;
675      readQuantity( qcellx, "1.0arcmin" ) ;
676      qcelly = qcellx ;
677    }
678    else {
679      if ( wx == 0.0 ) {
680        os << "Using default spatial extent (10arcmin) in x" << LogIO::POST ;
681        wx = 0.00290888 ;
682      }
683      if ( wy == 0.0 ) {
684        os << "Using default spatial extent (10arcmin) in y" << LogIO::POST ;
685        wy = 0.00290888 ;
686      }
687      qcellx = Quantum<Double>( wx/nx_, "rad" ) ;
688      qcelly = Quantum<Double>( wy/ny_, "rad" ) ;
689    }
690  }
691  cellx_ = qcellx.getValue( "rad" ) ;
692  celly_ = qcelly.getValue( "rad" ) ;
693  if ( nx_ < 0 ) {
694    if ( wx == 0.0 ) {
695      os << "Using default spatial extent (10arcmin) in x" << LogIO::POST ;
696      wx = 0.00290888 ;
697    }
698    if ( wy == 0.0 ) {
699      os << "Using default spatial extent (10arcmin) in y" << LogIO::POST ;
700      wy = 0.00290888 ;
701    }
702    nx_ = Int( ceil( wx/cellx_ ) ) ;
703    ny_ = Int( ceil( wy/celly_ ) ) ;
704  }
705}
706
707void STGrid::selectData()
708{
709  Int ifno = ifno_ ;
710  Table taborg( infile_ ) ;
711  if ( ifno == -1 ) {
712    LogIO os( LogOrigin("STGrid","selectData",WHERE) ) ;
713//     os << LogIO::SEVERE
714//        << "Please set IFNO before actual gridding"
715//        << LogIO::EXCEPTION ;
716    ROScalarColumn<uInt> ifnoCol( taborg, "IFNO" ) ;
717    ifno = ifnoCol( 0 ) ;
718    os << LogIO::WARN
719       << "IFNO is not given. Using default IFNO: " << ifno << LogIO::POST ;
720  }
721//   tab = taborg( taborg.col("IFNO") == ifno ) ;
722  TableExprNode node ;
723  node = taborg.col("IFNO") == ifno ;
724  if ( scanlist_.size() > 0 ) {
725    node = node && taborg.col("SCANNO").in( scanlist_ ) ;
726  }
727  tab_ = taborg( node ) ;
728  if ( tab_.nrow() == 0 ) {
729    LogIO os( LogOrigin("STGrid","selectData",WHERE) ) ;
730    os << LogIO::SEVERE
731       << "No corresponding rows for given selection: IFNO " << ifno ;
732    if ( scanlist_.size() > 0 )
733      os << " SCANNO " << scanlist_ ;
734    os << LogIO::EXCEPTION ;
735  }
736  attach( tab_ ) ;
737}
738
739void STGrid::attach( Table &tab )
740{
741  // attach to table
742  spectraCol_.attach( tab, "SPECTRA" ) ;
743  flagtraCol_.attach( tab, "FLAGTRA" ) ;
744  directionCol_.attach( tab, "DIRECTION" ) ;
745  flagRowCol_.attach( tab, "FLAGROW" ) ;
746  tsysCol_.attach( tab, "TSYS" ) ;
747  intervalCol_.attach( tab, "INTERVAL" ) ;
748//   Vector<String> colnames( 6 ) ;
749//   colnames[0] = "SPECTRA" ;
750//   colnames[1] = "FLAGTRA" ;
751//   colnames[2] = "DIRECTION" ;
752//   colnames[3] = "FLAGROW" ;
753//   colnames[4] = "TSYS" ;
754//   colnames[5] = "INTERVAL" ;
755//   row_ = ROTableRow( tab_, colnames ) ;
756//   const TableRecord &rec = row_.record() ;
757//   spectraRF_.attachToRecord( rec, colnames[0] ) ;
758//   flagtraRF_.attachToRecord( rec, colnames[1] ) ;
759//   directionRF_.attachToRecord( rec, colnames[2] ) ;
760//   flagRowRF_.attachToRecord( rec, colnames[3] ) ;
761//   tsysRF_.attachToRecord( rec, colnames[4] ) ;
762//   intervalRF_.attachToRecord( rec, colnames[5] ) ;
763}
764
765void STGrid::getDataPerPol( Array<Float> &spectra,
766                            Array<Double> &direction,
767                            Array<uChar> &flagtra,
768                            Array<uInt> &rflag,
769                            Array<Float> &weight )
770{
771  LogIO os( LogOrigin("STGrid","getDataPerPol",WHERE) ) ;
772  Vector<uInt> rflagVec( rflag ) ;
773  // 2011/12/22 TN
774  // weight and tsys shares its storage
775  Array<Float> tsys( weight ) ;
776  Array<Double> tint( rflag.shape() ) ;
777  Vector<Double> tintVec( tint ) ;
778
779  spectraCol_.getColumn( spectra ) ;
780  flagtraCol_.getColumn( flagtra ) ;
781  flagRowCol_.getColumn( rflagVec ) ;
782  directionCol_.getColumn( direction ) ;
783  intervalCol_.getColumn( tintVec ) ;
784  Vector<Float> tsysTemp = tsysCol_( 0 ) ;
785  if ( tsysTemp.nelements() == (uInt)nchan_ ) {
786    tsysCol_.getColumn( tsys ) ;
787  }
788  else {
789    tsys = tsysTemp[0] ;
790  }
791
792  getWeightPerPol( weight, tsys, tint ) ;
793}
794
795void STGrid::getDataPerPol( Array<Complex> &spectra,
796                            Array<Double> &direction,
797                            Array<Int> &flagtra,
798                            Array<Int> &rflag,
799                            Array<Float> &weight )
800{
801  LogIO os( LogOrigin("STGrid","getDataPerPol",WHERE) ) ;
802  double t0, t1 ;
803
804  Array<uChar> flagUC( flagtra.shape() ) ;
805  Array<uInt> rflagUI( rflag.shape() ) ;
806  Array<Float> spectraF( spectra.shape() ) ;
807  getDataPerPol( spectraF, direction, flagUC, rflagUI, weight ) ;
808
809  convertArray( spectra, spectraF ) ;
810  t0 = mathutil::gettimeofday_sec() ;
811  toInt( flagUC, flagtra ) ;
812  toInt( rflagUI, rflag ) ;
813  t1 = mathutil::gettimeofday_sec() ;
814  os << "toInt: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
815}
816
817Int STGrid::getDataChunk( Array<Complex> &spectra,
818                          Array<Double> &direction,
819                          Array<Int> &flagtra,
820                          Array<Int> &rflag,
821                          Array<Float> &weight )
822{
823  Int nrow = getDataChunk( spectraF_, direction, flagtraUC_, rflagUI_, weight ) ;
824  double t0, t1 ;
825  t0 = mathutil::gettimeofday_sec() ;
826  convertArray( spectra, spectraF_ ) ;
827  toInt( flagtraUC_, flagtra ) ;
828  toInt( rflagUI_, rflag ) ;
829  t1 = mathutil::gettimeofday_sec() ;
830  subtime_ = t1 - t0 ;
831 
832  return nrow ;
833}
834
835Int STGrid::getDataChunk( Array<Float> &spectra,
836                          Array<Double> &direction,
837                          Array<uChar> &flagtra,
838                          Array<uInt> &rflag,
839                          Array<Float> &weight )
840{
841  LogIO os( LogOrigin("STGrid","getDataChunk",WHERE) ) ;
842  Int nrow = min( spectra.shape()[2], nrow_-nprocessed_ ) ;
843  Array<Float> tsys( spectra.shape() ) ;
844  Array<Double> tint( IPosition(2,spectra.shape()[0],spectra.shape()[2]) ) ;
845  IPosition m( 2, 0, 2 ) ;
846  IPosition v( 1, 0 ) ;
847  ArrayIterator<Float> spi( spectra, m, False ) ;
848  ArrayIterator<uChar> fli( flagtra, m, False ) ;
849  ArrayIterator<Float> tsi( tsys, m, False ) ;
850  ArrayIterator<Double> di( direction, v ) ;
851  Bool bfr, bti ;
852  uInt *fr_p = rflag.getStorage( bfr ) ;
853  Double *ti_p = tint.getStorage( bti ) ;
854  uInt *wfr_p = fr_p ;
855  Double *wti_p = ti_p ;
856  Int offset = nprocessed_ * npol_ ;
857  Int start = offset ;
858  Int end = start + nrow * npol_ ;
859  for ( Int irow = 0 ; irow < npol_ * nrow ; irow++ ) {
860    Array<Float> spSlice = spi.array() ;
861    Array<uChar> flSlice = fli.array() ;
862    Array<Float> tsSlice = tsi.array() ;
863
864    uInt idx = rows_[offset+irow] ;
865    spectraCol_.get( idx, spSlice ) ;
866
867    flagtraCol_.get( idx, flSlice ) ;
868    Vector<Float> tmpF = tsysCol_( idx ) ;
869    if ( tmpF.nelements() == (uInt)nchan_ ) {
870      tsSlice = tmpF ;
871    }
872    else {
873      tsSlice = tmpF[0] ;
874    }
875    *wti_p = intervalCol_( idx ) ;
876
877    spi.next() ;
878    fli.next() ;
879    tsi.next() ;
880    wti_p++ ;
881  }
882  tint.putStorage( ti_p, bti ) ;
883  for ( Int irow = 0 ; irow < nrow ; irow += npol_ ) {
884    uInt idx = rows_[offset+irow] ;
885    directionCol_.get( idx, di.array() ) ;
886    di.next() ;
887
888    *wfr_p = flagRowCol_( idx ) ;
889    for ( Int ipol = 1 ; ipol < npol_ ; ipol++ ) {
890      *wfr_p = max( *wfr_p, flagRowCol_( rows_[offset+irow+ipol] ) ) ;
891    }
892    wfr_p++ ;
893  }
894  rflag.putStorage( fr_p, bfr ) ;
895//   Bool bti, bfr ;
896//   Double *ti_p = tint.getStorage( bti ) ;
897//   Double *wti_p = ti_p ;
898//   uInt *fr_p = rflag.getStorage( bfr ) ;
899//   uInt *wfr_p = fr_p - 1 ;
900//   Int start = nprocessed_ * npol_ ;
901//   Int end = start + nrow * npol_ ;
902//   for ( Int irow = start ; irow < end ; irow++ ) {
903//     uInt idx = rows_[irow] ;
904//     row_.get( idx ) ;
905//     // SPECTRA
906// //     os << "spi.array().shape()=" << spi.array().shape() << LogIO::POST ;
907// //     os << "(*spectraRF_).shape()=" << (*spectraRF_).shape() << LogIO::POST ;
908//     spi.array() = *spectraRF_ ;
909   
910//     // FLAGTRA
911//     fli.array() = *flagtraRF_ ;
912
913//     // INTERVAL
914//     *wti_p = *intervalRF_ ;
915
916//     // TSYS
917// //     os << "tsi.array().shape()=" << tsi.array().shape() << LogIO::POST ;
918// //     os << "(*tsysRF_).shape()=" << (*tsysRF_).shape() << LogIO::POST ;
919// //     os << "(*tsysRF_).nelements()=" << (*tsysRF_).nelements() << LogIO::POST ;
920//     if ( (*tsysRF_).nelements() == (uInt)nchan_ )
921//       tsi.array() = *tsysRF_ ;
922//     else
923//       tsi.array() = *((*tsysRF_).data()) ;
924
925//     // DIRECTION and FLAGROW
926//     Int mod = irow % npol_ ;
927//     if ( mod == 0 ) {
928// //       os << "di.array().shape()=" << di.array().shape() << LogIO::POST ;
929// //       os << "(*directionRF_).shape()=" << (*directionRF_).shape() << LogIO::POST ;
930//       di.array() = *directionRF_ ;
931//       wfr_p++ ;
932//       *wfr_p = *flagRowRF_ ;
933//     }
934//     else {
935//       *wfr_p += *flagRowRF_ ;
936//     }
937   
938//     // increment
939//     spi.next() ;
940//     fli.next() ;
941//     tsi.next() ;
942//     di.next() ;
943//     *wti_p++ ;
944//   }
945//   tint.putStorage( ti_p, bti ) ;
946//   rflag.putStorage( fr_p, bfr ) ;
947
948  getWeight( weight, tsys, tint ) ;
949
950  nprocessed_ += nrow ;
951 
952  return nrow ;
953}
954
955void STGrid::setupArray()
956{
957  LogIO os( LogOrigin("STGrid","setupArray",WHERE) ) ;
958  ROScalarColumn<uInt> polnoCol( tab_, "POLNO" ) ;
959  Vector<uInt> pols = polnoCol.getColumn() ;
960  //os << pols << LogIO::POST ;
961  Vector<uInt> pollistOrg ;
962  uInt npolOrg = 0 ;
963  uInt polno ;
964  for ( uInt i = 0 ; i < polnoCol.nrow() ; i++ ) {
965    //polno = polnoCol( i ) ;
966    polno = pols( i ) ;
967    if ( allNE( pollistOrg, polno ) ) {
968      pollistOrg.resize( npolOrg+1, True ) ;
969      pollistOrg[npolOrg] = polno ;
970      npolOrg++ ;
971    }
972  }
973  if ( pollist_.size() == 0 )
974    pollist_ = pollistOrg ;
975  else {
976    Vector<uInt> newlist ;
977    uInt newsize = 0 ;
978    for ( uInt i = 0 ; i < pollist_.size() ; i++ ) {
979      if ( anyEQ( pollistOrg, pollist_[i] ) ) {
980        newlist.resize( newsize+1, True ) ;
981        newlist[newsize] = pollist_[i] ;
982        newsize++ ;
983      }
984    }
985    pollist_.assign( newlist ) ;
986  }
987  npol_ = pollist_.size() ;
988  if ( npol_ == 0 ) {
989    os << LogIO::SEVERE << "Empty pollist" << LogIO::EXCEPTION ;
990  }
991  nrow_ = tab_.nrow() / npolOrg ;
992  ROArrayColumn<uChar> tmpCol( tab_, "FLAGTRA" ) ;
993  nchan_ = tmpCol( 0 ).nelements() ;
994//   os << "npol_ = " << npol_ << "(" << pollist_ << ")" << endl
995//      << "nchan_ = " << nchan_ << endl
996//      << "nrow_ = " << nrow_ << LogIO::POST ;
997}
998
999void STGrid::getWeight( Array<Float> &w,
1000                        Array<Float> &tsys,
1001                        Array<Double> &tint )
1002{
1003  LogIO os( LogOrigin("STGrid","getWeight",WHERE) ) ;
1004//   double t0, t1 ;
1005//   t0 = mathutil::gettimeofday_sec() ;
1006  // resize
1007  IPosition refShape = tsys.shape() ;
1008  Int nchan = refShape[1] ;
1009  Int nrow = refShape[2] ;
1010
1011  // set weight
1012  if ( wtype_.compare( "UNIFORM" ) == 0 ) {
1013    w = 1.0 ;
1014  }
1015  else if ( wtype_.compare( "TINT" ) == 0 ) {
1016    Bool b0, b1 ;
1017    Float *w_p = w.getStorage( b0 ) ;
1018    Float *w0_p = w_p ;
1019    const Double *ti_p = tint.getStorage( b1 ) ;
1020    const Double *w1_p = ti_p ;
1021    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1022      Float val = (Float)(polMean( w1_p )) ;
1023      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1024        *w0_p = val ;
1025        w0_p++ ;
1026      }
1027    }
1028    w.putStorage( w_p, b0 ) ;
1029    tint.freeStorage( ti_p, b1 ) ;
1030  }
1031  else if ( wtype_.compare( "TSYS" ) == 0 ) {
1032    Bool b0, b1 ;
1033    Float *w_p = w.getStorage( b0 ) ;
1034    Float *w0_p = w_p ;
1035    const Float *ts_p = tsys.getStorage( b1 ) ;
1036    const Float *w1_p = ts_p ;
1037    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1038      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1039        Float val = polMean( w1_p ) ;
1040        *w0_p = 1.0 / ( val * val ) ;
1041        w0_p++ ;
1042      }
1043    }
1044    w.putStorage( w_p, b0 ) ;
1045    tsys.freeStorage( ts_p, b1 ) ;
1046  }
1047  else if ( wtype_.compare( "TINTSYS" ) == 0 ) {
1048    Bool b0, b1, b2 ;
1049    Float *w_p = w.getStorage( b0 ) ;
1050    Float *w0_p = w_p ;
1051    const Double *ti_p = tint.getStorage( b1 ) ;
1052    const Double *w1_p = ti_p ;
1053    const Float *ts_p = tsys.getStorage( b2 ) ;
1054    const Float *w2_p = ts_p ;
1055    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1056      Float interval = (Float)(polMean( w1_p )) ;
1057      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1058        Float temp = polMean( w2_p ) ;
1059        *w0_p = interval / ( temp * temp ) ;
1060        w0_p++ ;
1061      }
1062    }
1063    w.putStorage( w_p, b0 ) ;
1064    tint.freeStorage( ti_p, b1 ) ;
1065    tsys.freeStorage( ts_p, b2 ) ;
1066  }
1067  else {
1068    //LogIO os( LogOrigin("STGrid", "getWeight", WHERE) ) ;
1069    //os << LogIO::WARN << "Unsupported weight type '" << wtype_ << "', apply UNIFORM weight" << LogIO::POST ;
1070    w = 1.0 ;
1071  }
1072
1073//   t1 = mathutil::gettimeofday_sec() ;
1074//   os << "getWeight: elapsed time is " << t1-t0 << " sec" << LogIO::POST ;
1075}
1076
1077void STGrid::getWeightPerPol( Array<Float> &w,
1078                              Array<Float> &tsys,
1079                              Array<Double> &tint )
1080{
1081  LogIO os( LogOrigin("STGrid","getWeightPerPol",WHERE) ) ;
1082  //os << "start getWeightPerPol" << LogIO::POST ;
1083  double t0, t1 ;
1084  t0 = mathutil::gettimeofday_sec() ;
1085  // 2011/12/22 TN
1086  // w (weight) and tsys share storage
1087  IPosition refShape = tsys.shape() ;
1088  Int nchan = refShape[0] ;
1089  Int nrow = refShape[1] ;
1090//   os << "nchan=" << nchan << ", nrow=" << nrow << LogIO::POST ;
1091//   os << "w.shape()=" << w.shape() << endl
1092//      << "tsys.shape()=" << tsys.shape() << endl
1093//      << "tint.shape()=" << tint.shape() << LogIO::POST ;
1094
1095  // set weight
1096  if ( wtype_.compare( "UNIFORM" ) == 0 ) {
1097    w = 1.0 ;
1098  }
1099  else if ( wtype_.compare( "TINT" ) == 0 ) {
1100    Bool b0, b1 ;
1101    Float *w_p = w.getStorage( b0 ) ;
1102    Float *w0_p = w_p ;
1103    const Double *ti_p = tint.getStorage( b1 ) ;
1104    const Double *w1_p = ti_p ;
1105    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1106      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1107        *w0_p = *w1_p ;
1108        w0_p++ ;
1109      }
1110      w1_p++ ;
1111    }
1112    w.putStorage( w_p, b0 ) ;
1113    tint.freeStorage( ti_p, b1 ) ;
1114  }
1115  else if ( wtype_.compare( "TSYS" ) == 0 ) {
1116    Bool b0 ;
1117    Float *w_p = w.getStorage( b0 ) ;
1118    Float *w0_p = w_p ;
1119    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1120      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1121        Float temp = *w0_p ;
1122        *w0_p = 1.0 / ( temp * temp ) ;
1123        w0_p++ ;
1124      }
1125    }
1126    w.putStorage( w_p, b0 ) ;
1127  }
1128  else if ( wtype_.compare( "TINTSYS" ) == 0 ) {
1129    Bool b0, b1 ;
1130    Float *w_p = w.getStorage( b0 ) ;
1131    Float *w0_p = w_p ;
1132    const Double *ti_p = tint.getStorage( b1 ) ;
1133    const Double *w1_p = ti_p ;
1134    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1135      Float interval = *w1_p ;
1136      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1137        Float temp = *w0_p ;
1138        *w0_p = interval / ( temp * temp ) ;
1139        w0_p++ ;
1140      }
1141      w1_p++ ;
1142    }
1143    w.putStorage( w_p, b0 ) ;
1144    tint.freeStorage( ti_p, b1 ) ;
1145  }
1146  else {
1147    //LogIO os( LogOrigin("STGrid", "getWeight", WHERE) ) ;
1148    //os << LogIO::WARN << "Unsupported weight type '" << wtype_ << "', apply UNIFORM weight" << LogIO::POST ;
1149    w = 1.0 ;
1150  }
1151
1152  t1 = mathutil::gettimeofday_sec() ;
1153  os << "getWeight: elapsed time is " << t1-t0 << " sec" << LogIO::POST ;
1154}
1155
1156Float STGrid::polMean( const Float *p )
1157{
1158  Float v = 0.0 ;
1159  for ( Int i = 0 ; i < npol_ ; i++ ) {
1160    v += *p ;
1161    p++ ;
1162  }
1163  v /= npol_ ;
1164  return v ;
1165}
1166
1167Double STGrid::polMean( const Double *p )
1168{
1169  Double v = 0.0 ;
1170  for ( Int i = 0 ; i < npol_ ; i++ ) {
1171    v += *p ;
1172    p++ ;
1173  }
1174  v /= npol_ ;
1175  return v ;
1176}
1177
1178void STGrid::toInt( Array<uChar> &u, Array<Int> &v )
1179{
1180  uInt len = u.nelements() ;
1181  Int *int_p = new Int[len] ;
1182  Bool deleteIt ;
1183  const uChar *data_p = u.getStorage( deleteIt ) ;
1184  Int *i_p = int_p ;
1185  const uChar *u_p = data_p ;
1186  for ( uInt i = 0 ; i < len ; i++ ) {
1187    *i_p = ( *u_p == 0 ) ? 0 : 1 ;
1188    i_p++ ;
1189    u_p++ ;
1190  }
1191  u.freeStorage( data_p, deleteIt ) ;
1192  v.takeStorage( u.shape(), int_p, TAKE_OVER ) ;
1193}
1194
1195void STGrid::toInt( Array<uInt> &u, Array<Int> &v )
1196{
1197  uInt len = u.nelements() ;
1198  Int *int_p = new Int[len] ;
1199  Bool deleteIt ;
1200  const uInt *data_p = u.getStorage( deleteIt ) ;
1201  Int *i_p = int_p ;
1202  const uInt *u_p = data_p ;
1203  for ( uInt i = 0 ; i < len ; i++ ) {
1204    *i_p = ( *u_p == 0 ) ? 0 : 1 ;
1205    i_p++ ;
1206    u_p++ ;
1207  }
1208  u.freeStorage( data_p, deleteIt ) ;
1209  v.takeStorage( u.shape(), int_p, TAKE_OVER ) ;
1210}
1211
1212void STGrid::toPixel( Array<Double> &world, Array<Double> &pixel )
1213{
1214  // gridding will be done on (nx_+2*convSupport_) x (ny_+2*convSupport_)
1215  // grid plane to avoid unexpected behavior on grid edge
1216  Block<Double> pixc( 2 ) ;
1217  pixc[0] = Double( nx_-1 ) * 0.5 ;
1218  pixc[1] = Double( ny_-1 ) * 0.5 ;
1219//   pixc[0] = Double( nx_+2*convSupport_-1 ) * 0.5 ;
1220//   pixc[1] = Double( ny_+2*convSupport_-1 ) * 0.5 ;
1221  uInt nrow = world.shape()[1] ;
1222  Bool bw, bp ;
1223  const Double *w_p = world.getStorage( bw ) ;
1224  Double *p_p = pixel.getStorage( bp ) ;
1225  const Double *ww_p = w_p ;
1226  Double *wp_p = p_p ;
1227  for ( uInt i = 0 ; i < nrow ; i++ ) {
1228    *wp_p = pixc[0] + ( *ww_p - center_[0] ) / cellx_ ;
1229    wp_p++ ;
1230    ww_p++ ;
1231    *wp_p = pixc[1] + ( *ww_p - center_[1] ) / celly_ ;
1232    wp_p++ ;
1233    ww_p++ ;
1234  }
1235  world.freeStorage( w_p, bw ) ;
1236  pixel.putStorage( p_p, bp ) ; 
1237//   String gridfile = "grid."+convType_+"."+String::toString(convSupport_)+".dat" ;
1238//   ofstream ofs( gridfile.c_str(), ios::out ) ;
1239//   ofs << "center " << center_(0) << " " << pixc(0)
1240//       << " " << center_(1) << " " << pixc(1) << endl ;
1241//   for ( uInt irow = 0 ; irow < nrow ; irow++ ) {
1242//     ofs << irow ;
1243//     for ( uInt i = 0 ; i < 2 ; i++ ) {
1244//       ofs << " " << world(i, irow) << " " << pixel(i, irow) ;
1245//     }
1246//     ofs << endl ;
1247//   }
1248//   ofs.close() ;
1249}
1250
1251void STGrid::boxFunc( Vector<Float> &convFunc, Int &convSize )
1252{
1253  convFunc = 0.0 ;
1254  for ( Int i = 0 ; i < convSize/2 ; i++ )
1255    convFunc(i) = 1.0 ;
1256}
1257
1258#define NEED_UNDERSCORES
1259#if defined(NEED_UNDERSCORES)
1260#define grdsf grdsf_
1261#endif
1262extern "C" {
1263   void grdsf(Double*, Double*);
1264}
1265void STGrid::spheroidalFunc( Vector<Float> &convFunc )
1266{
1267  convFunc = 0.0 ;
1268  for ( Int i = 0 ; i < convSampling_*convSupport_ ; i++ ) {
1269    Double nu = Double(i) / Double(convSupport_*convSampling_) ;
1270    Double val ;
1271    grdsf( &nu, &val ) ;
1272    convFunc(i) = ( 1.0 - nu * nu ) * val ;
1273  }
1274}
1275
1276void STGrid::gaussFunc( Vector<Float> &convFunc )
1277{
1278  convFunc = 0.0 ;
1279  // HWHM of the Gaussian is convSupport_ / 4
1280  // To take into account Gaussian tail, kernel cutoff is set to 4 * HWHM
1281  Int len = convSampling_ * convSupport_ ;
1282  Double hwhm = len * 0.25 ;
1283  for ( Int i = 0 ; i < len ; i++ ) {
1284    Double val = Double(i) / hwhm ;
1285    convFunc(i) = exp( -log(2)*val*val ) ;
1286  }
1287}
1288
1289void STGrid::pbFunc( Vector<Float> &convFunc )
1290{
1291  convFunc = 0.0 ;
1292}
1293
1294void STGrid::setConvFunc( Vector<Float> &convFunc )
1295{
1296  convSupport_ = userSupport_ ;
1297  if ( convType_ == "BOX" ) {
1298    if ( convSupport_ < 0 )
1299      convSupport_ = 0 ;
1300    Int convSize = convSampling_ * ( 2 * convSupport_ + 2 )  ;
1301    convFunc.resize( convSize ) ;
1302    boxFunc( convFunc, convSize ) ;
1303  }
1304  else if ( convType_ == "SF" ) {
1305    if ( convSupport_ < 0 )
1306      convSupport_ = 3 ;
1307    Int convSize = convSampling_ * ( 2 * convSupport_ + 2 )  ;
1308    convFunc.resize( convSize ) ;
1309    spheroidalFunc( convFunc ) ;
1310  }
1311  else if ( convType_ == "GAUSS" ) {
1312    // to take into account Gaussian tail
1313    if ( convSupport_ < 0 )
1314      convSupport_ = 12 ; // 3 * 4
1315    else {
1316      convSupport_ = userSupport_ * 4 ;
1317    }
1318    Int convSize = convSampling_ * ( 2 * convSupport_ + 2 ) ;
1319    convFunc.resize( convSize ) ;
1320    gaussFunc( convFunc ) ;
1321  }
1322  else if ( convType_ == "PB" ) {
1323    if ( convSupport_ < 0 )
1324      convSupport_ = 0 ;
1325    pbFunc( convFunc ) ;
1326  }
1327  else {
1328    throw AipsError( "Unsupported convolution function" ) ;
1329  }
1330}
1331
1332string STGrid::saveData( string outfile )
1333{
1334  LogIO os( LogOrigin("STGrid", "saveData", WHERE) ) ;
1335  double t0, t1 ;
1336  t0 = mathutil::gettimeofday_sec() ;
1337
1338  //Int polno = 0 ;
1339  String outfile_ ;
1340  if ( outfile.size() == 0 ) {
1341    if ( infile_.lastchar() == '/' ) {
1342      outfile_ = infile_.substr( 0, infile_.size()-1 ) ;
1343    }
1344    else {
1345      outfile_ = infile_ ;
1346    }
1347    outfile_ += ".grid" ;
1348  }
1349  else {
1350    outfile_ = outfile ;
1351  }
1352  Table tab ;
1353  prepareTable( tab, outfile_ ) ;
1354  IPosition dshape = data_.shape() ;
1355  Int nrow = nx_ * ny_ * npol_ ;
1356  tab.rwKeywordSet().define( "nPol", npol_ ) ;
1357  tab.addRow( nrow ) ;
1358  Vector<Double> cpix( 2 ) ;
1359  cpix(0) = Double( nx_ - 1 ) * 0.5 ;
1360  cpix(1) = Double( ny_ - 1 ) * 0.5 ;
1361  Vector<Double> dir( 2 ) ;
1362  ArrayColumn<Double> directionCol( tab, "DIRECTION" ) ;
1363  ArrayColumn<Float> spectraCol( tab, "SPECTRA" ) ;
1364  ScalarColumn<uInt> polnoCol( tab, "POLNO" ) ;
1365  Int irow = 0 ;
1366  Vector<Float> sp( nchan_ ) ;
1367  Bool bsp, bdata ;
1368  const Float *data_p = data_.getStorage( bdata ) ;
1369  Float *wsp_p, *sp_p ;
1370  const Float *wdata_p = data_p ;
1371  long step = nx_ * ny_ * npol_ ;
1372  long offset ;
1373  for ( Int iy = 0 ; iy < ny_ ; iy++ ) {
1374    dir(1) = center_(1) - ( cpix(1) - (Double)iy ) * celly_ ;
1375    for ( Int ix = 0 ; ix < nx_ ; ix++ ) {
1376      dir(0) = center_(0) - ( cpix(0) - (Double)ix ) * cellx_ ;
1377      for ( Int ipol = 0 ; ipol < npol_ ; ipol++ ) {
1378        offset = ix + iy * nx_ + ipol * nx_ * ny_ ;
1379        //os << "offset = " << offset << LogIO::POST ;
1380        sp_p = sp.getStorage( bsp ) ;
1381        wsp_p = sp_p ;
1382        wdata_p = data_p + offset ;
1383        for ( Int ichan = 0 ; ichan < nchan_ ; ichan++ ) {
1384          *wsp_p = *wdata_p ;
1385          wsp_p++ ;
1386          wdata_p += step ;
1387        }
1388        sp.putStorage( sp_p, bsp ) ;
1389        spectraCol.put( irow, sp ) ;
1390        directionCol.put( irow, dir ) ;
1391        polnoCol.put( irow, pollist_[ipol] ) ;
1392        irow++ ;
1393      }
1394    }
1395  }
1396  data_.freeStorage( data_p, bdata ) ;
1397
1398  t1 = mathutil::gettimeofday_sec() ;
1399  os << "saveData: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
1400
1401  return outfile_ ;
1402}
1403
1404void STGrid::prepareTable( Table &tab, String &name )
1405{
1406  Table t( infile_, Table::Old ) ;
1407  t.deepCopy( name, Table::New, False, t.endianFormat(), True ) ;
1408  tab = Table( name, Table::Update ) ;
1409}
1410
1411void STGrid::sortData()
1412{
1413  LogIO os( LogOrigin("STGRid","sortData",WHERE) ) ;
1414  double t0, t1 ;
1415  t0 = mathutil::gettimeofday_sec() ;
1416  rows_.resize( npol_*nrow_ ) ;
1417  Table tab = tab_( tab_.col("POLNO").in(pollist_) ) ;
1418  Block<String> cols( 2 ) ;
1419  cols[0] = "TIME" ;
1420  cols[1] = "BEAMNO" ;
1421  TableIterator iter( tab, cols ) ;
1422  uInt idx = 0 ;
1423  while( !iter.pastEnd() ) {
1424    Table t = iter.table().sort( "POLNO" ) ;
1425    Vector<uInt> rows = t.rowNumbers() ;
1426    //os << "rows=" << rows << LogIO::POST ;
1427    for ( uInt i = 0 ; i < rows.nelements() ; i++ ) {
1428      rows_[idx] = rows[i] ;
1429      idx++ ;
1430    }
1431    iter.next() ;
1432  }
1433  t1 = mathutil::gettimeofday_sec() ;
1434  os << "sortData: elapsed time is " << t1-t0 << " sec" << LogIO::POST ;
1435  //os << "rows_ = " << rows_ << LogIO::POST ;
1436}
1437}
Note: See TracBrowser for help on using the repository browser.