source: trunk/src/STGrid.cpp @ 2381

Last change on this file since 2381 was 2381, checked in by Takeshi Nakazato, 12 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...

Defined STGrid::call_ggridsd.
Defined some temporary data storage.
Some test code is inserted but commented out so far.

File size: 39.7 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  sortData() ;
386
387  if ( npol_ > 1 ) {
388    LogIO os( LogOrigin("STGrid", "grid", WHERE) ) ;
389    os << LogIO::WARN << "STGrid doesn't support assigning polarization-dependent weight. Use averaged weight over polarization." << LogIO::POST ;
390  }
391 
392  if ( wtype_.compare("UNIFORM") != 0 &&
393       wtype_.compare("TINT") != 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    gridAll() ;
404  else
405    gridPerRow() ;
406}
407
408Bool STGrid::examine()
409{
410  // TODO: nchunk_ must be determined from nchan_, npol_, and (nx_,ny_)
411  //       by considering data size to be allocated for ggridsd input/output
412  nchunk_ = 100 ;
413  Bool b = nchunk_ >= nrow_ ;
414  nchunk_ = min( nchunk_, nrow_ ) ;
415  return b ;
416}
417
418void STGrid::gridAll()
419{
420  LogIO os( LogOrigin("STGrid", "gridAll", WHERE) ) ;
421
422  // retrieve data
423  Array<Complex> spectra ;
424  Array<Double> direction ;
425  Array<Int> flagtra ;
426  Array<Int> rflag ;
427  Array<Float> weight ;
428  double t0, t1 ;
429  t0 = mathutil::gettimeofday_sec() ;
430  getData( spectra, direction, flagtra, rflag, weight ) ;
431  t1 = mathutil::gettimeofday_sec() ;
432  os << "getData: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
433  IPosition sshape = spectra.shape() ;
434  //os << "spectra.shape()=" << spectra.shape() << LogIO::POST ;
435  //os << "max(spectra) = " << max(spectra) << LogIO::POST ;
436  //os << "weight = " << weight << LogIO::POST ;
437
438  // grid parameter
439  os << LogIO::DEBUGGING ;
440  os << "----------" << endl ;
441  os << "Grid parameter summary" << endl ;
442  os << "   (nx,ny) = (" << nx_ << "," << ny_ << ")" << endl ;
443  os << "   (cellx,celly) = (" << cellx_ << "," << celly_ << ")" << endl ;
444  os << "   center = " << center_ << endl ;
445  os << "----------" << LogIO::POST ;
446  os << LogIO::NORMAL ;
447
448  // convolution kernel
449  Vector<Float> convFunc ;
450  t0 = mathutil::gettimeofday_sec() ;
451  setConvFunc( convFunc ) ;
452  t1 = mathutil::gettimeofday_sec() ;
453  os << "setConvFunc: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
454  //cout << "convSupport=" << convSupport_ << endl ;
455  //cout << "convFunc=" << convFunc << endl ;
456
457  // world -> pixel
458  Array<Double> xypos( direction.shape(), 0.0 ) ;
459  t0 = mathutil::gettimeofday_sec() ;
460  toPixel( direction, xypos ) ; 
461  t1 = mathutil::gettimeofday_sec() ;
462  //os << "xypos=" << xypos << LogIO::POST ;
463  os << "toPixel: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
464 
465  // call ggridsd
466  Bool deletePos, deleteData, deleteWgt, deleteFlag, deleteFlagR, deleteConv, deleteDataG, deleteWgtG ;
467  Double *xypos_p = xypos.getStorage( deletePos ) ;
468  const Complex *data_p = spectra.getStorage( deleteData ) ;
469  const Float *wgt_p = weight.getStorage( deleteWgt ) ;
470  //const Int *flag_p = flagI.getStorage( deleteFlag ) ;
471  //const Int *rflag_p = rflagI.getStorage( deleteFlagR ) ;
472  const Int *flag_p = flagtra.getStorage( deleteFlag ) ;
473  const Int *rflag_p = rflag.getStorage( deleteFlagR ) ;
474  Float *conv_p = convFunc.getStorage( deleteConv ) ;
475  // Extend grid plane with convSupport_
476  Int gnx = nx_ ;
477  Int gny = ny_ ;
478//   Int gnx = nx_+convSupport_*2 ;
479//   Int gny = ny_+convSupport_*2 ;
480  IPosition gshape( 4, gnx, gny, npol_, nchan_ ) ;
481  Array<Complex> gdataArrC( gshape, 0.0 ) ;
482  //Array<Float> gwgtArr( gshape, 0.0 ) ;
483  // 2011/12/20 TN
484  // data_ and weight array shares storage
485  data_.resize( gshape ) ;
486  data_ = 0.0 ;
487  Array<Float> gwgtArr( data_ ) ;
488  Complex *gdata_p = gdataArrC.getStorage( deleteDataG ) ;
489  Float *wdata_p = gwgtArr.getStorage( deleteWgtG ) ;
490  Int *chanMap = new Int[nchan_] ;
491  {
492    Int *work_p = chanMap ;
493    for ( Int i = 0 ; i < nchan_ ; i++ ) {
494      *work_p = i ;
495      work_p++ ;
496    }
497  }
498  Int *polMap = new Int[npol_] ;
499  {
500    Int *work_p = polMap ;
501    for ( Int i = 0 ; i < npol_ ; i++ ) {
502      *work_p = i ;
503      work_p++ ;
504    }
505  }
506  t0 = mathutil::gettimeofday_sec() ;
507  Int irow = -1 ;
508  call_ggridsd( xypos_p,
509                data_p,
510                &npol_,
511                &nchan_,
512                flag_p,
513                rflag_p,
514                wgt_p,
515                &nrow_,
516                &irow,
517                gdata_p,
518                wdata_p,
519                &gnx,
520                &gny,
521                &npol_,
522                &nchan_,
523                &convSupport_,
524                &convSampling_,
525                conv_p,
526                chanMap,
527                polMap ) ;
528  t1 = mathutil::gettimeofday_sec() ;
529  os << "ggridsd: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
530  xypos.putStorage( xypos_p, deletePos ) ;
531  spectra.freeStorage( data_p, deleteData ) ;
532  weight.freeStorage( wgt_p, deleteWgt ) ;
533  flagtra.freeStorage( flag_p, deleteFlag ) ;
534  rflag.freeStorage( rflag_p, deleteFlagR ) ;
535  convFunc.putStorage( conv_p, deleteConv ) ;
536  delete polMap ;
537  delete chanMap ;
538  gdataArrC.putStorage( gdata_p, deleteDataG ) ;
539  gwgtArr.putStorage( wdata_p, deleteWgtG ) ;
540  setData( gdataArrC, gwgtArr ) ;
541  //Matrix<Double> sumWeight( IPosition( 2, npol_, nchan_ ), sumw_p, TAKE_OVER ) ;
542  //cout << "sumWeight = " << sumWeight << endl ;
543//   os << "gdataArr = " << gdataArr << LogIO::POST ;
544//   os << "gwgtArr = " << gwgtArr << LogIO::POST ;
545//   os << "data_ " << data_ << LogIO::POST ;
546}
547
548void STGrid::setData( Array<Complex> &gdata,
549                      Array<Float> &gwgt )
550{
551  // 2011/12/20 TN
552  // gwgt and data_ share storage
553  LogIO os( LogOrigin("STGrid","setData",WHERE) ) ;
554  double t0, t1 ;
555  t0 = mathutil::gettimeofday_sec() ;
556  uInt len = data_.nelements() ;
557  const Complex *w1_p ;
558  Float *w2_p ;
559  Bool b1, b2 ;
560  const Complex *gdata_p = gdata.getStorage( b1 ) ;
561  Float *gwgt_p = data_.getStorage( b2 ) ;
562  w1_p = gdata_p ;
563  w2_p = gwgt_p ;
564  for ( uInt i = 0 ; i < len ; i++ ) {
565    if ( *w2_p > 0.0 ) *w2_p = (*w1_p).real() / *w2_p ;
566    w1_p++ ;
567    w2_p++ ;
568  }
569  gdata.freeStorage( gdata_p, b1 ) ;
570  data_.putStorage( gwgt_p, b2 ) ;
571  t1 = mathutil::gettimeofday_sec() ;
572  os << "setData: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
573}
574
575void STGrid::setupGrid( Int &nx,
576                        Int &ny,
577                        String &cellx,
578                        String &celly,
579                        Double &xmin,
580                        Double &xmax,
581                        Double &ymin,
582                        Double &ymax,
583                        String &center )
584{
585  LogIO os( LogOrigin("STGrid","setupGrid",WHERE) ) ;
586  //cout << "nx=" << nx << ", ny=" << ny << endl ;
587
588  // center position
589  if ( center.size() == 0 ) {
590    center_(0) = 0.5 * ( xmin + xmax ) ;
591    center_(1) = 0.5 * ( ymin + ymax ) ;
592  }
593  else {
594    String::size_type pos0 = center.find( " " ) ;
595    if ( pos0 == String::npos ) {
596      throw AipsError( "bad string format in parameter center" ) ;
597    }
598    String::size_type pos1 = center.find( " ", pos0+1 ) ;
599    String typestr, xstr, ystr ;
600    if ( pos1 != String::npos ) {
601      typestr = center.substr( 0, pos0 ) ;
602      xstr = center.substr( pos0+1, pos1-pos0 ) ;
603      ystr = center.substr( pos1+1 ) ;
604      // todo: convert to J2000 (or direction ref for DIRECTION column)
605    }
606    else {
607      typestr = "J2000" ;
608      xstr = center.substr( 0, pos0 ) ;
609      ystr = center.substr( pos0+1 ) ;
610    }
611    QuantumHolder qh ;
612    String err ;
613    qh.fromString( err, xstr ) ;
614    Quantum<Double> xcen = qh.asQuantumDouble() ;
615    qh.fromString( err, ystr ) ;
616    Quantum<Double> ycen = qh.asQuantumDouble() ;
617    center_(0) = xcen.getValue( "rad" ) ;
618    center_(1) = ycen.getValue( "rad" ) ;
619  }
620
621
622  nx_ = nx ;
623  ny_ = ny ;
624  if ( nx < 0 && ny > 0 ) {
625    nx_ = ny ;
626    ny_ = ny ;
627  }
628  if ( ny < 0 && nx > 0 ) {
629    nx_ = nx ;
630    ny_ = nx ;
631  }
632
633  //Double wx = xmax - xmin ;
634  //Double wy = ymax - ymin ;
635  Double wx = max( abs(xmax-center_(0)), abs(xmin-center_(0)) ) * 2 ;
636  Double wy = max( abs(ymax-center_(1)), abs(ymin-center_(1)) ) * 2 ;
637  // take 10% margin
638  wx *= 1.10 ;
639  wy *= 1.10 ;
640
641  Quantum<Double> qcellx ;
642  Quantum<Double> qcelly ;
643  //cout << "nx_ = " << nx_ << ",  ny_ = " << ny_ << endl ;
644  if ( cellx.size() != 0 && celly.size() != 0 ) {
645    readQuantity( qcellx, cellx ) ;
646    readQuantity( qcelly, celly ) ;
647  }
648  else if ( celly.size() != 0 ) {
649    os << "Using celly to x-axis..." << LogIO::POST ;
650    readQuantity( qcelly, celly ) ;
651    qcellx = qcelly ;
652  }
653  else if ( cellx.size() != 0 ) {
654    os << "Using cellx to y-axis..." << LogIO::POST ;
655    readQuantity( qcellx, cellx ) ;
656    qcelly = qcellx ;
657  }
658  else {
659    if ( nx_ < 0 ) {
660      os << "No user preference in grid setting. Using default..." << LogIO::POST ;
661      readQuantity( qcellx, "1.0arcmin" ) ;
662      qcelly = qcellx ;
663    }
664    else {
665      if ( wx == 0.0 ) {
666        os << "Using default spatial extent (10arcmin) in x" << LogIO::POST ;
667        wx = 0.00290888 ;
668      }
669      if ( wy == 0.0 ) {
670        os << "Using default spatial extent (10arcmin) in y" << LogIO::POST ;
671        wy = 0.00290888 ;
672      }
673      qcellx = Quantum<Double>( wx/nx_, "rad" ) ;
674      qcelly = Quantum<Double>( wy/ny_, "rad" ) ;
675    }
676  }
677  cellx_ = qcellx.getValue( "rad" ) ;
678  celly_ = qcelly.getValue( "rad" ) ;
679  if ( nx_ < 0 ) {
680    if ( wx == 0.0 ) {
681      os << "Using default spatial extent (10arcmin) in x" << LogIO::POST ;
682      wx = 0.00290888 ;
683    }
684    if ( wy == 0.0 ) {
685      os << "Using default spatial extent (10arcmin) in y" << LogIO::POST ;
686      wy = 0.00290888 ;
687    }
688    nx_ = Int( ceil( wx/cellx_ ) ) ;
689    ny_ = Int( ceil( wy/celly_ ) ) ;
690  }
691}
692
693void STGrid::selectData()
694{
695  Int ifno = ifno_ ;
696  Table taborg( infile_ ) ;
697  if ( ifno == -1 ) {
698    LogIO os( LogOrigin("STGrid","selectData",WHERE) ) ;
699//     os << LogIO::SEVERE
700//        << "Please set IFNO before actual gridding"
701//        << LogIO::EXCEPTION ;
702    ROScalarColumn<uInt> ifnoCol( taborg, "IFNO" ) ;
703    ifno = ifnoCol( 0 ) ;
704    os << LogIO::WARN
705       << "IFNO is not given. Using default IFNO: " << ifno << LogIO::POST ;
706  }
707//   tab = taborg( taborg.col("IFNO") == ifno ) ;
708  TableExprNode node ;
709  node = taborg.col("IFNO") == ifno ;
710  if ( scanlist_.size() > 0 ) {
711    node = node && taborg.col("SCANNO").in( scanlist_ ) ;
712  }
713  tab_ = taborg( node ) ;
714  if ( tab_.nrow() == 0 ) {
715    LogIO os( LogOrigin("STGrid","selectData",WHERE) ) ;
716    os << LogIO::SEVERE
717       << "No corresponding rows for given selection: IFNO " << ifno ;
718    if ( scanlist_.size() > 0 )
719      os << " SCANNO " << scanlist_ ;
720    os << LogIO::EXCEPTION ;
721  }
722  attach() ;
723}
724
725void STGrid::attach()
726{
727  // attach to table
728  spectraCol_.attach( tab_, "SPECTRA" ) ;
729  flagtraCol_.attach( tab_, "FLAGTRA" ) ;
730  directionCol_.attach( tab_, "DIRECTION" ) ;
731  flagRowCol_.attach( tab_, "FLAGROW" ) ;
732  tsysCol_.attach( tab_, "TSYS" ) ;
733  intervalCol_.attach( tab_, "INTERVAL" ) ;
734//   Vector<String> colnames( 6 ) ;
735//   colnames[0] = "SPECTRA" ;
736//   colnames[1] = "FLAGTRA" ;
737//   colnames[2] = "DIRECTION" ;
738//   colnames[3] = "FLAGROW" ;
739//   colnames[4] = "TSYS" ;
740//   colnames[5] = "INTERVAL" ;
741//   row_ = ROTableRow( tab_, colnames ) ;
742//   const TableRecord &rec = row_.record() ;
743//   spectraRF_.attachToRecord( rec, colnames[0] ) ;
744//   flagtraRF_.attachToRecord( rec, colnames[1] ) ;
745//   directionRF_.attachToRecord( rec, colnames[2] ) ;
746//   flagRowRF_.attachToRecord( rec, colnames[3] ) ;
747//   tsysRF_.attachToRecord( rec, colnames[4] ) ;
748//   intervalRF_.attachToRecord( rec, colnames[5] ) ;
749}
750
751void STGrid::getData( Array<Complex> &spectra,
752                      Array<Double> &direction,
753                      Array<uChar> &flagtra,
754                      Array<uInt> &rflag,
755                      Array<Float> &weight )
756{
757  LogIO os( LogOrigin("STGrid","getData",WHERE) ) ;
758//   os << "start" << LogIO::POST ;
759//   os << "npol_ = " << npol_ << LogIO::POST ;
760//   os << "nchan_ = " << nchan_ << LogIO::POST ;
761//   os << "nrow_ = " << nrow_ << LogIO::POST ;
762  IPosition cshape( 3, npol_, nchan_, nrow_ ) ;
763  IPosition mshape( 2, npol_, nrow_ ) ;
764  IPosition vshape( 1, nrow_ ) ;
765  spectra.resize( cshape ) ;
766  flagtra.resize( cshape ) ;
767  rflag.resize( vshape ) ;
768  Vector<uInt> rflagPerPol( rflag ) ;
769  direction.resize( IPosition(2,2,nrow_) ) ;
770  Array<Float> tsys( cshape ) ;
771  Array<Double> tint( mshape ) ;
772
773  ArrayIterator<uChar> fli( flagtra, IPosition(2,1,2) ) ;
774  ArrayIterator<Float> tsi( tsys, IPosition(2,1,2) ) ;
775  ArrayIterator<Double> tii( tint, IPosition(1,1) ) ;
776 
777  // boolean for pointer access
778  Bool bsp, bsps ;
779  // pointer to the data
780  Complex *sp_p = spectra.getStorage( bsp ) ;
781  // working pointer
782  Complex *wsp_p = sp_p ;
783  uInt len = nchan_ * nrow_ ;
784  IPosition mshape2( 2, nchan_, nrow_ ) ;
785  Vector<Float> spSlice( nchan_ ) ;
786  const Float *sps_p = spSlice.getStorage( bsps ) ;
787  long cincr = npol_ ;
788  long rincr = npol_ * nchan_ ;
789  for ( Int ipol = 0 ; ipol < npol_ ; ipol++ ) {
790    Table subt = tab_( tab_.col("POLNO") == pollist_[ipol] ) ;
791    ROArrayColumn<Float> spectraCol( subt, "SPECTRA" ) ;
792    ROArrayColumn<Double> directionCol( subt, "DIRECTION" ) ;
793    ROArrayColumn<uChar> flagtraCol( subt, "FLAGTRA" ) ;
794    ROScalarColumn<uInt> rflagCol( subt, "FLAGROW" ) ;
795    ROArrayColumn<Float> tsysCol( subt, "TSYS" ) ;
796    ROScalarColumn<Double> tintCol( subt, "INTERVAL" ) ;
797    for ( Int irow = 0 ; irow < nrow_ ; irow++ ) {
798      spectraCol.get( irow, spSlice ) ;
799      const Float *wsps_p = sps_p ;
800      wsp_p = sp_p + (long)ipol + rincr * (long)irow ;
801      for ( Int ichan = 0 ; ichan < nchan_ ; ichan++ ) {
802        *wsp_p = *wsps_p ;
803        wsps_p++ ;
804        wsp_p += cincr ;
805      }
806    }
807    Array<uChar> flSlice = fli.array() ;
808    flagtraCol.getColumn( flSlice ) ;
809    if ( ipol == 0 ) {
810      directionCol.getColumn( direction ) ;
811      rflagCol.getColumn( rflagPerPol ) ;
812    }
813    else {
814      rflagPerPol += rflagCol.getColumn() ;
815    }
816    Vector<Float> tmpF = tsysCol( 0 ) ;
817    Array<Float> tsSlice = tsi.array() ;
818    if ( tmpF.nelements() == (uInt)nchan_ ) {
819      tsysCol.getColumn( tsSlice ) ;
820    }
821    else {
822      tsSlice = tmpF( 0 ) ;
823    }
824    Vector<Double> tmpD = tii.array() ;
825    tintCol.getColumn( tmpD ) ;
826
827    wsp_p += len ;
828
829    fli.next() ;
830    tsi.next() ;
831    tii.next() ;
832  }
833  spSlice.freeStorage( sps_p, bsps ) ;
834  spectra.putStorage( sp_p, bsp ) ;
835
836//   os << "spectra=" << spectra << LogIO::POST ;
837//   os << "flagtra=" << flagtra << LogIO::POST ;
838//   os << "rflag=" << rflag << LogIO::POST ;
839//   os << "direction=" << direction << LogIO::POST ;
840
841  weight.resize( IPosition(2,nchan_,nrow_) ) ;
842  getWeight( weight, tsys, tint ) ;
843}
844
845void STGrid::getData( Array<Complex> &spectra,
846                      Array<Double> &direction,
847                      Array<Int> &flagtra,
848                      Array<Int> &rflag,
849                      Array<Float> &weight )
850{
851  LogIO os( LogOrigin("STGrid","getData",WHERE) ) ;
852  double t0, t1 ;
853
854  Array<uChar> flagUC ;
855  Array<uInt> rflagUI ;
856  getData( spectra, direction, flagUC, rflagUI, weight ) ;
857
858  t0 = mathutil::gettimeofday_sec() ;
859  toInt( flagUC, flagtra ) ;
860  toInt( rflagUI, rflag ) ;
861  t1 = mathutil::gettimeofday_sec() ;
862  os << "toInt: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
863}
864
865Int STGrid::getDataChunk( Array<Complex> &spectra,
866                          Array<Double> &direction,
867                          Array<Int> &flagtra,
868                          Array<Int> &rflag,
869                          Array<Float> &weight )
870{
871  Int nrow = getDataChunk( spectraF_, direction, flagtraUC_, rflagUI_, weight ) ;
872  double t0, t1 ;
873  t0 = mathutil::gettimeofday_sec() ;
874  convertArray( spectra, spectraF_ ) ;
875  convertArray( flagtra, flagtraUC_ ) ;
876  convertArray( rflag, rflagUI_ ) ;
877  t1 = mathutil::gettimeofday_sec() ;
878  subtime_ = t1 - t0 ;
879 
880  return nrow ;
881}
882
883Int STGrid::getDataChunk( Array<Float> &spectra,
884                          Array<Double> &direction,
885                          Array<uChar> &flagtra,
886                          Array<uInt> &rflag,
887                          Array<Float> &weight )
888{
889  LogIO os( LogOrigin("STGrid","getDataChunk",WHERE) ) ;
890  Int nrow = min( spectra.shape()[2], nrow_-nprocessed_ ) ;
891  Array<Float> tsys( spectra.shape() ) ;
892  Array<Double> tint( IPosition(2,spectra.shape()[0],spectra.shape()[2]) ) ;
893  IPosition m( 2, 0, 2 ) ;
894  IPosition v( 1, 0 ) ;
895  ArrayIterator<Float> spi( spectra, m, False ) ;
896  ArrayIterator<uChar> fli( flagtra, m, False ) ;
897  ArrayIterator<Float> tsi( tsys, m, False ) ;
898  ArrayIterator<Double> di( direction, v ) ;
899  Bool bfr, bti ;
900  uInt *fr_p = rflag.getStorage( bfr ) ;
901  Double *ti_p = tint.getStorage( bti ) ;
902  uInt *wfr_p = fr_p ;
903  Double *wti_p = ti_p ;
904  Int offset = nprocessed_ * npol_ ;
905  Int start = offset ;
906  Int end = start + nrow * npol_ ;
907  for ( Int irow = 0 ; irow < npol_ * nrow ; irow++ ) {
908    Array<Float> spSlice = spi.array() ;
909    Array<uChar> flSlice = fli.array() ;
910    Array<Float> tsSlice = tsi.array() ;
911
912    uInt idx = rows_[offset+irow] ;
913    spectraCol_.get( idx, spSlice ) ;
914
915    flagtraCol_.get( idx, flSlice ) ;
916    Vector<Float> tmpF = tsysCol_( idx ) ;
917    if ( tmpF.nelements() == (uInt)nchan_ ) {
918      tsSlice = tmpF ;
919    }
920    else {
921      tsSlice = tmpF[0] ;
922    }
923    *wti_p = intervalCol_( idx ) ;
924
925    spi.next() ;
926    fli.next() ;
927    tsi.next() ;
928    wti_p++ ;
929  }
930  tint.putStorage( ti_p, bti ) ;
931  for ( Int irow = 0 ; irow < nrow ; irow += npol_ ) {
932    uInt idx = rows_[offset+irow] ;
933    directionCol_.get( idx, di.array() ) ;
934    di.next() ;
935
936    *wfr_p = flagRowCol_( idx ) ;
937    for ( Int ipol = 1 ; ipol < npol_ ; ipol++ ) {
938      *wfr_p = max( *wfr_p, flagRowCol_( rows_[offset+irow+ipol] ) ) ;
939    }
940    wfr_p++ ;
941  }
942  rflag.putStorage( fr_p, bfr ) ;
943//   Bool bti, bfr ;
944//   Double *ti_p = tint.getStorage( bti ) ;
945//   Double *wti_p = ti_p ;
946//   uInt *fr_p = rflag.getStorage( bfr ) ;
947//   uInt *wfr_p = fr_p - 1 ;
948//   Int start = nprocessed_ * npol_ ;
949//   Int end = start + nrow * npol_ ;
950//   for ( Int irow = start ; irow < end ; irow++ ) {
951//     uInt idx = rows_[irow] ;
952//     row_.get( idx ) ;
953//     // SPECTRA
954// //     os << "spi.array().shape()=" << spi.array().shape() << LogIO::POST ;
955// //     os << "(*spectraRF_).shape()=" << (*spectraRF_).shape() << LogIO::POST ;
956//     spi.array() = *spectraRF_ ;
957   
958//     // FLAGTRA
959//     fli.array() = *flagtraRF_ ;
960
961//     // INTERVAL
962//     *wti_p = *intervalRF_ ;
963
964//     // TSYS
965// //     os << "tsi.array().shape()=" << tsi.array().shape() << LogIO::POST ;
966// //     os << "(*tsysRF_).shape()=" << (*tsysRF_).shape() << LogIO::POST ;
967// //     os << "(*tsysRF_).nelements()=" << (*tsysRF_).nelements() << LogIO::POST ;
968//     if ( (*tsysRF_).nelements() == (uInt)nchan_ )
969//       tsi.array() = *tsysRF_ ;
970//     else
971//       tsi.array() = *((*tsysRF_).data()) ;
972
973//     // DIRECTION and FLAGROW
974//     Int mod = irow % npol_ ;
975//     if ( mod == 0 ) {
976// //       os << "di.array().shape()=" << di.array().shape() << LogIO::POST ;
977// //       os << "(*directionRF_).shape()=" << (*directionRF_).shape() << LogIO::POST ;
978//       di.array() = *directionRF_ ;
979//       wfr_p++ ;
980//       *wfr_p = *flagRowRF_ ;
981//     }
982//     else {
983//       *wfr_p += *flagRowRF_ ;
984//     }
985   
986//     // increment
987//     spi.next() ;
988//     fli.next() ;
989//     tsi.next() ;
990//     di.next() ;
991//     *wti_p++ ;
992//   }
993//   tint.putStorage( ti_p, bti ) ;
994//   rflag.putStorage( fr_p, bfr ) ;
995
996  getWeight( weight, tsys, tint ) ;
997
998  nprocessed_ += nrow ;
999 
1000  return nrow ;
1001}
1002
1003void STGrid::setupArray()
1004{
1005  LogIO os( LogOrigin("STGrid","setupArray",WHERE) ) ;
1006  ROScalarColumn<uInt> polnoCol( tab_, "POLNO" ) ;
1007  Vector<uInt> pols = polnoCol.getColumn() ;
1008  //os << pols << LogIO::POST ;
1009  Vector<uInt> pollistOrg ;
1010  uInt npolOrg = 0 ;
1011  uInt polno ;
1012  for ( uInt i = 0 ; i < polnoCol.nrow() ; i++ ) {
1013    //polno = polnoCol( i ) ;
1014    polno = pols( i ) ;
1015    if ( allNE( pollistOrg, polno ) ) {
1016      pollistOrg.resize( npolOrg+1, True ) ;
1017      pollistOrg[npolOrg] = polno ;
1018      npolOrg++ ;
1019    }
1020  }
1021  if ( pollist_.size() == 0 )
1022    pollist_ = pollistOrg ;
1023  else {
1024    Vector<uInt> newlist ;
1025    uInt newsize = 0 ;
1026    for ( uInt i = 0 ; i < pollist_.size() ; i++ ) {
1027      if ( anyEQ( pollistOrg, pollist_[i] ) ) {
1028        newlist.resize( newsize+1, True ) ;
1029        newlist[newsize] = pollist_[i] ;
1030        newsize++ ;
1031      }
1032    }
1033    pollist_.assign( newlist ) ;
1034  }
1035  npol_ = pollist_.size() ;
1036  if ( npol_ == 0 ) {
1037    os << LogIO::SEVERE << "Empty pollist" << LogIO::EXCEPTION ;
1038  }
1039  nrow_ = tab_.nrow() / npolOrg ;
1040  ROArrayColumn<uChar> tmpCol( tab_, "FLAGTRA" ) ;
1041  nchan_ = tmpCol( 0 ).nelements() ;
1042//   os << "npol_ = " << npol_ << "(" << pollist_ << ")" << endl
1043//      << "nchan_ = " << nchan_ << endl
1044//      << "nrow_ = " << nrow_ << LogIO::POST ;
1045}
1046
1047void STGrid::getWeight( Array<Float> &w,
1048                        Array<Float> &tsys,
1049                        Array<Double> &tint )
1050{
1051  LogIO os( LogOrigin("STGrid","getWeight",WHERE) ) ;
1052//   double t0, t1 ;
1053//   t0 = mathutil::gettimeofday_sec() ;
1054  // resize
1055  IPosition refShape = tsys.shape() ;
1056  Int nchan = refShape[1] ;
1057  Int nrow = refShape[2] ;
1058
1059  // set weight
1060  if ( wtype_.compare( "UNIFORM" ) == 0 ) {
1061    w = 1.0 ;
1062  }
1063  else if ( wtype_.compare( "TINT" ) == 0 ) {
1064    Bool b0, b1 ;
1065    Float *w_p = w.getStorage( b0 ) ;
1066    Float *w0_p = w_p ;
1067    const Double *ti_p = tint.getStorage( b1 ) ;
1068    const Double *w1_p = ti_p ;
1069    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1070      Float val = (Float)(polMean( w1_p )) ;
1071      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1072        *w0_p = val ;
1073        w0_p++ ;
1074      }
1075    }
1076    w.putStorage( w_p, b0 ) ;
1077    tint.freeStorage( ti_p, b1 ) ;
1078  }
1079  else if ( wtype_.compare( "TSYS" ) == 0 ) {
1080    Bool b0, b1 ;
1081    Float *w_p = w.getStorage( b0 ) ;
1082    Float *w0_p = w_p ;
1083    const Float *ts_p = tsys.getStorage( b1 ) ;
1084    const Float *w1_p = ts_p ;
1085    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1086      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1087        Float val = polMean( w1_p ) ;
1088        *w0_p = 1.0 / ( val * val ) ;
1089        w0_p++ ;
1090      }
1091    }
1092    w.putStorage( w_p, b0 ) ;
1093    tsys.freeStorage( ts_p, b1 ) ;
1094  }
1095  else if ( wtype_.compare( "TINTSYS" ) == 0 ) {
1096    Bool b0, b1, b2 ;
1097    Float *w_p = w.getStorage( b0 ) ;
1098    Float *w0_p = w_p ;
1099    const Double *ti_p = tint.getStorage( b1 ) ;
1100    const Double *w1_p = ti_p ;
1101    const Float *ts_p = tsys.getStorage( b2 ) ;
1102    const Float *w2_p = ts_p ;
1103    for ( Int irow = 0 ; irow < nrow ; irow++ ) {
1104      Float interval = (Float)(polMean( w1_p )) ;
1105      for ( Int ichan = 0 ; ichan < nchan ; ichan++ ) {
1106        Float temp = polMean( w2_p ) ;
1107        *w0_p = interval / ( temp * temp ) ;
1108        w0_p++ ;
1109      }
1110    }
1111    w.putStorage( w_p, b0 ) ;
1112    tint.freeStorage( ti_p, b1 ) ;
1113    tsys.freeStorage( ts_p, b2 ) ;
1114  }
1115  else {
1116    //LogIO os( LogOrigin("STGrid", "getWeight", WHERE) ) ;
1117    //os << LogIO::WARN << "Unsupported weight type '" << wtype_ << "', apply UNIFORM weight" << LogIO::POST ;
1118    w = 1.0 ;
1119  }
1120
1121//   t1 = mathutil::gettimeofday_sec() ;
1122//   os << "getWeight: elapsed time is " << t1-t0 << " sec" << LogIO::POST ;
1123}
1124
1125Float STGrid::polMean( const Float *p )
1126{
1127  Float v = 0.0 ;
1128  for ( Int i = 0 ; i < npol_ ; i++ ) {
1129    v += *p ;
1130    p++ ;
1131  }
1132  v /= npol_ ;
1133  return v ;
1134}
1135
1136Double STGrid::polMean( const Double *p )
1137{
1138  Double v = 0.0 ;
1139  for ( Int i = 0 ; i < npol_ ; i++ ) {
1140    v += *p ;
1141    p++ ;
1142  }
1143  v /= npol_ ;
1144  return v ;
1145}
1146
1147void STGrid::toInt( Array<uChar> &u, Array<Int> &v )
1148{
1149  uInt len = u.nelements() ;
1150  Int *int_p = new Int[len] ;
1151  Bool deleteIt ;
1152  const uChar *data_p = u.getStorage( deleteIt ) ;
1153  Int *i_p = int_p ;
1154  const uChar *u_p = data_p ;
1155  for ( uInt i = 0 ; i < len ; i++ ) {
1156    *i_p = ( *u_p == 0 ) ? 0 : 1 ;
1157    i_p++ ;
1158    u_p++ ;
1159  }
1160  u.freeStorage( data_p, deleteIt ) ;
1161  v.takeStorage( u.shape(), int_p, TAKE_OVER ) ;
1162}
1163
1164void STGrid::toInt( Array<uInt> &u, Array<Int> &v )
1165{
1166  uInt len = u.nelements() ;
1167  Int *int_p = new Int[len] ;
1168  Bool deleteIt ;
1169  const uInt *data_p = u.getStorage( deleteIt ) ;
1170  Int *i_p = int_p ;
1171  const uInt *u_p = data_p ;
1172  for ( uInt i = 0 ; i < len ; i++ ) {
1173    *i_p = ( *u_p == 0 ) ? 0 : 1 ;
1174    i_p++ ;
1175    u_p++ ;
1176  }
1177  u.freeStorage( data_p, deleteIt ) ;
1178  v.takeStorage( u.shape(), int_p, TAKE_OVER ) ;
1179}
1180
1181void STGrid::toPixel( Array<Double> &world, Array<Double> &pixel )
1182{
1183  // gridding will be done on (nx_+2*convSupport_) x (ny_+2*convSupport_)
1184  // grid plane to avoid unexpected behavior on grid edge
1185  Block<Double> pixc( 2 ) ;
1186  pixc[0] = Double( nx_-1 ) * 0.5 ;
1187  pixc[1] = Double( ny_-1 ) * 0.5 ;
1188//   pixc[0] = Double( nx_+2*convSupport_-1 ) * 0.5 ;
1189//   pixc[1] = Double( ny_+2*convSupport_-1 ) * 0.5 ;
1190  uInt nrow = world.shape()[1] ;
1191  Bool bw, bp ;
1192  const Double *w_p = world.getStorage( bw ) ;
1193  Double *p_p = pixel.getStorage( bp ) ;
1194  const Double *ww_p = w_p ;
1195  Double *wp_p = p_p ;
1196  for ( uInt i = 0 ; i < nrow ; i++ ) {
1197    *wp_p = pixc[0] + ( *ww_p - center_[0] ) / cellx_ ;
1198    wp_p++ ;
1199    ww_p++ ;
1200    *wp_p = pixc[1] + ( *ww_p - center_[1] ) / celly_ ;
1201    wp_p++ ;
1202    ww_p++ ;
1203  }
1204  world.freeStorage( w_p, bw ) ;
1205  pixel.putStorage( p_p, bp ) ; 
1206//   String gridfile = "grid."+convType_+"."+String::toString(convSupport_)+".dat" ;
1207//   ofstream ofs( gridfile.c_str(), ios::out ) ;
1208//   ofs << "center " << center_(0) << " " << pixc(0)
1209//       << " " << center_(1) << " " << pixc(1) << endl ;
1210//   for ( uInt irow = 0 ; irow < nrow ; irow++ ) {
1211//     ofs << irow ;
1212//     for ( uInt i = 0 ; i < 2 ; i++ ) {
1213//       ofs << " " << world(i, irow) << " " << pixel(i, irow) ;
1214//     }
1215//     ofs << endl ;
1216//   }
1217//   ofs.close() ;
1218}
1219
1220void STGrid::boxFunc( Vector<Float> &convFunc, Int &convSize )
1221{
1222  convFunc = 0.0 ;
1223  for ( Int i = 0 ; i < convSize/2 ; i++ )
1224    convFunc(i) = 1.0 ;
1225}
1226
1227#define NEED_UNDERSCORES
1228#if defined(NEED_UNDERSCORES)
1229#define grdsf grdsf_
1230#endif
1231extern "C" {
1232   void grdsf(Double*, Double*);
1233}
1234void STGrid::spheroidalFunc( Vector<Float> &convFunc )
1235{
1236  convFunc = 0.0 ;
1237  for ( Int i = 0 ; i < convSampling_*convSupport_ ; i++ ) {
1238    Double nu = Double(i) / Double(convSupport_*convSampling_) ;
1239    Double val ;
1240    grdsf( &nu, &val ) ;
1241    convFunc(i) = ( 1.0 - nu * nu ) * val ;
1242  }
1243}
1244
1245void STGrid::gaussFunc( Vector<Float> &convFunc )
1246{
1247  convFunc = 0.0 ;
1248  // HWHM of the Gaussian is convSupport_ / 4
1249  // To take into account Gaussian tail, kernel cutoff is set to 4 * HWHM
1250  Int len = convSampling_ * convSupport_ ;
1251  Double hwhm = len * 0.25 ;
1252  for ( Int i = 0 ; i < len ; i++ ) {
1253    Double val = Double(i) / hwhm ;
1254    convFunc(i) = exp( -log(2)*val*val ) ;
1255  }
1256}
1257
1258void STGrid::pbFunc( Vector<Float> &convFunc )
1259{
1260  convFunc = 0.0 ;
1261}
1262
1263void STGrid::setConvFunc( Vector<Float> &convFunc )
1264{
1265  convSupport_ = userSupport_ ;
1266  if ( convType_ == "BOX" ) {
1267    if ( convSupport_ < 0 )
1268      convSupport_ = 0 ;
1269    Int convSize = convSampling_ * ( 2 * convSupport_ + 2 )  ;
1270    convFunc.resize( convSize ) ;
1271    boxFunc( convFunc, convSize ) ;
1272  }
1273  else if ( convType_ == "SF" ) {
1274    if ( convSupport_ < 0 )
1275      convSupport_ = 3 ;
1276    Int convSize = convSampling_ * ( 2 * convSupport_ + 2 )  ;
1277    convFunc.resize( convSize ) ;
1278    spheroidalFunc( convFunc ) ;
1279  }
1280  else if ( convType_ == "GAUSS" ) {
1281    // to take into account Gaussian tail
1282    if ( convSupport_ < 0 )
1283      convSupport_ = 12 ; // 3 * 4
1284    else {
1285      convSupport_ = userSupport_ * 4 ;
1286    }
1287    Int convSize = convSampling_ * ( 2 * convSupport_ + 2 ) ;
1288    convFunc.resize( convSize ) ;
1289    gaussFunc( convFunc ) ;
1290  }
1291  else if ( convType_ == "PB" ) {
1292    if ( convSupport_ < 0 )
1293      convSupport_ = 0 ;
1294    pbFunc( convFunc ) ;
1295  }
1296  else {
1297    throw AipsError( "Unsupported convolution function" ) ;
1298  }
1299}
1300
1301string STGrid::saveData( string outfile )
1302{
1303  LogIO os( LogOrigin("STGrid", "saveData", WHERE) ) ;
1304  double t0, t1 ;
1305  t0 = mathutil::gettimeofday_sec() ;
1306
1307  //Int polno = 0 ;
1308  String outfile_ ;
1309  if ( outfile.size() == 0 ) {
1310    if ( infile_.lastchar() == '/' ) {
1311      outfile_ = infile_.substr( 0, infile_.size()-1 ) ;
1312    }
1313    else {
1314      outfile_ = infile_ ;
1315    }
1316    outfile_ += ".grid" ;
1317  }
1318  else {
1319    outfile_ = outfile ;
1320  }
1321  Table tab ;
1322  prepareTable( tab, outfile_ ) ;
1323  IPosition dshape = data_.shape() ;
1324  Int nrow = nx_ * ny_ * npol_ ;
1325  tab.rwKeywordSet().define( "nPol", npol_ ) ;
1326  tab.addRow( nrow ) ;
1327  Vector<Double> cpix( 2 ) ;
1328  cpix(0) = Double( nx_ - 1 ) * 0.5 ;
1329  cpix(1) = Double( ny_ - 1 ) * 0.5 ;
1330  Vector<Double> dir( 2 ) ;
1331  ArrayColumn<Double> directionCol( tab, "DIRECTION" ) ;
1332  ArrayColumn<Float> spectraCol( tab, "SPECTRA" ) ;
1333  ScalarColumn<uInt> polnoCol( tab, "POLNO" ) ;
1334  Int irow = 0 ;
1335  Vector<Float> sp( nchan_ ) ;
1336  Bool bsp, bdata ;
1337  const Float *data_p = data_.getStorage( bdata ) ;
1338  Float *wsp_p, *sp_p ;
1339  const Float *wdata_p = data_p ;
1340  long step = nx_ * ny_ * npol_ ;
1341  long offset ;
1342  for ( Int iy = 0 ; iy < ny_ ; iy++ ) {
1343    dir(1) = center_(1) - ( cpix(1) - (Double)iy ) * celly_ ;
1344    for ( Int ix = 0 ; ix < nx_ ; ix++ ) {
1345      dir(0) = center_(0) - ( cpix(0) - (Double)ix ) * cellx_ ;
1346      for ( Int ipol = 0 ; ipol < npol_ ; ipol++ ) {
1347        offset = ix + iy * nx_ + ipol * nx_ * ny_ ;
1348        //os << "offset = " << offset << LogIO::POST ;
1349        sp_p = sp.getStorage( bsp ) ;
1350        wsp_p = sp_p ;
1351        wdata_p = data_p + offset ;
1352        for ( Int ichan = 0 ; ichan < nchan_ ; ichan++ ) {
1353          *wsp_p = *wdata_p ;
1354          wsp_p++ ;
1355          wdata_p += step ;
1356        }
1357        sp.putStorage( sp_p, bsp ) ;
1358        spectraCol.put( irow, sp ) ;
1359        directionCol.put( irow, dir ) ;
1360        polnoCol.put( irow, pollist_[ipol] ) ;
1361        irow++ ;
1362      }
1363    }
1364  }
1365  data_.freeStorage( data_p, bdata ) ;
1366
1367  t1 = mathutil::gettimeofday_sec() ;
1368  os << "saveData: elapsed time is " << t1-t0 << " sec." << LogIO::POST ;
1369
1370  return outfile_ ;
1371}
1372
1373void STGrid::prepareTable( Table &tab, String &name )
1374{
1375  Table t( infile_, Table::Old ) ;
1376  t.deepCopy( name, Table::New, False, t.endianFormat(), True ) ;
1377  tab = Table( name, Table::Update ) ;
1378}
1379
1380void STGrid::sortData()
1381{
1382  LogIO os( LogOrigin("STGRid","sortData",WHERE) ) ;
1383  double t0, t1 ;
1384  t0 = mathutil::gettimeofday_sec() ;
1385  rows_.resize( npol_*nrow_ ) ;
1386  Table tab = tab_( tab_.col("POLNO").in(pollist_) ) ;
1387  Block<String> cols( 2 ) ;
1388  cols[0] = "TIME" ;
1389  cols[1] = "BEAMNO" ;
1390  TableIterator iter( tab, cols ) ;
1391  uInt idx = 0 ;
1392  while( !iter.pastEnd() ) {
1393    Table t = iter.table().sort( "POLNO" ) ;
1394    Vector<uInt> rows = t.rowNumbers() ;
1395    //os << "rows=" << rows << LogIO::POST ;
1396    for ( uInt i = 0 ; i < rows.nelements() ; i++ ) {
1397      rows_[idx] = rows[i] ;
1398      idx++ ;
1399    }
1400    iter.next() ;
1401  }
1402  t1 = mathutil::gettimeofday_sec() ;
1403  os << "sortData: elapsed time is " << t1-t0 << " sec" << LogIO::POST ;
1404  //os << "rows_ = " << rows_ << LogIO::POST ;
1405}
1406}
Note: See TracBrowser for help on using the repository browser.