Vi2ChunkDataProvider.h

Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2002,2003,2015
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 // Base class of data providers based on StatsDataProvider, backed by a
00028 // VisibilityIterator2 instances.
00029 //
00030 #ifndef MSVIS_STATISTICS_VI2_CHUNK_DATA_PROVIDER_H_
00031 #define MSVIS_STATISTICS_VI2_CHUNK_DATA_PROVIDER_H_
00032 
00033 #include <casacore/casa/aips.h>
00034 #include <casacore/casa/Arrays/Array.h>
00035 #include <msvis/MSVis/VisibilityIterator2.h>
00036 #include <msvis/MSVis/VisBufferComponents2.h>
00037 #include <msvis/MSVis/statistics/Vi2StatsFlagsIterator.h>
00038 #include <msvis/MSVis/statistics/Vi2StatsWeightsIterator.h>
00039 #include <msvis/MSVis/statistics/Vi2StatsSigmasIterator.h>
00040 #include <msvis/MSVis/statistics/Vi2ChunkStatisticsIteratee.h>
00041 #include <casacore/scimath/Mathematics/StatisticsAlgorithm.h>
00042 #include <casacore/scimath/Mathematics/StatsDataProvider.h>
00043 #include <memory>
00044 #include <vector>
00045 
00046 namespace casa {
00047 
00048 //
00049 // Data provider template class backed by VisibilityIterator2 instances. These
00050 // data providers operate on a single MS column over all vi2 sub-chunks in the
00051 // chunk selected when the data provider is instantiated. In other words, the
00052 // data sample for statistics generated with a Vi2ChunkDataProvider instance is
00053 // the data from a single column in a single vi2 chunk. It is intended that the
00054 // user set up the VisibilityIterator2 appropriately to select the desired data
00055 // sample for computing statistics. The user may then iterate through the
00056 // VisibilityIterator2 chunks, calling reset() on the Vi2ChunkDataProvider
00057 // instance before supplying the instance to the Statistics::setDataProvider()
00058 // call to compute statistics for that chunk's data. In outline:
00059 //
00060 // Vi2ChunkDataProvider *dp; // given
00061 // StatisticsAlgorithm statistics; // given
00062 // for (dp->vi2->originChunks(); dp->vi2->moreChunks(); dp->vi2->nextChunk()) {
00063 //  // Prepare the data provider
00064 //  dp->vi2->origin();
00065 //  dp->reset();
00066 //  // Compute statistics for this chunk
00067 //  statistics.setDataProvider(dp);
00068 //  doStuff(statistics);  // do something with the statistics;
00069 //                        // maybe call statistics.getStatistics()
00070 // }
00071 //
00072 // The above pattern is encapsulated by the Vi2ChunkDataProvider::foreachChunk()
00073 // method and Vi2ChunkStatisticsIteratee. The above can be implemented as
00074 // follows (but with template parameters where needed):
00075 //
00076 // Vi2ChunkDataProvider *dp; // given
00077 // StatisticsAlgorithm statistics; // given
00078 // class DoStuff : public Vi2ChunkStatisticsIteratee {
00079 //   ... // constructor, probably needs some sort of accumulator
00080 //   void nextChunk(StatisticsAlgorithm stats, const * VisBuffer2 vb) {
00081 //     stats.getStatistics()...;
00082 //   }
00083 // }
00084 // DoStuff doStuff;
00085 // dp->foreachChunk(statistics, doStuff);
00086 //
00087 // Note that the AccumType template parameter value of StatsDataProvider is
00088 // derived from the DataIterator parameter value of this template, imposing a
00089 // constraint on the classes that can be used for DataIterator.
00090 //
00091 template <class DataIterator, class MaskIterator, class WeightsIterator>
00092 class Vi2ChunkDataProvider
00093         : public StatsDataProvider<typename DataIterator::AccumType,
00094                                    DataIterator,
00095                                    MaskIterator,
00096                                    WeightsIterator> {
00097 
00098 public:
00099         // Define typedefs for some template parameters. This is primarily to
00100         // support instantiating "...Statistics" instances of the proper type given
00101         // only an instance of this type. [AccumType is an exception, in that it's
00102         // also needed by the (macro) definition of DataRanges.]
00103         typedef typename DataIterator::AccumType AccumType;
00104         typedef DataIterator DataIteratorType;
00105         typedef MaskIterator MaskIteratorType;
00106         typedef WeightsIterator WeightsIteratorType;
00107 
00108         Vi2ChunkDataProvider(
00109                 vi::VisibilityIterator2 *vi2,
00110                 vi::VisBufferComponent2 component,
00111                 Bool omit_flagged_data,
00112                 Bool use_data_weights)
00113                 : vi2(vi2)
00114                 , component(component)
00115                 , use_data_weights(use_data_weights)
00116                 , omit_flagged_data(omit_flagged_data) {
00117 
00118                 // Attach the MS columns to vi2 by calling originChunks(). Not the most
00119                 // direct method, but attaching the columns is required in many cases to
00120                 // pass existsColumn() test.
00121                 vi2->originChunks();
00122                 if (!vi2->existsColumn(component))
00123                         throw AipsError("Column is not present");
00124         }
00125 
00126         Vi2ChunkDataProvider(Vi2ChunkDataProvider&& other)
00127                 : vi2(other.vi2)
00128                 , component(other.component)
00129                 , use_data_weights(other.use_data_weights)
00130                 , omit_flagged_data(other.omit_flagged_data)
00131                 , data_iterator(other.data_iterator)
00132                 , weights_iterator(other.weights_iterator)
00133                 , mask_iterator(other.mask_iterator) {
00134                 other.vi2 = nullptr;
00135         }
00136 
00137         Vi2ChunkDataProvider& operator=(Vi2ChunkDataProvider&& other) {
00138                 vi2 = other.vi2;
00139                 component = other.component;
00140                 use_data_weights = other.use_data_weights;
00141                 omit_flagged_data = other.omit_flagged_data;
00142                 data_iterator = other.data_iterator;
00143                 weights_iterator = other.weights_iterator;
00144                 mask_iterator = other.mask_iterator;
00145                 other.vi2 = nullptr;
00146                 return *this;
00147         }
00148 
00149         // Increment the data provider to the next sub-chunk.
00150         void operator++() {
00151                 reset_iterators();
00152                 vi2->next();
00153         }
00154 
00155         // Are there any sub-chunks left to provide?
00156         Bool atEnd() const {
00157                 return !vi2->more();
00158         }
00159 
00160         // Take any actions necessary to finalize the provider. This will be called
00161         // when atEnd() returns True.
00162         void finalize() {};
00163 
00164         uInt64 getCount() {
00165                 return getData().getCount();
00166         }
00167 
00168         // Get the current sub-chunk
00169         DataIterator getData() {
00170                 if (!data_iterator)
00171                         data_iterator =
00172                                 std::unique_ptr<DataIterator>(new DataIterator(dataArray()));
00173                 return *data_iterator;
00174         }
00175 
00176         uInt getStride() {
00177                 return 1;
00178         };
00179 
00180         Bool hasMask() const {
00181                 return omit_flagged_data;
00182         };
00183 
00184         // Get the associated mask of the current sub-chunk. Only called if
00185         // hasMask() returns True.
00186         MaskIterator getMask() {
00187                 if (!mask_iterator)
00188                         mask_iterator = std::unique_ptr<MaskIterator>(
00189                                 new MaskIterator(vi2->getVisBuffer()));
00190                 return *mask_iterator;
00191         };
00192 
00193         // Get the stride for the current mask (only called if hasMask() returns
00194         // True). Will always return 1 in this implementation.
00195         uInt getMaskStride() {
00196                 return 1;
00197         };
00198 
00199         Bool hasWeights() const {
00200                 return use_data_weights;
00201         };
00202 
00203         // Get the associated weights of the current sub-chunk. Only called if
00204         // hasWeights() returns True;
00205         WeightsIterator getWeights() {
00206                 if (!weights_iterator)
00207                         weights_iterator = std::unique_ptr<WeightsIterator>(
00208                                 new WeightsIterator(vi2->getVisBuffer()));
00209                 return *weights_iterator;
00210         };
00211 
00212         Bool hasRanges() const {
00213                 return false; // TODO: is this correct in all cases?
00214         };
00215 
00216         // Get the associated range(s) of the current sub-chunk. Only called if
00217         // hasRanges() returns True, which will never be the case in this
00218         // implementation.
00219         DataRanges
00220         getRanges() {
00221                 DataRanges result;
00222                 return result;
00223         };
00224 
00225         // If the associated data set has ranges, are these include (return True) or
00226         // exclude (return False) ranges?
00227         Bool isInclude() const {
00228                 return false;
00229         };
00230 
00231         // Reset the provider to point to the first sub-chunk.
00232         void reset() {
00233                 reset_iterators();
00234                 vi2->origin();
00235         }
00236 
00237         std::unique_ptr<vi::VisibilityIterator2> vi2;
00238 
00239         void foreachChunk(
00240                 StatisticsAlgorithm<AccumType,DataIteratorType,MaskIteratorType,WeightsIteratorType>& statistics,
00241                 Vi2ChunkStatisticsIteratee<DataIterator,WeightsIterator,MaskIterator>& iteratee) {
00242 
00243                 for (vi2->originChunks(); vi2->moreChunks(); vi2->nextChunk()) {
00244                         reset();
00245                         statistics.setDataProvider(this);
00246                         iteratee.nextChunk(statistics, vi2->getVisBuffer());
00247                 }
00248         }
00249 
00250 protected:
00251 
00252         vi::VisBufferComponent2 component;
00253 
00254         std::unique_ptr<const DataIterator> data_iterator;
00255 
00256         const Bool use_data_weights;
00257 
00258         std::unique_ptr<const WeightsIterator> weights_iterator;
00259 
00260         const Bool omit_flagged_data;
00261 
00262         std::unique_ptr<const MaskIterator> mask_iterator;
00263 
00264 private:
00265 
00266         void reset_iterators() {
00267                 data_iterator.reset();
00268                 weights_iterator.reset();
00269                 mask_iterator.reset();
00270         }
00271 
00272         virtual const Array<typename DataIterator::DataType>& dataArray() = 0;
00273 };
00274 
00275 // Data provider template for row-based MS columns (i.e, not visibilities) using
00276 // the 'weights' column for data weights. In most instances, you would not
00277 // weight the data in these columns, but the Vi2ChunkDataProvider template
00278 // requires that a WeightsIterator be provided.
00279 template<class DataIterator>
00280 using Vi2ChunkWeightsRowDataProvider =
00281         Vi2ChunkDataProvider<
00282         DataIterator,Vi2StatsFlagsRowIterator,Vi2StatsWeightsRowIterator>;
00283 
00284 // Data provider template for row-based MS columns (i.e, not visibilities) using
00285 // the 'sigma' column for data weights (appropriately transformed). In most
00286 // instances, you would not weight the data in these columns, but the
00287 // Vi2ChunkDataProvider template requires that a WeightsIterator be provided.
00288 template<class DataIterator>
00289 using Vi2ChunkSigmasRowDataProvider =
00290         Vi2ChunkDataProvider<
00291         DataIterator,Vi2StatsFlagsRowIterator,Vi2StatsSigmasRowIterator>;
00292 
00293 // Data provider template for cube-based MS columns (i.e, the visibilities)
00294 // using the 'weights' column for data weights.
00295 template<class DataIterator>
00296 using Vi2ChunkWeightsCubeDataProvider =
00297         Vi2ChunkDataProvider<
00298         DataIterator,Vi2StatsFlagsCubeIterator,Vi2StatsWeightsCubeIterator>;
00299 
00300 // Data provider template for cube-based MS columns (i.e, the visibilities)
00301 // using the 'sigma' column for data weights (appropriately transformed).
00302 template<class DataIterator>
00303 using Vi2ChunkSigmasCubeDataProvider =
00304         Vi2ChunkDataProvider<
00305         DataIterator,Vi2StatsFlagsCubeIterator,Vi2StatsSigmasCubeIterator>;
00306 
00307 } // end namespace casa
00308 
00309 #endif // MSVIS_STATISTICS_VI2_CHUNK_DATA_PROVIDER_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1