00001 //# SkyCal.h: this defines <ClassName>, which ... 00002 //# Copyright (C) 2003 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$ 00028 00029 #ifndef _SYNTHESIS_SKY_CAL_H_ 00030 #define _SYNTHESIS_SKY_CAL_H_ 00031 00032 #include <casa/Arrays/Matrix.h> 00033 00034 namespace casa { //# NAMESPACE CASA - BEGIN 00035 00036 // <summary> 00037 //#! A one line summary of the class. This summary (shortened a bit 00038 //#! if necessary so that it fits along with the "ClassFileName.h" in 75 00039 //#! characters) should also appear as the first line of this file. 00040 //#! Be sure to use the word "abstract" here if this class is, indeed, 00041 //#! an abstract base class. 00042 // </summary> 00043 00044 // <use visibility=local> or <use visibility=export> 00045 //#! If a class is intended for use by application programmers, or 00046 //#! people writing other libraries, then specify that this class 00047 //#! has an "export" visibility: it defines an interface that 00048 //#! will be seen outside of its module. On the other hand, if the 00049 //#! class has a "local" visibility, then it is known and used only 00050 //#! within its module. 00051 00052 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00053 //#! for example: 00054 //#! <reviewed reviewer="pshannon@nrao.edu" date="1994/10/10" tests="tMyClass, t1MyClass" demos="dMyClass, d1MyClass"> 00055 //#! This is a well-designed class, without any obvious problems. 00056 //#! However, the addition of several more demo programs would 00057 //#! go a *long* way towards making it more usable. 00058 //#! </reviewed> 00059 //#! 00060 //#! (In time, the documentation extractor will be able handle reviewed 00061 //#! attributes spread over more than one line.) 00062 //#! 00063 //#! see "Coding Standards and Guidelines" (AIPS++ note 167) and 00064 //#! "AIPS++ Code Review Process" (note 170) for a full explanation 00065 //#! It is up to the class author (the programmer) to fill in these fields: 00066 //#! tests, demos 00067 //#! The reviewer fills in 00068 //#! reviewer, date 00069 // </reviewed> 00070 00071 // <prerequisite> 00072 //#! Classes or concepts you should understand before using this class. 00073 // <li> SomeClass 00074 // <li> SomeOtherClass 00075 // <li> some concept 00076 // </prerequisite> 00077 // 00078 // <etymology> 00079 //#! Except when it is obvious (e.g., "Array") explain how the class name 00080 //#! expresses the role of this class. Example: IPosition is short for 00081 //#! "Integral Position" - a specialized integer vector for specifying 00082 //#! array dimensions and indices. 00083 // </etymology> 00084 // 00085 // <synopsis> 00086 //#! What does the class do? How? For whom? This should include code 00087 //#! fragments as appropriate to support text. Code fragments shall be 00088 //#! delimited by <srcblock> </srcblock> tags. The synopsis section will 00089 //#! usually be dozens of lines long. 00090 // </synopsis> 00091 // 00092 // <example> 00093 //#! One or two concise (~10-20 lines) examples, with a modest amount of 00094 //#! text to support code fragments. Use <srcblock> and </srcblock> to 00095 //#! delimit example code. 00096 // </example> 00097 // 00098 // <motivation> 00099 //#! Insight into a class is often provided by a description of 00100 //#! the circumstances that led to its conception and design. Describe 00101 //#! them here. 00102 // </motivation> 00103 // 00104 // <templating arg=T> 00105 //#! A list of member functions that must be provided by classes that 00106 //#! appear as actual template arguments. For example: imagine that you 00107 //#! are writing a templated sort class, which does a quicksort on a 00108 //#! list of arbitrary objects. Anybody who uses your templated class 00109 //#! must make sure that the actual argument class (say, Int or 00110 //#! String or Matrix) has comparison operators defined. 00111 //#! This tag must be repeated for each template formal argument in the 00112 //#! template class definition -- that's why this tag has the "arg" attribute. 00113 //#! (Most templated classes, however, are templated on only a single 00114 //#! argument.) 00115 // <li> 00116 // <li> 00117 // </templating> 00118 // 00119 // <thrown> 00120 //#! A list of exceptions thrown if errors are discovered in the function. 00121 //#! This tag will appear in the body of the header file, preceding the 00122 //#! declaration of each function which throws an exception. 00123 // <li> 00124 // <li> 00125 // </thrown> 00126 // 00127 // <todo asof="yyyy/mm/dd"> 00128 //#! A List of bugs, limitations, extensions or planned refinements. 00129 //#! The programmer should fill in a date in the "asof" field, which 00130 //#! will usually be the date at which the class is submitted for review. 00131 //#! If, during the review, new "todo" items come up, then the "asof" 00132 //#! date should be changed to the end of the review period. 00133 // <li> add this feature 00134 // <li> fix this bug 00135 // <li> start discussion of this possible extension 00136 // </todo> 00137 00138 template<class DataType, class CalDataType> 00139 class SkyCal 00140 { 00141 // all the member functions are inline 00142 public: 00143 SkyCal() 00144 : npol_(2), 00145 nchan_(1), 00146 m0_(NULL), 00147 ok0_(NULL), 00148 m_(NULL), 00149 mi_(NULL), 00150 ok_(NULL), 00151 oki_(NULL), 00152 cOne_(1.0), 00153 cZero_(0.0), 00154 scalardata_(False) 00155 {} 00156 00157 virtual ~SkyCal() {} 00158 00159 // stride 00160 // In Mueller series, typesize is defined as "number of polarizations" 00161 // while SkyCal definition is "number of elements in the DATA cell", 00162 // which is npol * nchan in practice. 00163 uInt typesize() const { return npol_ * nchan_; } 00164 void setNumChannel(uInt n) { nchan_ = n; } 00165 void setNumPolarization(uInt n) { npol_ = n; } 00166 00167 // Set scalardata_ 00168 // TBD: Handle this better; for now, we need to set this from 00169 // an external call so we handle single-corr data properly 00170 // when setting non-corr-dep flags 00171 void setScalarData(Bool scalardata) const { scalardata_=scalardata; } 00172 00173 // Synchronize with leading element in external array 00174 void sync(CalDataType& mat) { m0_=&mat; origin(); } 00175 void sync(CalDataType& mat, Bool& ok) { m0_=&mat; ok0_=&ok; origin(); } 00176 00177 // Reset to origin 00178 void origin() {m_=m0_;ok_=ok0_;} 00179 00180 // Increment to next vector (according to len) 00181 // In practice, this operator increments row index 00182 void operator++() { m_+=typesize(); if (ok_) ok_+=typesize();} 00183 void operator++(int) { m_+=typesize(); if (ok_) ok_+=typesize();} 00184 00185 // Advance step matrices forward (according to len) 00186 void advance(const Int& step) { m_+=(step*typesize()); if (ok_) ok_+=(step*typesize());} 00187 00188 // In-place invert 00189 void invert() {} 00190 00191 // Set matrix elements according to ok flag 00192 // (so we don't have to check ok flags atomically in apply) 00193 void setMatByOk() 00194 { 00195 throw(AipsError("Illegal use of SkyCal::setMatByOk")); 00196 } 00197 00198 // In-place multiply onto a data with flag information 00199 // apply implements position switch calibration: (ON - OFF)/OFF 00200 // 00201 // This processes the data corresponding to each DATA cell 00202 // (npol * nchan) together in contrast to Mueller series, which 00203 // processes one Stokes vector, i.e., process each channel 00204 // individually. 00205 void apply(Matrix<DataType>& v, Matrix<Bool> &f) 00206 { 00207 if (f.shape() == v.shape()) { 00208 flag(f); 00209 } 00210 00211 Bool deleteIt; 00212 DataType *data = v.getStorage(deleteIt); 00213 for (size_t i = 0; i < npol_ * nchan_; ++i) { 00214 // (ON - OFF) / OFF 00215 data[i] = (data[i] - m_[i]) / m_[i]; 00216 } 00217 v.putStorage(data, deleteIt); 00218 } 00219 00220 void apply(Matrix<DataType>& v, Matrix<Bool> &f, Vector<Bool>& vflag) 00221 { 00222 if (!ok_) throw(AipsError("Illegal use of SkyCal::applyFlag.")); 00223 00224 applyFlag(vflag); 00225 apply(v, f); 00226 } 00227 00228 // Apply only flags according to cal flags 00229 // 00230 // Similar to apply, flagging also processes each DATA cell together. 00231 void applyFlag(Vector<Bool>& vflag) 00232 { 00233 if (!ok_) throw(AipsError("Illegal use of SkyCal::applyFlag(vflag).")); 00234 00235 if (scalardata_) { 00236 for (size_t i = 0; i < nchan_; ++i) { 00237 vflag[i] |= (!ok_[0]); 00238 } 00239 } 00240 else { 00241 for (size_t i = 0; i < nchan_; ++i) { 00242 for (size_t j = 0; j < npol_; ++j) { 00243 vflag[i] |= !(ok_[i*npol_ + j]); 00244 } 00245 } 00246 } 00247 } 00248 00249 void flag(Matrix<Bool>& v) 00250 { 00251 Bool deleteIt; 00252 Bool *data = v.getStorage(deleteIt); 00253 for (size_t i = 0; i < typesize(); ++i) { 00254 data[i] |= (!ok_[i]); // data: False is valid, ok_: True is valid 00255 } 00256 v.putStorage(data, deleteIt); 00257 } 00258 00259 // Multiply onto a vis VisVector, preserving input (copy then in-place apply) 00260 void apply(Matrix<DataType>& out, Matrix<Bool> &outFlag, 00261 const Matrix<DataType>& in, const Matrix<Bool> &inFlag) 00262 { 00263 out = in; 00264 outFlag = inFlag; 00265 apply(out, outFlag); 00266 } 00267 00268 // print it out 00269 friend ostream& operator<<(ostream& os, const SkyCal<DataType, CalDataType>& mat) 00270 { 00271 return os; 00272 } 00273 00274 protected: 00275 00276 private: 00277 uInt npol_; 00278 uInt nchan_; 00279 00280 // Pointer to origin 00281 CalDataType *m0_; 00282 Bool *ok0_; 00283 00284 // Moving pointer 00285 CalDataType *m_, *mi_; 00286 Bool *ok_, *oki_; 00287 00288 // Complex unity, zero (for use in invert and similar methods) 00289 const CalDataType cOne_,cZero_; 00290 00291 mutable Bool scalardata_; 00292 00293 // Copy ctor protected 00294 SkyCal(const SkyCal<DataType, CalDataType>& mat); 00295 }; 00296 00297 } //# NAMESPACE CASA - END 00298 00299 //#include <synthesis/MeasurementComponents/SkyCal.tcc> 00300 00301 #endif /* _SYNTHESIS_SKY_CAL_H_ */ 00302 00303 00304