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 314179 : 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 304 : ~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 903 : 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_ */
|