casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MSSelector.h
Go to the documentation of this file.
00001 //# MSSelector.h: this defines MSSelector, which specifies MS selections
00002 //# Copyright (C) 1997,1998,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //#
00027 //# $Id: MSSelector.h 21298 2012-12-07 14:53:03Z gervandiepen $
00028 
00029 #ifndef MS_MSSELECTOR_H
00030 #define MS_MSSELECTOR_H
00031 
00032 #include <casa/aips.h>
00033 #include <casa/Arrays/Vector.h>
00034 #include <casa/Arrays/Slice.h>
00035 #include <casa/Arrays/Slicer.h>
00036 #include <ms/MeasurementSets/MeasurementSet.h>
00037 #include <ms/MeasurementSets/StokesConverter.h>
00038 #include <ms/MeasurementSets/MSDerivedValues.h>
00039 #include <ms/MeasurementSets/MSSelectionKeywords.h>
00040 
00041 namespace casa { //# NAMESPACE CASA - BEGIN
00042 
00043 template <class T> class ArrayColumn;
00044 class Record;
00045 class MSIter;
00046 
00047 // <summary>
00048 // MSSelector specifies selections on a MeasurementSet
00049 // </summary>
00050 
00051 // <use visibility=export>
00052 
00053 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00054 // </reviewed>
00055 
00056 // <prerequisite>
00057 //   <li> MeasurementSet
00058 //   <li> Record
00059 // </prerequisite>
00060 //
00061 // <etymology>
00062 // MSSelector's main function is selection of data from a MeasurementSet
00063 // </etymology>
00064 //
00065 // <synopsis>
00066 // This class is used to select and retrieve data from a MeasurementSet. 
00067 // It allows selections on e.g., time, field, spectral window (all row based),
00068 // but also on channel and polarization (within a row). It can optionally
00069 // do polarization conversion, spectral averaging and time averaging on the
00070 // data retrieved and allows modified data to be written back to the Table.
00071 // This class also provides the DO interface to the MS Iterator.
00072 // The ms DO uses this class to allow these operations to be done from glish.
00073 //
00074 // <example> <srcblock>
00075 // MSSelector msSelector(myMS);
00076 // // select data desc Id 1
00077 // msSelector.initSelection(1);
00078 // Vector<String> items(3); 
00079 // // fill in some fields
00080 // items(0)="field_id";
00081 // items(1)="time";
00082 // items(2)="num_chan";
00083 // // get the range of values for the items specified
00084 // MSRange msRange(msSelector.selectedTable(),msSelector.spectralWindow());
00085 // Record range=msRange.range(items);
00086 // //.. change the ranges as needed
00087 // // now select with the new range
00088 // msSelector.select(range);
00089 // Int nchan=10, start=3, width=1, incr=2;
00090 // msSelector.selectChannel(nchan,start,width,incr)
00091 // // get out some data
00092 // Vector<String> dataItems(3);
00093 // dataItems(0)="data";
00094 // dataItems(1)="antenna1";
00095 // dataItems(2)="antenna2";
00096 // Record dataRec=msSelector.getData(items);
00097 // </srcblock></example>
00098 // </synopsis>
00099 //
00100 // <motivation>
00101 // Selection from an MS is needed in various places. It makes sense to
00102 // provide a uniform interface for MS selection.
00103 // </motivation>
00104 //
00105 // <thrown>
00106 //    <li>
00107 // </thrown>
00108 //
00109 // <todo asof="1998/12/11">
00110 //   <li> provide access to all other columns in the MS?
00111 // </todo>
00112 
00113 class MSSelector
00114 {
00115   friend class MSRange;
00116 
00117 public:
00118 
00119   MSSelector();
00120   
00121   // construct from an MS, the MS will supply the range of the various
00122   // parameters that can be selected on.
00123   explicit MSSelector(MeasurementSet& ms);
00124   
00125   // Copy constructor, this will initialize the MS with other's MS
00126   MSSelector(const MSSelector& other);
00127   
00128   // Assignment, this will initialize the MS with other's MS
00129   MSSelector& operator=(const MSSelector& other);
00130 
00131   ~MSSelector();
00132   
00133   // Change or Set the MS this MSSelector refers to.
00134   void setMS(MeasurementSet& ms);
00135   
00136   // initialize the selection by specifying, optionally, 
00137   // the DATA_DESC_IDs. 
00138   // If you don't specify the dataDescIds and the data shape is constant
00139   // all data is selected, if the shape does change, only the first 
00140   // dataDescId is selected. If you specify a number of dataDescIds
00141   // and they all have the same shape, they are all selected, otherwise
00142   // only the first is selected. The function returns false if
00143   // the selection was limited due to changing data shape.
00144   // Use the reset argument to return to the completely unselected ms.
00145   Bool initSelection(const Vector<Int>& dataDescIds, Bool reset=False);
00146 
00147   // As above without the data desc id argument
00148   Bool initSelection(Bool reset=False);
00149 
00150   // Return the data desc IDs selected 
00151   Vector<Int> dataDescId() const;
00152 
00153   // Set the mapping from input channels in the DATA column to
00154   // output channels. nChan is the number of output channels,
00155   // start is the first channel to use, width specifies how wide a 
00156   // block of channels to average, increment specifies the start of
00157   // the next block relative to the start of the current block.
00158   // Note: averaging uncalibrated data should be avoided (no bandpass applied)
00159   Bool selectChannel(Int nChan, Int start, Int width, Int incr);
00160 
00161   // Specify the output polarization. 
00162   // Missing input polarizations are assumed to be zero.
00163   // This selection/conversion assumes that parallactic angle rotation
00164   // is taken care of elsewhere (i.e., results may only be correct for
00165   // CORRECTED_DATA and MODEL_DATA conversions, not for the observed DATA)
00166   Bool selectPolarization(const Vector<String>& wantedPol);
00167 
00168   // Select the MS based on the selections present in the input record.
00169   // The format of this record is the same as that returned by range.
00170   // Not all possible items can be selected on, some are quietly ignored.
00171   // Correct for one-based indexing if oneBased is True.
00172   Bool select(const Record& items, Bool oneBased=False);
00173 
00174   // Select the MS based on the TaQL selection string
00175   Bool select(const String& msSelect);
00176 
00177   // Return the data for the items requested, all returned values
00178   // will be arrays, the last dimension of these is the table row number.
00179   // The data arrays are normally 3D with axes: polarization, frequency, row.
00180   // If ifrAxis is set to True, the data arrays returned will be 4D, with
00181   // the data being split out along an extra interferometer axis, the
00182   // axes will be: polarization, frequency, interferometer and time.
00183   // Missing interferometers will be marked flagged.
00184   // The order of the interferometers is that specified by the last
00185   // select call.
00186   // Add a (flagged) gap in the data at every antenna1 change if ifrAxisGap>0.
00187   // Use inc > 1 to return data from every inc'th row.
00188   // Use average=True to vector average the data along the row or time axis 
00189   // taking the weights column into account (use selectChannel to average
00190   // channels together as well). Note that different interferometers will be
00191   // averaged together if ifrAxis is False.
00192   // Correct for one-based indexing if oneBased is True.
00193   Record getData(const Vector<String>& items, Bool ifrAxis, 
00194                       Int ifrAxisGap=0, Int inc=1,
00195                       Bool average=False, Bool oneBased=False);
00196 
00197   // Put the data for the items provided. Note that only fields corresponding
00198   // to actual table columns can be put (i.e., no AMPLITUDEs, IFR_NUMBERs etc)
00199   // The data will need to have the correct shape for the column and a last
00200   // dimension matching the number of selected rows (or last two dimensions
00201   // matching times and interferometers, for data retrieved with ifraxis=T)
00202   // Channel selection is supported, but the width parameter has to be 1.
00203   Bool putData(const Record& items);
00204 
00205   // Set up an iterator, iterating over the specified columns, with
00206   // optional time interval and maximum number of rows to return at once
00207   // (the default of zero returns all rows). To keep MSIter from adding  
00208   // the default sort columns, specify addDefaultSortColumns=False
00209   Bool iterInit(const Vector<String>& columns,
00210                 Double interval, Int maxRows=0,
00211                 Bool addDefaultSortColumns=True);
00212   
00213   // Step the iterator, sets the selection to the current table iteration.
00214   // Returns false if there is no more data
00215   // and sets the selection back to the state before iteration started.
00216   Bool iterNext();
00217 
00218   // (Re)Set the iterator to the first iteration, call this after iterInit.
00219   Bool iterOrigin();
00220 
00222   // and set the selection back to the state before iteration started.
00223   Bool iterEnd();
00224 
00225   // Number of rows in selected table
00226   Int nrow() const;
00227 
00228   // Return the selected table
00229   Table selectedTable() const;
00230 
00231   // Return the selection status of the table
00232   Bool selected() const;
00233 
00234 protected:
00235   // average and convert data
00236   void getAveragedData(Array<Complex>& avData, const Array<Bool>& flag,
00237                        const ArrayColumn<Complex>& col) const;
00238 
00239   // average and convert float data
00240   void getAveragedData(Array<Float>& avData, const Array<Bool>& flag,
00241                        const ArrayColumn<Float>& col) const;
00242 
00243   // average and convert data, with row Slicer
00244   void getAveragedData(Array<Complex>& avData, const Array<Bool>& flag,
00245                        const ArrayColumn<Complex>& col,
00246                        const Slicer & rowSlicer) const;
00247 
00248   // average and convert float data, with row Slicer
00249   void getAveragedData(Array<Float>& avData, const Array<Bool>& flag,
00250                        const ArrayColumn<Float>& col,
00251                        const Slicer & rowSlicer) const;
00252 
00253   // "average" flag, at present all output which has a flagged input is flagged
00254   Array<Bool> getAveragedFlag(Array<Bool>& avFlag, 
00255                        const ArrayColumn<Bool>& col) const;
00256 
00257   // "average" flag, at present all output which has a flagged input is flagged,
00258   // with row Slicer
00259   Array<Bool> getAveragedFlag(Array<Bool>& avFlag, 
00260                        const ArrayColumn<Bool>& col,
00261                        const Slicer& rowSlicer) const;
00262 
00263   // "unaverage" flag, distribute the flags back to the channels that went
00264   // into the average
00265   void putAveragedFlag(const Array<Bool>& avFlag,
00266                        ArrayColumn<Bool>& col);
00267 
00268   // get the weight, set sigma=True when retrieving sigma's
00269   Array<Float> getWeight(const ArrayColumn<Float>& wtCol,
00270                          Bool sigma=False) const;
00271 
00272   // make the data slicer, pass in the first and the number of correlations
00273   // to select
00274   void makeSlicer(Int start, Int nCorr) const;
00275 
00276   // reorder from 2d to 1d (removing ifr axis)
00277   void reorderFlagRow(Array<Bool>& flagRow);
00278 
00279   // reorder from 2d to 1d (removing ifr axis)
00280   void reorderWeight(Array<Float>& weight);
00281 
00282   // time average the input data, return new flags
00283   void timeAverage(Array<Bool>& dataFlags, Array<Complex>& data,
00284                    const Array<Bool>& flags, const Array<Float>& weights);
00285 
00286   // check if the data description selection has been done & do default
00287   // selection if not. Return False if the selection fails.
00288   Bool checkSelection();
00289 
00290 private:
00291   // The function types
00292   enum {Amp,Phase,Real,Imag,Data,nFuncType};
00293 
00294   // The data types
00295   enum {Observed,Corrected,Model,Ratio,Residual,ObsResidual,ObsFloat,nDataType};
00296 
00297   MeasurementSet ms_p; // the original ms
00298   MeasurementSet selms_p; // the selected ms
00299   MeasurementSet savems_p; // the saved preselection
00300   MSIter* msIter_p;
00301   Bool initSel_p;
00302   Vector<Int> dataDescId_p, lastDataDescId_p;
00303   Vector<uInt> spwId_p, polId_p;
00304   Vector<Int> chanSel_p;
00305   Bool useSlicer_p;
00306   mutable Bool haveSlicer_p;
00307   mutable Slicer slicer_p;
00308   Slice chanSlice_p,polSlice_p;
00309   Vector<Int> polIndex_p;
00310   Int wantedOne_p;
00311   Bool convert_p, subSet_p;
00312   StokesConverter stokesConverter_p;
00313   Vector<String> polSelection_p;
00314   Vector<Int> ifrSelection_p,ifrAxis_p;
00315   Matrix<Double> chanFreq_p,bandwidth_p;
00316   MSDerivedValues msd_p;
00317   Matrix<Int> rowIndex_p; // mapping of rows to time and ifr slots
00318   Vector<uInt> selRows_p; // range of rows from selms_p returned by getData
00319   Int startRow_p, maxRow_p; // start and length of range of rows
00320   Bool useIfrDefault_p;
00321 
00322 };
00323 inline Int MSSelector::nrow() const { return selms_p.nrow();}
00324 inline Vector<Int> MSSelector::dataDescId() const { return dataDescId_p;}
00325 inline Table MSSelector::selectedTable() const {return selms_p;}
00326 inline Bool MSSelector::selected() const {return initSel_p;}
00327 
00328 
00329 } //# NAMESPACE CASA - END
00330 
00331 #endif
00332