casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Mueller.h
Go to the documentation of this file.
00001 //# Mueller.h: Definition of Mueller
00002 //# Copyright (C) 1996,1997,2000,2001,2002,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 adressed 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 
00028 #ifndef SYNTHESIS_MUELLER_H
00029 #define SYNTHESIS_MUELLER_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/BasicSL/Complex.h>
00033 #include <casa/iostream.h>
00034 #include <casa/Exceptions/Error.h>
00035 #include <synthesis/MeasurementComponents/VisVector.h>
00036 #include <synthesis/MeasurementComponents/Jones.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 class Mueller {
00041   
00042 public:
00043   
00044   enum MuellerType{AddDiag2=6,AddDiag=5,General=4,Diagonal=3,Diag2=2,Scalar=1};
00045  
00046   // Construct 
00047   Mueller();
00048   
00049   // Dtor
00050   virtual ~Mueller() {};
00051   
00052   // Return type id
00053   inline virtual MuellerType type() const { return Mueller::General; };
00054   inline virtual uInt typesize() const { return 16; };
00055 
00056   // Set scalardata_ 
00057   //  TBD: Handle this better; for now, we need to set this from
00058   //       an external call so we handle single-corr data properly
00059   //       when setting non-corr-dep flags
00060   inline void setScalarData(Bool scalardata) const { scalardata_=scalardata; };
00061   
00062   // Synchronize with leading element in external array
00063   inline void sync(Complex& mat) { m0_=&mat; origin(); };
00064   inline void sync(Complex& mat, Bool& ok) { m0_=&mat; ok0_=&ok; origin(); };
00065   
00066   // Reset to origin
00067   inline void origin() {m_=m0_;ok_=ok0_;};
00068   
00069   // Increment to next vector (according to len)
00070   inline void operator++()    { m_+=typesize(); if (ok_) ok_+=typesize();};
00071   inline void operator++(int) { m_+=typesize(); if (ok_) ok_+=typesize();};
00072 
00073   // Advance step matrices forward (according to len)
00074   inline void advance(const Int& step) { m_+=(step*typesize()); if (ok_) ok_+=(step*typesize());};
00075 
00076   // Formation from Jones matrix outer product: General version
00077   virtual void fromJones(const Jones& jones1, const Jones& jones2);
00078 
00079   // In-place invert
00080   virtual void invert();
00081 
00082   // Set matrix elements according to ok flag
00083   //  (so we don't have to check ok flags atomically in apply)
00084   virtual void setMatByOk();
00085 
00086   // In-place multiply onto a VisVector: General version
00087   virtual void apply(VisVector& v);
00088   virtual void apply(VisVector& v, Bool& vflag);
00089 
00090   // Apply only flags according to cal flags
00091   virtual void applyFlag(Bool& vflag);
00092 
00093   // Multiply onto a vis VisVector, preserving input (copy then in-place apply)
00094   virtual void apply(VisVector& out, const VisVector& in);
00095 
00096   // print it out
00097   friend ostream& operator<<(ostream& os, const Mueller& mat);
00098     
00099 protected:
00100   
00101   // Copy ctor protected 
00102   Mueller(const Mueller& mat);
00103 
00104   // Pointer to origin
00105   Complex *m0_;
00106   Bool *ok0_;
00107 
00108   // Moving pointer
00109   Complex *m_, *mi_;
00110   Bool *ok_, *oki_;
00111 
00112   // Complex unity, zero (for use in invert and similar methods)
00113   const Complex cOne_,cZero_;
00114 
00115   mutable Bool scalardata_;
00116 
00117 private: 
00118 
00119   // Zero the whole Mueller
00120   virtual void zero();
00121 
00122   // VisVector temporary (only relevant for Mueller::General)
00123   VisVector vtmp_;
00124 
00125 
00126   
00127 };
00128 
00129 class MuellerDiag : public Mueller {
00130 
00131 public:
00132   
00133   // Construct 
00134   MuellerDiag();
00135   
00136   // Dtor
00137   virtual ~MuellerDiag() {};
00138   
00139   // Return type id
00140   inline virtual MuellerType type() const { return Mueller::Diagonal; };
00141   inline virtual uInt typesize() const { return 4; };
00142 
00143   // Formation from Jones matrix outer product: optimized Diagonal version
00144   virtual void fromJones(const Jones& jones1, const Jones& jones2);
00145   
00146   // In-place invert
00147   virtual void invert();
00148 
00149   // Set matrix elements according to ok flag
00150   //  (so we don't have to check ok flags atomically in apply)
00151   virtual void setMatByOk();
00152 
00153   // In-place multiply onto a VisVector: optimized Diagonal version
00154   virtual void apply(VisVector& v);
00155   virtual void apply(VisVector& v, Bool& vflag);
00156   using Mueller::apply;
00157 
00158   // Apply only flags according to cal flags
00159   virtual void applyFlag(Bool& vflag);
00160 
00161 protected:
00162   
00163   // Default/Copy ctors are protected 
00164   MuellerDiag(const MuellerDiag& mat);
00165 
00166 private: 
00167 
00168   // Zero the whole Mueller
00169   virtual void zero();
00170   
00171 };
00172 
00173 class MuellerDiag2 : public MuellerDiag {
00174   
00175 public:
00176 
00177   // Construct 
00178   MuellerDiag2();
00179 
00180   // Dtor
00181   virtual ~MuellerDiag2() {};
00182   
00183   // Return type id
00184   inline virtual MuellerType type() const { return Mueller::Diag2; };
00185   inline virtual uInt typesize() const { return 2; };
00186 
00187   // Formation from Jones matrix outer product: optimized Diag2 version
00188   virtual void fromJones(const Jones& jones1, const Jones& jones2);
00189   
00190   // In-place invert
00191   virtual void invert();
00192 
00193   // Set matrix elements according to ok flag
00194   //  (so we don't have to check ok flags atomically in apply)
00195   virtual void setMatByOk();
00196 
00197   // In-place multiply onto a VisVector: optimized Diag2 version
00198   virtual void apply(VisVector& v);
00199   virtual void apply(VisVector& v, Bool& vflag);
00200   using MuellerDiag::apply;
00201 
00202   // Apply only flags according to cal flags
00203   virtual void applyFlag(Bool& vflag);
00204 
00205 protected:
00206   
00207   // Default/Copy ctors are protected 
00208   MuellerDiag2(const MuellerDiag2& mat);
00209   
00210 private: 
00211 
00212   // Zero the whole Mueller
00213   virtual void zero();
00214 
00215 };
00216 
00217 
00218 class MuellerScal : public MuellerDiag {
00219  
00220 public:
00221 
00222   // Construct 
00223   MuellerScal();
00224 
00225   // Dtor
00226   virtual ~MuellerScal() {};
00227 
00228   // Return type id
00229   inline virtual MuellerType type() const { return Mueller::Scalar; }
00230   inline virtual uInt typesize() const { return 1; };
00231 
00232   // Formation from Jones matrix outer product: optimized Scalar version
00233   virtual void fromJones(const Jones& jones1, const Jones& jones2);
00234 
00235   // In-place invert
00236   virtual void invert();
00237 
00238   // Set matrix elements according to ok flag
00239   //  (so we don't have to check ok flags atomically in apply)
00240   virtual void setMatByOk();
00241 
00242   // In-place multiply onto a VisVector: optimized Scalar version
00243   virtual void apply(VisVector& v);
00244   virtual void apply(VisVector& v, Bool& vflag);
00245   using MuellerDiag::apply;
00246 
00247   // Apply only flags according to cal flags
00248   virtual void applyFlag(Bool& vflag);
00249 
00250 protected:
00251   
00252   // Default/Copy ctors are protected 
00253   MuellerScal(const MuellerScal& mat);
00254 
00255 private: 
00256 
00257   // Zero the whole Mueller
00258   virtual void zero();
00259 
00260 };
00261 
00262 
00263 // Parallel-hands only "additive Mueller"
00264 class AddMuellerDiag2 : public MuellerDiag2 {
00265   
00266 public:
00267 
00268   // Construct 
00269   AddMuellerDiag2();
00270 
00271   // Dtor
00272   virtual ~AddMuellerDiag2() {};
00273   
00274   // Return type id
00275   inline virtual MuellerType type() const { return Mueller::AddDiag2; };
00276 
00277   // In-place invert (negate)
00278   virtual void invert();
00279 
00280   // Set matrix elements according to ok flag
00281   //  (so we don't have to check ok flags atomically in apply)
00282   virtual void setMatByOk();
00283 
00284   // In-place add onto a VisVector: optimized Diag2 version
00285   virtual void apply(VisVector& v);
00286   using MuellerDiag2::apply;
00287 
00288 protected:
00289   
00290   // Default/Copy ctors are protected 
00291   AddMuellerDiag2(const AddMuellerDiag2& mat);
00292   
00293 };
00294 
00295 
00296 // Full polarization "additive Mueller"
00297 class AddMuellerDiag : public MuellerDiag {
00298   
00299 public:
00300 
00301   // Construct 
00302   AddMuellerDiag();
00303 
00304   // Dtor
00305   virtual ~AddMuellerDiag() {};
00306   
00307   // Return type id
00308   inline virtual MuellerType type() const { return Mueller::AddDiag; };
00309 
00310   // In-place invert (negate)
00311   virtual void invert();
00312 
00313   // Set matrix elements according to ok flag
00314   //  (so we don't have to check ok flags atomically in apply)
00315   virtual void setMatByOk();
00316 
00317   // In-place add onto a VisVector:
00318   virtual void apply(VisVector& v);
00319   using MuellerDiag::apply;
00320 
00321 protected:
00322   
00323   // Default/Copy ctors are protected 
00324   AddMuellerDiag(const AddMuellerDiag& mat);
00325   
00326 };
00327 
00328 
00329 
00330 
00331 // Globals
00332 
00333 // Factory method
00334 Mueller* createMueller(const Mueller::MuellerType& mtype);
00335 
00336 // Return Mueller type according to Int
00337 //Mueller::MuellerType muellerType(const Int& n);
00338 
00339 // Return parameter count according to type
00340 inline Int muellerNPar(const Mueller::MuellerType& mtype) {
00341   switch (mtype) {
00342   case Mueller::General:
00343     return 16;
00344     break;
00345   case Mueller::Diagonal:
00346   case Mueller::AddDiag:
00347     return 4;
00348     break;
00349   case Mueller::Diag2:
00350   case Mueller::AddDiag2:
00351     return 2;
00352     break;
00353   case Mueller::Scalar:
00354     return 1;
00355     break;
00356   }
00357   // must return something (shouldn't reach here)
00358   return 0;
00359 }
00360     
00361 
00362 // Return Mueller type according to underlying Jones and VisVector types
00363 Mueller::MuellerType muellerType(const Jones::JonesType& jtype, const VisVector::VisType& vtype);
00364 
00365 } //# NAMESPACE CASA - END
00366 
00367 #endif
00368