LCOV - code coverage report
Current view: top level - synthesis/Utilities - PointingDirectionCalculator.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 8 9 88.9 %
Date: 2024-12-11 20:54:31 Functions: 7 8 87.5 %

          Line data    Source code
       1             : //# PointingDirectionCalculator.h: Does for MSes various fixes which do not involve calibrating.
       2             : //# Copyright (C) 2008
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : //#
      28             : 
      29             : #ifndef _SYNTHESIS_POINTING_DIRECTION_CALCULATOR_H_
      30             : #define _SYNTHESIS_POINTING_DIRECTION_CALCULATOR_H_
      31             : 
      32             : #include <casacore/casa/aipstype.h>
      33             : #include <casacore/casa/BasicSL/String.h>
      34             : #include <casacore/casa/Arrays/Matrix.h>
      35             : #include <casacore/casa/Arrays/Vector.h>
      36             : #include <casacore/casa/Quanta/MVDirection.h>
      37             : #include <casacore/casa/Utilities/CountedPtr.h>
      38             : #include <casacore/ms/MeasurementSets/MeasurementSet.h>
      39             : #include <casacore/ms/MeasurementSets/MSPointing.h>
      40             : #include <casacore/ms/MeasurementSets/MSPointingColumns.h>
      41             : #include <casacore/measures/Measures/MCDirection.h>
      42             : #include <casacore/measures/Measures/MDirection.h>
      43             : #include <casacore/measures/Measures/MPosition.h>
      44             : #include <casacore/measures/Measures/MEpoch.h>
      45             : #include <casacore/measures/Measures/MeasFrame.h>
      46             : #include <casacore/measures/TableMeasures/ScalarMeasColumn.h>
      47             : #include <casacore/measures/TableMeasures/ArrayMeasColumn.h>
      48             : #include <casacore/tables/Tables/ScalarColumn.h>
      49             : // CAS-8418 //
      50             : #include <synthesis/Utilities/SDPosInterpolator.h>
      51             : #include <memory>  // for unique_ptr<> 
      52             : #include <utility> // for std::pair
      53             : 
      54             : namespace casa {
      55             : 
      56             : ///
      57             : // <summary>Calculates Pointing Direction Efficiently</summary>
      58             : //
      59             : //<use visibility=export>
      60             : //
      61             : // <reviewed reviewer="UNKNOWN" date="before2018/05/22" tests="" demos="">
      62             : // </reviewed>
      63             : //
      64             : // The PointingDirectionCalculator calculates pointing directions for selected MS rows.
      65             : // The calculation is based on the information recorded in MS POINTING table.
      66             : // In general, sampling intervals for spectral (autocorrelation) data (MS MAIN table)
      67             : // and pointing direction information (MS POINTING table) are independent. Thus,
      68             : // any interpolation in time domain should be necessary to calculate the pointing
      69             : // direction from the MS POINTING table. In addition, a direction reference frame
      70             : // in MS POINTING table may be different from the desired one. In that case,
      71             : // the frame conversion is also required. The class is intended to automate those
      72             : // complicated calculation. User can obtain a list of pointing directions by
      73             : // calling a few configuration method to select data and/or specify output direction
      74             : // reference frame. The class supports pointing direction calculation for moving
      75             : // objects. If the flag for moving source is turn on, returned direction will be
      76             : // shifted to the first timestamp.
      77             : //
      78             : // <prerequisite>
      79             : // </prerequisite>
      80             : //
      81             : // <etymology>
      82             : // </etymology>
      83             : //
      84             : // <synopsis>
      85             : // The PointingDirectionCalculator calculates pointing directions for selected
      86             : // MS rows. The calculation is based on the information recorded in MS POINTING
      87             : // table.
      88             : // </synopsis>
      89             : //
      90             : // <example>
      91             : // Here is a typical example for ALMA data. In ALMA, POINTING information is
      92             : // recorded in AZELGEO reference. However, there is a case that we need
      93             : // pointing direction in celestial coordinate such as J2000. In such case,
      94             : // the code will look like the following.
      95             : // <srcblock>
      96             : // MeasurementSet ms; // any MS
      97             : // PointingDirectionCalculator calculator(ms);
      98             : // calculator.setDirectionListMatrixShape(PointingDirectionCalculator::ROW_MAJOR);
      99             : // calculator.selectData(spw="19", antenna="PM01&&&"); // select spw 19 and antnena PM01
     100             : // calculator.setDirectionColumn("DIRECTION");
     101             : // calculator.setFrame("J2000");
     102             : // Matrix directions = calculator.getDirection();
     103             : // </srcblock>
     104             : // </example>
     105             : //
     106             : // <motivation>
     107             : // Pointing direction is one of the crucial information on single-dish data
     108             : // reduction. However, such information is not directly associated with
     109             : // spectral (autocorrelation) data. Instead, pointing directions must be
     110             : // calculated from the records in MS POINTING table. That calculation is
     111             : // sometimes complicated. It may contain an interpolation in time as well
     112             : // as a conversion to desired direction reference frame. This class is
     113             : // designed to automate such calculation. The implementation is somewhat
     114             : // specialized for the usecase of single-dish data reduction.
     115             : // </motivation>
     116             : //
     117             : //#! <templating arg=T>
     118             : //#! </templating>
     119             : //
     120             : // <thrown>
     121             : // </thrown>
     122             : //
     123             : // <todo asof="before2018/05/22">
     124             : //   <li> Define unit test
     125             : //   <li> Implement more sophisticated interpolation method such as cubic spline
     126             : // </todo>
     127             : ///
     128             : 
     129             : class SplineInterpolation;       // CAS-8418 Forward Reference //
     130             : 
     131             : class PointingDirectionCalculator {
     132             : public:
     133             : 
     134             :     //+
     135             :     //  CAS-8418:  typedef of accessor_ and  Direction column types.
     136             :     //-
     137             :     typedef 
     138             :     casacore::MDirection (*ACCESSOR)(  casacore::MSPointingColumns &pointingColumns,
     139             :                                        casacore::uInt rownr);
     140             :     typedef
     141             :     enum DC_ { DIRECTION, TARGET, POINTING_OFFSET, SOURCE_OFFSET, ENCODER, nItems} PtColID;
     142             : 
     143             :     typedef casacore::Vector<casacore::Vector<casacore::Vector<casacore::Vector<casacore::Double> > > > 
     144             :     COEFF;
     145             : 
     146             :     // Enumerations for memory layout of the output pointing direction array.
     147             :     // User should select the layout according to an usercase of this class.
     148             :     enum MatrixShape {
     149             :         // Memory layout is "column major"
     150             :         COLUMN_MAJOR,
     151             :         // Memory layout is "row major"
     152             :         ROW_MAJOR
     153             :     };
     154             : 
     155             :     //+
     156             :     // Constructor
     157             :     //-
     158             :    
     159             : //+
     160             : 
     161             : //   Create Spline five Objects on PointingDirectionCalculator.
     162             : //
     163             : //   - The setDirectionColumn(name) performs all the initialization and make Coefficient table.
     164             : //   - In this constructor, init() and setDirectionColumn("DIRECTION") are called,
     165             : //     soon or later, setDirectionColumn will be called, whenever new Direction column is used
     166             : //     and interporation is made.
     167             : //   - The spline object is created by a column, which contains all antenna_Id.
     168             : //   - Cofficient table is obtained from SDPosInterpolation. 
     169             : //   - SplineInterpolation class in this file provides calculation but it is sort of customize 
     170             : //     for PoinitngDirectionCalculator.
     171             : //   - To see the initialization, please start from setDirectionColumn().  
     172             : //- 
     173             : 
     174             :     PointingDirectionCalculator(casacore::MeasurementSet const &ms);
     175             : 
     176             :     // Destructor
     177             :     ~PointingDirectionCalculator();
     178             : 
     179             :     // Select data in the given MS.
     180             :     // Each selection parameters accept MS data selection syntax.
     181             :     void selectData(casacore::String const &antenna = "", 
     182             :                 casacore::String const &spw ="",
     183             :                 casacore::String const &field = "", 
     184             :                 casacore::String const &time = "",
     185             :                 casacore::String const &scan = "", 
     186             :                 casacore::String const &feed = "",
     187             :                 casacore::String const &intent = "", 
     188             :                 casacore::String const &observation = "", 
     189             :                 casacore::String const &uvrange = "",
     190             :                 casacore::String const &msselect = "");
     191             : 
     192             :     //+
     193             :     // Select which POINTING column to use for pointing direction calculation.
     194             :     // Possible values are "DIRECTION" (default), "TARGET", "POINTING_OFFSET",
     195             :     // "SOURCE_OFFSET", and "ENCODER". These values are all case-sensitive.
     196             :     //
     197             :     // CAS-8418 Update
     198             :     //   Spline-Interpolation initialization is inserted for each POINTING Column.
     199             :     //   Once this is done, the object will be reused.
     200             :     //-
     201             :        
     202             :     void setDirectionColumn(casacore::String const &columnName = "DIRECTION");
     203             : 
     204             :     //+
     205             :     // Set output direction reference frame. This accepts reference strings which
     206             :     // <linkto class=MDirection>MDirection</linkto> can recognize.
     207             :     // If given string is invalid, the frame will be set to "J2000".
     208             :     //-
     209             :  
     210             :     void setFrame(casacore::String const frameType);
     211             : 
     212             :     //+
     213             :     // Set output direction matrix shape. If "ROW_MAJOR" is given, the shape will be
     214             :     // (2, nrow) where nrow is a number of selected rows in MS. If "COLUMN_MAJOR" is
     215             :     // set, the shape will be (nrow, 2). User can choose appropriate shape according
     216             :     // to the access pattern for the output direction matrix.
     217             :     //-
     218             : 
     219             :     void setDirectionListMatrixShape(
     220             :             PointingDirectionCalculator::MatrixShape const shape);
     221             :     
     222             :     //+
     223             :     // <group>
     224             :     // Set source name for the moving source.
     225             :     // The method accepts source names which <linkto class=MDirection>MDirection</linkto>
     226             :     // can recognize (e.g. "Moon", "Jupiter").
     227             :     // If given string is invalid, exception will be thrown. User can specify the moving source
     228             :     // using a string or the MDirection instance.
     229             :     
     230             :     void setMovingSource(casacore::String const sourceName);
     231             :     void setMovingSource(casacore::MDirection const &sourceDirection);
     232             :     
     233             :     // </group>
     234             : 
     235             :     //+
     236             :     // Clear the moving source setting.
     237             :     //-
     238             :     
     239             :     void unsetMovingSource();
     240             : 
     241             :     //+
     242             :     // Return number of rows for selected MS.
     243             :     //-
     244             : 
     245           9 :     casacore::uInt getNrowForSelectedMS() {return selectedMS_->nrow();}
     246             : 
     247             :     //+
     248             :     // Return direction type as a <linkto class=MDirection>MDirection::Types</linkto>
     249             :     // enum.
     250             :     //-
     251             : 
     252           4 :     casacore::MDirection::Types const &getDirectionType() {return directionType_;}
     253             : 
     254             :     //+
     255             :     // Return an information on the moving source as a <linkto class=MDirection>MDirection</linkto>
     256             :     // instance.
     257             :     //-
     258             :     
     259           4 :     casacore::MDirection const &getMovingSourceDirection() {return *movingSource_;}
     260             : 
     261             :     //+
     262             :     // Return pointing direction matrix. Its shape depends on the user set the shape to
     263             :     // "ROW_MAJOR" or "COLUMN_MAJOR". Returned directions are interpolated to timestamps
     264             :     // recorded in the selected MS, and are converted to desired direction reference
     265             :     // frame if necessary.
     266             :     //-     
     267             : 
     268             :     casacore::Matrix<casacore::Double> getDirection();
     269             : 
     270             :     //+
     271             :     // Return pointing direction for specified row.
     272             :     // If irow is larger than or equal to the number of rows for selected MS,
     273             :     // exception will be thrown.
     274             :     //-
     275             : 
     276             :     casacore::Vector<casacore::Double> getDirection(casacore::uInt irow);
     277             : 
     278             :     // <group>
     279             :     // Return a list of row ids for selected rows. The getRowId will return the ids
     280             :     // in selected MS. On the other hand, the getRowIdForOriginalMS will return
     281             :     // the ids in original MS.
     282             : 
     283             :     casacore::Vector<casacore::rownr_t> getRowId();
     284             :     casacore::Vector<casacore::rownr_t> getRowIdForOriginalMS();
     285             : 
     286             :     // </group>
     287             : 
     288             :     //+
     289             :     // Return a row id for specified row.
     290             :     // If irow is larger than or equal to the number of rows for selected MS,
     291             :     // exception will be thrown.
     292             :     //-
     293             : 
     294             :     casacore::rownr_t getRowId(casacore::uInt irow);
     295             : 
     296             :     //***************************************
     297             :     // CAS-8418  Spline Interpolation API 
     298             :     //***************************************
     299             :     
     300             :     // Spline interpolation Enable/Disable (true=ENABLE) 
     301             : 
     302             :     inline void setSplineInterpolation(bool mode) {useSplineInterpolation_ = mode;};
     303             : 
     304             :     // Curret Direction column (=accessor in this source) (for UT)
     305             : 
     306             :     inline PtColID  getCurretAccessorId()  { return  accessorId_ ; };
     307             : 
     308             :     // Exporting COEFF table. //
     309             : 
     310             :     bool    isCoefficientReady();   // true if current COEFF is availabe 
     311             :     COEFF   exportCoeff();          // returns copy of COEFF
     312             : 
     313             : private: 
     314             : 
     315             :     void init();
     316             :     void initPointingTable(casacore::Int const antennaId);
     317             :     void resetAntennaPosition(casacore::Int const antennaId);
     318             :     void resetTime(casacore::Double const timestamp);
     319             :     void inspectAntenna();
     320             :     void configureMovingSourceCorrection();
     321             : 
     322             :     casacore::Vector<casacore::Double> doGetDirection(casacore::uInt irow);
     323             :     casacore::Vector<casacore::Double> doGetDirection(casacore::uInt irow, casacore::uInt antID);
     324             : 
     325             :     // table access stuff
     326             : 
     327             :     casacore::CountedPtr<casacore::MeasurementSet>                originalMS_;
     328             :     casacore::CountedPtr<casacore::MeasurementSet>                selectedMS_;
     329             :     casacore::CountedPtr<casacore::MSPointing>                    pointingTable_;
     330             :     casacore::CountedPtr<casacore::MSPointingColumns>           pointingColumns_;
     331             :     casacore::ScalarMeasColumn<casacore::MEpoch>          timeColumn_;
     332             :     casacore::ScalarColumn<casacore::Double>                      intervalColumn_;
     333             :     casacore::ScalarColumn<casacore::Int>                         antennaColumn_;
     334             :     casacore::String                                            directionColumnName_;
     335             : 
     336             :     casacore::MDirection (*accessor_)(  casacore::MSPointingColumns &pointingColumns,
     337             :                                         casacore::uInt rownr);
     338             :     // conversion stuff
     339             : 
     340             :     casacore::MPosition                         antennaPosition_;
     341             :     casacore::MEpoch                            referenceEpoch_;
     342             :     casacore::MeasFrame                         referenceFrame_;
     343             :     casacore::CountedPtr<casacore::MDirection::Convert> directionConvert_;
     344             :     casacore::MDirection::Types                         directionType_;
     345             :     casacore::CountedPtr<casacore::MDirection>            movingSource_;
     346             :     casacore::CountedPtr<casacore::MDirection::Convert> movingSourceConvert_;
     347             : 
     348             :     void (*movingSourceCorrection_)(
     349             :             casacore::CountedPtr<casacore::MDirection::Convert> &convertToAzel,
     350             :             casacore::CountedPtr<casacore::MDirection::Convert> &convertToCelestial,
     351             :             casacore::Vector<casacore::Double> &direction);
     352             : 
     353             :     // other
     354             :    
     355             :     casacore::Vector<casacore::uInt>              antennaBoundary_;
     356             :     casacore::uInt                              numAntennaBoundary_;
     357             :     casacore::Vector<casacore::Double>            pointingTimeUTC_;
     358             :     casacore::Double                            lastTimeStamp_;
     359             :     casacore::Int                               lastAntennaIndex_;
     360             :     casacore::uInt                              pointingTableIndexCache_;
     361             :     PointingDirectionCalculator::MatrixShape    shape_;
     362             : 
     363             :     // privatize  default constructor
     364             : 
     365             :     PointingDirectionCalculator();
     366             : 
     367             :     //**********************************************
     368             :     // CAS-8418 Spline Extended
     369             :     //  (Initial values on the top of Constructor)
     370             :     //**********************************************
     371             : 
     372             :     // Spline Type , Initialized in Constructor. 'true' enables Spline Interpoation. //
     373             :       bool useSplineInterpolation_ ;      
     374             : 
     375             :     // Current Spline Object (become active with specified Direction Column)
     376             :       casa::SplineInterpolation                     *currSpline_ ;   
     377             : 
     378             :     // Spline Object for each Direction-Column 
     379             :       casacore::vector<std::unique_ptr<casa::SplineInterpolation> >    splineObj_;
     380             : 
     381             :     // Internal conditions to check limitted service.  
     382             :       casacore::Vector<bool>                         initializeReady_  ;
     383             :       casacore::Vector<bool>                         coefficientReady_ ;
     384             : 
     385             :     // Accessor ID (See typedef above. ) 
     386             :       PtColID   accessorId_ ;
     387             :  
     388             :     // check specified Column when creating Spline-Object.
     389             : 
     390             :       bool checkColumn(casacore::MeasurementSet const &ms,
     391             :                         casacore::String const &columnName );
     392             : 
     393             :     // Initialize Coefficient table.
     394             :       bool initializeSplinefromPointingColumn(casacore::MeasurementSet const &ms, PtColID  colNo );
     395             : 
     396             :     // Current Spline-Object handle. (only available SplineInterpolation class) 
     397      314193 :       casa::SplineInterpolation         *getCurrentSplineObj() {return currSpline_; }
     398             : 
     399             : };
     400             : 
     401             : //+
     402             : // CAS-8418
     403             : // Spline Interpolation Class
     404             : //-
     405             : 
     406             : class SplineInterpolation  {
     407             : public:
     408             :         // Coefficient table typedef //
     409             :           typedef casacore::Vector<casacore::Vector<casacore::Vector<casacore::Vector<casacore::Double> > > >
     410             :           COEFF;
     411             : 
     412             :         // Constructor 
     413             :           SplineInterpolation(casacore::MeasurementSet const &ms, PointingDirectionCalculator::ACCESSOR acc );
     414             : 
     415         311 :          ~SplineInterpolation() {    }
     416             : 
     417             :         // Calculating Function //
     418             : 
     419             :         casacore::Vector<casacore::Double>   calculate(casacore::uInt row,
     420             :                                                        casacore::Double dt,
     421             :                                                        casacore::uInt AntennaID =0);
     422             :         // Spline-Obj coefficient status   //
     423             : 
     424         924 :         bool isCoefficientReady()   {return stsCofficientReady; }
     425             :        
     426             :         // Programmers API:: for Coefficient Table access // 
     427             : 
     428           0 :         COEFF getCoeff() { return coeff_; }
     429             : 
     430             :         // CAS-8418 Time Gap
     431      106124 :         bool isTimeGap(casacore::uInt ant, casacore::uInt index)
     432      106124 :                       { return tmp_timegap[ant][index]; }
     433             : 
     434             : private:
     435             :         //  default constructor 
     436             : 
     437             :          SplineInterpolation();
     438             : 
     439             :         //  constructor sub. 
     440             : 
     441             :           void init( casacore::MeasurementSet const &ms, 
     442             :                      PointingDirectionCalculator::ACCESSOR const my_accessor);
     443             : 
     444             :         // Coefficient (set up by SDPosInterpolator)
     445             : 
     446             :           COEFF  coeff_;
     447             :        
     448             :         // Interal Staus (one Spline status)//
     449             :  
     450             :           bool stsCofficientReady = false;
     451             :   
     452             :         // Coeff debug in csv. //
     453             :           void dumpCsvCoeff();
     454             : 
     455             :         //*
     456             :         // CAS-8418 Time Gap
     457             :         //   (relocated and new )
     458             :         //*
     459             :         
     460             :          casacore::Vector<casacore::Vector<casacore::Vector<casacore::Double> > > tmp_dir;
     461             :          casacore::Vector<casacore::Vector<casacore::Double> >          tmp_time;
     462             :          casacore::Vector<casacore::Vector<casacore::Double> >          tmp_dtime;
     463             :          casacore::Vector<casacore::Vector<bool> >                      tmp_timegap;
     464             : 
     465             : };
     466             : 
     467             : 
     468             : } //# NAMESPACE CASA - END
     469             : 
     470             : #endif /* _SYNTHESIS_POINTING_DIRECTION_CALCULATOR_H_ */

Generated by: LCOV version 1.16