Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

covariance.h

Go to the documentation of this file.
00001 /*
00002 Arroyo - software for the simulation of electromagnetic wave propagation
00003 through turbulence and optics.
00004 
00005 Copyright (c) 2000-2004 California Institute of Technology.  Written by
00006 Dr. Matthew Britton.  For comments or questions about this software,
00007 please contact the author at mbritton@astro.caltech.edu.
00008 
00009 This program is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as  published by the
00011 Free Software Foundation; either version 2 of the License, or (at your
00012 option) any later version.
00013 
00014 This program is provided "as is" and distributed in the hope that it
00015 will be useful, but WITHOUT ANY WARRANTY; without even the implied
00016 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  In no
00017 event shall California Institute of Technology be liable to any party
00018 for direct, indirect, special, incidental or consequential damages,
00019 including lost profits, arising out of the use of this software and its
00020 documentation, even if the California Institute of Technology has been
00021 advised of the possibility of such damage.   The California Institute of
00022 Technology has no obligation to provide maintenance, support, updates,
00023 enhancements or modifications.  See the GNU General Public License for
00024 more details.
00025 
00026 You should have received a copy of the GNU General Public License along
00027 with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00029 */
00030 
00031 #ifndef COVARIANCE_H
00032 #define COVARIANCE_H
00033 
00034 #include <string>
00035 #include <iostream>
00036 #include <vector>
00037 #include "AO_sim_base.h"
00038 #include "pixel_array.h"
00039 #include "aperture.h"
00040 #include "refractive_atmosphere.h"
00041 
00042 namespace Arroyo {
00043   class iofits;
00044 }
00045 
00046 namespace Arroyo {
00047 
00048   using std::string;
00049 
00054 
00055   template<typename precision, typename aperture_type>
00056     class phase_covariance :
00057     public AO_sim_base {
00058 
00059     private:
00060 
00061     phase_covariance(){
00062       cerr << "phase_covariance::phase_covariance error - unsupported\n";
00063       exit(-1);
00064     }
00065   };
00066 
00067 
00072 
00073   template<typename precision>
00074     class phase_covariance<precision, circular_aperture> :
00075     public AO_sim_base {
00076     
00077     private:
00078 
00079     static const bool factory_registration;
00080 
00083     string unique_name() const {return(string("circular phase covariance"));};
00084 
00085     protected:
00086 
00087     refractive_atmospheric_model ref_atm_model;
00088     circular_aperture circ_ap;
00089 
00090     mutable double pixel_scale_meters;
00091     mutable int nsteps_in_integration;
00092 
00093     mutable pixel_array<precision> stored_caliph_A;
00094     mutable pixel_array<precision> stored_caliph_B;
00095     mutable precision stored_caliph_D;
00096     mutable precision stored_caliph_M;
00097 
00098     emitter * emtr_a;
00099     emitter * emtr_b;
00100 
00101     static double Xi;
00102 
00103     void initialize_integration(int nsteps_in_integration) const;
00104 
00105     void initialize_pixel_scale(double pixel_scale_meters) const;
00106 
00107     public:
00108 
00111     phase_covariance(){
00112       emtr_a = NULL;
00113       emtr_b = NULL;
00114     };
00115 
00118     phase_covariance(const emitter & emtr1,
00119                      const emitter & emtr2,
00120                      const refractive_atmospheric_model & ref_atm_model,
00121                      const circular_aperture & circ_ap);
00122     
00125     ~phase_covariance(){
00126       delete emtr_a;
00127       delete emtr_b;
00128     };
00129 
00132     phase_covariance(const phase_covariance & pcv){
00133       this->operator=(pcv);
00134     };
00135 
00138     phase_covariance(const char * filename){
00139       this->read(filename);
00140     };
00141 
00144     phase_covariance(const iofits & iof){
00145       this->read(iof);
00146     };
00147 
00150     phase_covariance & operator=(const phase_covariance & pcv);
00151 
00154     void read(const char * filename);
00155 
00158     void read(const Arroyo::iofits & iof);
00159 
00162     void write(const char * filename) const;
00163 
00166     void write(Arroyo::iofits & iof) const;
00167 
00170     void print(std::ostream & os, const char * prefix = "") const;
00171 
00174     const refractive_atmospheric_model & get_model() const {
00175       return(this->ref_atm_model);
00176     };
00177 
00180     circular_aperture get_aperture() const {
00181       return(this->circ_ap);
00182     };
00183 
00186     const emitter & get_first_emitter() const {
00187       return(*(this->emtr_a));
00188     };
00189 
00192     const emitter & get_second_emitter() const {
00193       return(*(this->emtr_b));
00194     };
00195 
00198     double aperture_averaged_variance(double wavelength_meters,
00199                                       int nsteps_in_integration) const;
00200 
00204     double variance(double wavelength_meters,
00205                     int nsteps_in_integration,
00206                     const three_point & tp) const;
00207 
00210     pixel_array<precision> variance(double pixel_scale_meters,
00211                                     double wavelength_meters,
00212                                     int nsteps_in_integration) const;
00213     
00217     double covariance(double wavelength_meters,
00218                       int nsteps_in_integration,
00219                       const three_point & tp1,
00220                       const three_point & tp2) const;
00221 
00225     pixel_array<precision> covariance(double pixel_scale_meters,
00226                                       double wavelength_meters,
00227                                       int nsteps_in_integration,
00228                                       const three_point & tp,
00229                                       bool first_arg = true) const;
00230 
00235     pixel_array<precision> covariance(double pixel_scale_meters,
00236                                       double wavelength_meters,
00237                                       int nsteps_in_integration,
00238                                       int xindex,
00239                                       int yindex,
00240                                       bool first_arg = true) const;
00241 
00242   };
00243 
00244   /*
00249 
00250   template<typename precision>
00251     class phase_covariance<precision, annular_aperture> :
00252     public AO_sim_base {
00253     
00254     private:
00255 
00256     static const bool factory_registration;
00257 
00260     string unique_name() const {return(string("annular phase covariance"));};
00261 
00262     protected:
00263 
00264 
00265     public:
00266 
00269     phase_covariance(){};
00270 
00273     phase_covariance(const emitter & emtr1,
00274                      const emitter & emtr2,
00275                      const refractive_atmospheric_model & ref_atm_model,
00276                      const annular_aperture & annular_ap);
00277     
00280     ~phase_covariance(){};
00281 
00284     phase_covariance(const phase_covariance & pcv){
00285       this->operator=(pcv);
00286     };
00287 
00290     phase_covariance(const char * filename){
00291       this->read(filename);
00292     };
00293 
00296     phase_covariance(const iofits & iof){
00297       this->read(iof);
00298     };
00299 
00302     phase_covariance & operator=(const phase_covariance & pcv);
00303 
00306     void read(const char * filename);
00307 
00310     void read(const Arroyo::iofits & iof);
00311 
00314     void write(const char * filename) const;
00315 
00318     void write(Arroyo::iofits & iof) const;
00319 
00322     void print(std::ostream & os, const char * prefix = "") const;
00323 
00326     const refractive_atmospheric_model & get_model() const {
00327       return(this->outer_aperture_phase_covariance.get_model());
00328     };
00329 
00332     annular_aperture get_aperture() const {
00333       annular_aperture annular_ap(this->inner_aperture_phase_covariance.get_aperture().get_diameter(),
00334                                   this->outer_aperture_phase_covariance.get_aperture().get_diameter());
00335       annular_ap.three_frame::operator=(this->outer_aperture_phase_covariance.get_aperture());
00336       return(annular_ap);
00337     };
00338 
00341     const emitter & get_first_emitter() const {
00342       return(this->outer_aperture_phase_covariance.get_first_emitter());
00343     };
00344 
00347     const emitter & get_second_emitter() const {
00348       return(this->outer_aperture_phase_covariance.get_second_emitter());
00349     };
00350 
00353     double aperture_averaged_variance(double wavelength_meters,
00354                                       int nsteps_in_integration) const;
00355 
00359     double variance(double wavelength_meters,
00360                     int nsteps_in_integration,
00361                     const three_point & tp) const;
00362 
00365     pixel_array<precision> variance(double pixel_scale_meters,
00366                                     double wavelength_meters,
00367                                     int nsteps_in_integration) const;
00368     
00372     double covariance(double wavelength_meters,
00373                       int nsteps_in_integration,
00374                       const three_point & tp1,
00375                       const three_point & tp2) const;
00376 
00380     pixel_array<precision> covariance(double pixel_scale_meters,
00381                                       double wavelength_meters,
00382                                       int nsteps_in_integration,
00383                                       const three_point & tp,
00384                                       bool first_arg = true) const;
00385 
00390     pixel_array<precision> covariance(double pixel_scale_meters,
00391                                       double wavelength_meters,
00392                                       int nsteps_in_integration,
00393                                       int xindex,
00394                                       int yindex,
00395                                       bool first_arg = true) const;
00396 
00397   };
00398   */
00399 
00400 
00405 
00406   template<typename precision, typename aperture_type>
00407     class tilt_covariance :
00408     public AO_sim_base {
00409 
00410     private:
00411 
00412     tilt_covariance(){
00413       cerr << "tilt_covariance::tilt_covariance error - unsupported\n";
00414       exit(-1);
00415     }
00416   };
00417 
00418 
00423 
00424   template<typename precision>
00425     class tilt_covariance<precision, circular_aperture> :
00426     public AO_sim_base {
00427     
00428     private:
00429 
00430     static const bool factory_registration;
00431 
00434     string unique_name() const {return(string("circular tilt covariance"));};
00435 
00436     protected:
00437 
00438     refractive_atmospheric_model ref_atm_model;
00439     circular_aperture circ_ap;
00440 
00441     mutable double pixel_scale_meters;
00442     mutable int nsteps_in_integration;
00443 
00444     mutable pixel_array<precision> stored_caliph_G;
00445     mutable pixel_array<precision> stored_caliph_H;
00446     mutable pixel_array<precision> stored_caliph_I;
00447     mutable pixel_array<precision> stored_caliph_J;
00448     mutable precision stored_caliph_E;
00449     mutable precision stored_caliph_F;
00450     mutable precision stored_caliph_F_bar;
00451     mutable precision stored_caliph_K;
00452     mutable precision stored_caliph_L;
00453 
00454     emitter * emtr_a;
00455     emitter * emtr_b;
00456 
00457     three_vector omega_hat;
00458 
00459     static double Xi;
00460 
00461     void initialize_integration(int nsteps_in_integration) const;
00462 
00463     void initialize_pixel_scale(double pixel_scale_meters) const;
00464 
00465     public:
00466 
00469     tilt_covariance(){
00470       emtr_a = NULL;
00471       emtr_b = NULL;
00472     };
00473 
00476     tilt_covariance(const emitter & emtr1,
00477                     const emitter & emtr2,
00478                     const refractive_atmospheric_model & ref_atm_model,
00479                     const circular_aperture & circ_ap);
00480     
00483     ~tilt_covariance(){
00484       delete emtr_a;
00485       delete emtr_b;
00486     };
00487 
00490     tilt_covariance(const tilt_covariance & tcv){
00491       this->operator=(tcv);
00492     };
00493 
00496     tilt_covariance(const char * filename){
00497       this->read(filename);
00498     };
00499 
00502     tilt_covariance(const iofits & iof){
00503       this->read(iof);
00504     };
00505 
00508     tilt_covariance & operator=(const tilt_covariance & tcv);
00509 
00512     void read(const char * filename);
00513 
00516     void read(const Arroyo::iofits & iof);
00517 
00520     void write(const char * filename) const;
00521 
00524     void write(Arroyo::iofits & iof) const;
00525 
00528     void print(std::ostream & os, const char * prefix = "") const;
00529 
00532     const refractive_atmospheric_model & get_model() const {
00533       return(this->ref_atm_model);
00534     };
00535 
00538     circular_aperture get_aperture() const {
00539       return(this->circ_ap);
00540     };
00541 
00544     const emitter & get_first_emitter() const {
00545       return(*(this->emtr_a));
00546     };
00547 
00550     const emitter & get_second_emitter() const {
00551       return(*(this->emtr_b));
00552     };
00553 
00556     double aperture_averaged_variance(double wavelength_meters,
00557                                       int nsteps_in_integration) const;
00558 
00562     double variance(double wavelength_meters,
00563                     int nsteps_in_integration,
00564                     const three_point & tp) const;
00565 
00568     pixel_array<precision> variance(double pixel_scale_meters,
00569                                     double wavelength_meters,
00570                                     int nsteps_in_integration) const;
00571     
00575     double covariance(double wavelength_meters,
00576                       int nsteps_in_integration,
00577                       const three_point & tp1,
00578                       const three_point & tp2) const;
00579 
00583     pixel_array<precision> covariance(double pixel_scale_meters,
00584                                       double wavelength_meters,
00585                                       int nsteps_in_integration,
00586                                       const three_point & tp,
00587                                       bool first_arg = true) const;
00588 
00593     pixel_array<precision> covariance(double pixel_scale_meters,
00594                                       double wavelength_meters,
00595                                       int nsteps_in_integration,
00596                                       int xindex,
00597                                       int yindex,
00598                                       bool first_arg = true) const;
00599 
00600   };
00601 
00602   /*
00607 
00608   template<typename precision>
00609     class tilt_covariance<precision, annular_aperture> :
00610     public AO_sim_base {
00611     
00612     private:
00613 
00614     static const bool factory_registration;
00615 
00618     string unique_name() const {return(string("annular tilt covariance"));};
00619 
00620     protected:
00621     
00622     tilt_covariance<precision, circular_aperture> outer_aperture_tilt_covariance;
00623     tilt_covariance<precision, circular_aperture> inner_aperture_tilt_covariance;
00624 
00625     public:
00626 
00629     tilt_covariance(){};
00630 
00633     tilt_covariance(const emitter & emtr1,
00634                     const emitter & emtr2,
00635                     const refractive_atmospheric_model & ref_atm_model,
00636                     const annular_aperture & annular_ap);
00637     
00640     ~tilt_covariance(){};
00641 
00644     tilt_covariance(const tilt_covariance & tcv){
00645       this->operator=(tcv);
00646     };
00647 
00650     tilt_covariance(const char * filename){
00651       this->read(filename);
00652     };
00653 
00656     tilt_covariance(const iofits & iof){
00657       this->read(iof);
00658     };
00659 
00662     tilt_covariance & operator=(const tilt_covariance & tcv);
00663 
00666     void read(const char * filename);
00667 
00670     void read(const Arroyo::iofits & iof);
00671 
00674     void write(const char * filename) const;
00675 
00678     void write(Arroyo::iofits & iof) const;
00679 
00682     void print(std::ostream & os, const char * prefix = "") const;
00683 
00686     const refractive_atmospheric_model & get_model() const {
00687       return(this->outer_aperture_tilt_covariance.get_model());
00688     };
00689 
00692     annular_aperture get_aperture() const {
00693       annular_aperture annular_ap(this->inner_aperture_tilt_covariance.get_aperture().get_diameter(),
00694                                   this->outer_aperture_tilt_covariance.get_aperture().get_diameter());
00695       annular_ap.three_frame::operator=(this->outer_aperture_tilt_covariance.get_aperture());
00696       return(annular_ap);
00697     };
00698 
00701     const emitter & get_first_emitter() const {
00702       return(this->outer_aperture_tilt_covariance.get_first_emitter());
00703     };
00704 
00707     const emitter & get_second_emitter() const {
00708       return(this->outer_aperture_tilt_covariance.get_second_emitter());
00709     };
00710 
00713     double aperture_averaged_variance(double wavelength_meters,
00714                                       int nsteps_in_integration) const;
00715 
00719     double variance(double wavelength_meters,
00720                     int nsteps_in_integration,
00721                     const three_point & tp) const;
00722 
00725     pixel_array<precision> variance(double pixel_scale_meters,
00726                                     double wavelength_meters,
00727                                     int nsteps_in_integration) const;
00728     
00732     double covariance(double wavelength_meters,
00733                       int nsteps_in_integration,
00734                       const three_point & tp1,
00735                       const three_point & tp2) const;
00736 
00740     pixel_array<precision> covariance(double pixel_scale_meters,
00741                                       double wavelength_meters,
00742                                       int nsteps_in_integration,
00743                                       const three_point & tp,
00744                                       bool first_arg = true) const;
00745 
00750     pixel_array<precision> covariance(double pixel_scale_meters,
00751                                       double wavelength_meters,
00752                                       int nsteps_in_integration,
00753                                       int xindex,
00754                                       int yindex,
00755                                       bool first_arg = true) const;
00756 
00757   };
00758   */
00759 
00760   namespace {
00761 
00762     template <typename precision> 
00763       void add_val_to_pixarr(pixel_array<precision> & pixarr,
00764                              precision & val,
00765                              double normalization_factor){
00766 
00767       vector<long> axes = pixarr.get_axes();
00768       double x_halfpix=0, y_halfpix=0;
00769       int x_extrapix=1, y_extrapix=1;
00770       if(axes[1]%2==0){
00771         x_halfpix = .5;
00772         x_extrapix = 0;
00773       }
00774       if(axes[0]%2==0){
00775         y_halfpix = .5;
00776         y_extrapix = 0;
00777       }
00778       three_frame tf;
00779       double val2;
00780       int index;
00781       three_vector pixel_vector;        
00782       for(int m=-axes[1]/2; m<axes[1]/2+x_extrapix; m++){
00783         for(int n=-axes[0]/2; n<axes[0]/2+y_extrapix; n++){
00784           pixel_vector = three_vector((m+x_halfpix)*normalization_factor,
00785                                       (n+y_halfpix)*normalization_factor,
00786                                       0,
00787                                       tf);
00788           index = (m+axes[1]/2)*axes[0]+n+axes[0]/2;
00789           if(pixel_vector.length_squared()<=1){
00790             val2 = pixarr.data(index);
00791             pixarr.set_data(index, val+val2);
00792           }
00793         }
00794       }
00795     }
00796 
00797     void get_omega_hat(const emitter & emtr_a,
00798                        const emitter & emtr_b,
00799                        const three_frame & tf,
00800                        three_vector & omega_hat) {
00801 
00802       three_vector emtr_a_unit_vector = 
00803         emtr_a.get_emission_vector(static_cast<const three_point>(tf));
00804       three_vector emtr_b_unit_vector = 
00805         emtr_b.get_emission_vector(static_cast<const three_point>(tf));
00806 
00807       double emtr_a_range_meters = 1e300;
00808       double emtr_b_range_meters = 1e300;
00809 
00810       const spherical_wave_emitter * swe;
00811       if((swe=dynamic_cast<const spherical_wave_emitter *>(&emtr_a)))
00812         emtr_a_range_meters = (*swe - tf).length();
00813       if(swe=dynamic_cast<const spherical_wave_emitter *>(&emtr_b))
00814         emtr_b_range_meters = (*swe - tf).length();
00815 
00816       three_vector max_range_unit_vector, min_range_unit_vector;
00817       if(emtr_a_range_meters>emtr_b_range_meters){
00818         max_range_unit_vector = emtr_a_unit_vector;
00819         min_range_unit_vector = emtr_b_unit_vector;
00820       } else {
00821         max_range_unit_vector = emtr_b_unit_vector;
00822         min_range_unit_vector = emtr_a_unit_vector;
00823       }
00824 
00825       if((max_range_unit_vector - min_range_unit_vector).length()<three_frame::precision){
00826         omega_hat = three_vector();
00827       } else {
00828         omega_hat = (max_range_unit_vector - min_range_unit_vector);
00829         omega_hat *= (1/omega_hat.length());
00830       }
00831     }
00832   }
00833 
00834   template<typename precision>
00835   double phase_covariance<precision, circular_aperture>::Xi = get_Xi();
00836 
00837   template<typename precision>
00838     void phase_covariance<precision, circular_aperture>::
00839     initialize_integration(int nsteps_in_integration) const {
00840 
00841     try{
00842 
00843       if(this->emtr_a==NULL || this->emtr_b==NULL){
00844         cerr << "phase_covariance::initialize_integration error - uninitialized emitters\n";
00845         throw(string("phase_covariance::initialize_integration"));
00846       }
00847 
00848       if(this->nsteps_in_integration==nsteps_in_integration)
00849         return;
00850       
00851       this->nsteps_in_integration = nsteps_in_integration;    
00852       stored_caliph_D = this->ref_atm_model.caliph_D(*(this->emtr_a),
00853                                                      *(this->emtr_b),
00854                                                      this->circ_ap.get_diameter(),
00855                                                      this->nsteps_in_integration);
00856     } catch(...) {
00857       cerr << "phase_covariance::initialize_integration error\n";
00858       this->emtr_a->print(cerr, "\temtra");
00859       this->emtr_b->print(cerr, "\temtrb");
00860       cout << "ap diameter " << this->circ_ap.get_diameter()
00861            << "\tnsteps in integration " << this->nsteps_in_integration
00862            << endl;
00863       throw(string("phase_covariance::initialize_integration"));
00864     }
00865   }
00866   
00867   template<typename precision>
00868     void phase_covariance<precision, circular_aperture>::
00869     initialize_pixel_scale(double pixel_scale_meters) const {
00870 
00871     try{
00872 
00873       if(this->emtr_a==NULL || this->emtr_b==NULL){
00874         cerr << "phase_covariance::initialize_pixel_scale error - uninitialized emitters\n";
00875         throw(string("phase_covariance::initialize_pixel_scale"));
00876       }
00877 
00878       if(this->pixel_scale_meters==pixel_scale_meters)
00879         return;
00880       
00881       this->pixel_scale_meters = pixel_scale_meters;
00882       stored_caliph_A = 
00883         this->ref_atm_model.template caliph_A<precision>(*(this->emtr_a),
00884                                                          *(this->emtr_b),
00885                                                          this->circ_ap.get_diameter(),
00886                                                          this->pixel_scale_meters);
00887       stored_caliph_B = 
00888         this->ref_atm_model.template caliph_B<precision>(*(this->emtr_a),
00889                                                          *(this->emtr_b),
00890                                                          this->circ_ap.get_diameter(),
00891                                                          this->pixel_scale_meters);
00892     } catch(...) {
00893       cerr << "phase_covariance::initialize_pixel_scale error\n";
00894       this->emtr_a->print(cerr, "\temtra");
00895       this->emtr_b->print(cerr, "\temtrb");
00896       cout << "ap diameter " << this->circ_ap.get_diameter()
00897            << "\tnsteps in integration " << this->pixel_scale_meters
00898            << endl;
00899       throw(string("phase_covariance::initialize_pixel_scale"));
00900     }
00901   }
00902 
00903   template<typename precision>
00904     phase_covariance<precision, circular_aperture>::
00905     phase_covariance(const emitter & emtr_a,
00906                      const emitter & emtr_b,
00907                      const refractive_atmospheric_model & ref_atm_model,
00908                      const circular_aperture & circ_ap) {
00909 
00910     this->emtr_a = emitter::emitter_factory(&emtr_a);
00911     this->emtr_b = emitter::emitter_factory(&emtr_b);
00912 
00913     this->ref_atm_model = ref_atm_model;
00914 
00915     this->circ_ap = circ_ap;
00916 
00917     stored_caliph_D = -1;
00918     stored_caliph_M = -1;
00919     pixel_scale_meters = -1;
00920     nsteps_in_integration = -1;
00921   }
00922 
00923   template<typename precision>
00924     phase_covariance<precision, circular_aperture> &
00925     phase_covariance<precision, circular_aperture>::operator=(const phase_covariance & pcv) {
00926 
00927     this->emtr_a = emitter::emitter_factory(pcv.emtr_a);
00928     this->emtr_b = emitter::emitter_factory(pcv.emtr_b);
00929 
00930     this->ref_atm_model = pcv.ref_atm_model;
00931     this->circ_ap = pcv.circ_ap;
00932     
00933     this->pixel_scale_meters = pcv.pixel_scale_meters;
00934     this->nsteps_in_integration = pcv.nsteps_in_integration;
00935 
00936     this->stored_caliph_A = pcv.stored_caliph_A;
00937     this->stored_caliph_B = pcv.stored_caliph_B;
00938     this->stored_caliph_D = pcv.stored_caliph_D;
00939     this->stored_caliph_M = pcv.stored_caliph_M;
00940   }
00941 
00942   template<typename precision>
00943     void phase_covariance<precision, circular_aperture>::read(const char * filename){
00944     iofits iof;
00945     try{iof.open(filename);}
00946     catch(...){
00947       cerr << "phase_covariance::read - "
00948            << "error opening file " << filename << endl;
00949       throw(string("phase_covariance::read"));
00950     }
00951     try{this->read(iof);}
00952     catch(...){
00953       cerr << "phase_covariance::read - "
00954            << "error reading "
00955            << this->unique_name() << " from file " 
00956            << filename << endl;
00957       throw(string("phase_covariance::read"));
00958     }
00959   }
00960   
00961   template<typename precision>
00962     void phase_covariance<precision, circular_aperture>::read(const Arroyo::iofits & iof){
00963 
00964     string type, comment;
00965     if (!iof.key_exists("TYPE"))
00966       {
00967         cerr << this->unique_name() << "::read error - unrecognized "
00968              << "file type" << endl;
00969         throw(this->unique_name() + string("::read"));
00970       }
00971     iof.read_key("TYPE",type,comment);
00972     if(type!=this->unique_name()){
00973       cerr << this->unique_name() << "::read error - file of type: " 
00974            << type << " rather than type " << this->unique_name() << endl;
00975       throw(this->unique_name() + string("::read"));
00976     }
00977 
00978     // Move to the next HDU
00979     iof.movrel_hdu(1);
00980 
00981     try{
00982       this->emtr_a = emitter::emitter_factory(iof);
00983     } catch(...){
00984       cerr << "phase_covariance::read error - could not read first emitter\n";
00985       throw(string("phase_covariance::read"));
00986     }
00987 
00988     try{
00989       this->emtr_b = emitter::emitter_factory(iof);
00990     } catch(...){
00991       cerr << "phase_covariance::read error - could not read second emitter\n";
00992       throw(string("phase_covariance::read"));
00993     }
00994 
00995     try{
00996       this->circ_ap.read(iof);
00997     } catch(...){
00998       cerr << "phase_covariance::read error - could not read aperture\n";
00999       throw(string("phase_covariance::read"));
01000     }
01001 
01002     try{
01003       this->ref_atm_model.read(iof);
01004     } catch(...){
01005       cerr << "phase_covariance::read error - could not read refractive atmospheric model\n";
01006       throw(string("phase_covariance::read"));
01007     }
01008 
01009   }
01010 
01011   template<typename precision>
01012     void phase_covariance<precision, circular_aperture>::write(const char * filename) const {
01013 
01014     iofits iof;
01015     try{iof.create(filename);}
01016     catch(...){
01017       cerr << "phase_covariance::write - "
01018            << "error opening file " << filename << endl;
01019       throw(string("phase_covariance::write"));
01020     }
01021 
01022     try{this->write(iof);}
01023     catch(...){
01024       cerr << "phase_covariance::write - "
01025            << "error writing "
01026            << this->unique_name() << " to file " 
01027            << filename << endl;
01028       throw(string("phase_covariance::write"));
01029     }
01030   }
01031 
01032   template<typename precision>
01033     void phase_covariance<precision, circular_aperture>::write(Arroyo::iofits & iof) const {
01034 
01035     fits_header_data<double> tmphdr;
01036     tmphdr.write(iof);
01037 
01038     string type, comment;
01039 
01040     type = this->unique_name();
01041     comment = "object type";
01042     iof.write_key("TYPE", type, comment);
01043 
01044     try{this->emtr_a->write(iof);}
01045     catch(...){
01046       cerr << "phase_covariance::write error - could not write first emitter\n";
01047       throw(string("phase_covariance::write"));
01048     }
01049       
01050     try{this->emtr_b->write(iof);}
01051     catch(...){
01052       cerr << "phase_covariance::write error - could not write second emitter\n";
01053       throw(string("phase_covariance::write"));
01054     }
01055 
01056     try{this->circ_ap.write(iof);}
01057     catch(...){
01058       cerr << "phase_covariance::write error - could not write aperture\n";
01059       throw(string("phase_covariance::write"));
01060     }
01061 
01062     try{this->ref_atm_model.write(iof);}
01063     catch(...){
01064       cerr << "phase_covariance::write error - could not write refractive atmospheric model\n";
01065       throw(string("phase_covariance::write"));
01066     }
01067   }
01068 
01069   template<typename precision>
01070     void phase_covariance<precision, circular_aperture>::print(std::ostream & os, 
01071                                             const char * prefix) const {
01072 
01073     int vlspc = 30;
01074     os.setf(ios::left, ios::adjustfield); 
01075     os << prefix << "TYPE       = " << setw(vlspc) << this->unique_name()
01076        << "/" << "object type" << endl;
01077     this->emtr_a->print(os, prefix);
01078     this->emtr_b->print(os, prefix);
01079     this->circ_ap.print(os, prefix);
01080     this->ref_atm_model.print(os, prefix);
01081   }
01082 
01083   template<typename precision>
01084     double phase_covariance<precision, circular_aperture>::aperture_averaged_variance(double wavelength_meters,
01085                                                                                       int nsteps_in_integration) const {
01086 
01087     try{
01088 
01089       this->initialize_integration(nsteps_in_integration);
01090       if(stored_caliph_M==-1)
01091         stored_caliph_M = this->ref_atm_model.caliph_M(*(this->emtr_a),
01092                                                         *(this->emtr_b),
01093                                                         this->circ_ap.get_diameter());
01094       
01095       return(Xi*pow(this->circ_ap.get_diameter(),5/3.)*
01096              4*M_PI*M_PI/wavelength_meters/wavelength_meters*
01097              (stored_caliph_D - stored_caliph_M));
01098     } catch(...){
01099       cerr << "phase_covariance::aperture_averaged_variance error - could not form variance\n";
01100       throw(string("phase_covariance::aperture_averaged_variance"));
01101     }      
01102 
01103   }
01104 
01105   template<typename precision>
01106     double phase_covariance<precision, circular_aperture>::variance(double wavelength_meters,
01107                                                                     int nsteps_in_integration,
01108                                                                     const three_point & tp) const {
01109 
01110     try{
01111       double val;
01112       double ap_diameter_meters = this->circ_ap.get_diameter();
01113       
01114       this->initialize_integration(nsteps_in_integration);
01115       
01116       three_vector pixel_vector = tp - static_cast<three_point>(this->circ_ap);
01117       pixel_vector *= (2/ap_diameter_meters);
01118       if((pixel_vector.length()-1)>-three_frame::precision){
01119         cerr << "phase_covariance::variance error - "
01120              << "three_point lies outside of aperture\n";
01121         throw(string("phase_covariance::variance"));
01122       }
01123       
01124       
01125       val = this->ref_atm_model.caliph_A(*(this->emtr_a),
01126                                          *(this->emtr_b), 
01127                                          ap_diameter_meters,
01128                                          pixel_vector);
01129       
01130       val += this->ref_atm_model.caliph_B(*(this->emtr_a), 
01131                                           *(this->emtr_b), 
01132                                           ap_diameter_meters,
01133                                           pixel_vector);
01134       
01135       val -= this->ref_atm_model.caliph_C(*(this->emtr_a), 
01136                                           *(this->emtr_b), 
01137                                           ap_diameter_meters,
01138                                           pixel_vector,
01139                                           pixel_vector);
01140 
01141       val -= stored_caliph_D;
01142 
01143       return(val*Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters);
01144     } catch(...) {
01145       cerr << "phase_covariance::variance error - could not form variance\n";
01146       throw(string("phase_covariance::variance"));
01147     }      
01148   }
01149 
01150   template<typename precision>
01151   pixel_array<precision> 
01152   phase_covariance<precision, circular_aperture>::variance(double pixel_scale_meters,
01153                                                            double wavelength_meters,
01154                                                            int nsteps_in_integration) const {
01155     
01156     try{
01157       this->initialize_integration(nsteps_in_integration);
01158       this->initialize_pixel_scale(pixel_scale_meters);
01159       
01160       double ap_diameter_meters = this->circ_ap.get_diameter();
01161       
01162       pixel_array<precision> variance_pixarr = this->stored_caliph_A;
01163       variance_pixarr += this->stored_caliph_B;
01164       variance_pixarr -= this->ref_atm_model.template caliph_C<precision>(*(emtr_a),
01165                                                                           *(emtr_b),
01166                                                                           ap_diameter_meters,
01167                                                                           pixel_scale_meters);
01168       
01169       precision tmp = -1*this->stored_caliph_D;
01170 
01171       add_val_to_pixarr(variance_pixarr,
01172                         tmp,
01173                         2*pixel_scale_meters/ap_diameter_meters);
01174 
01175       variance_pixarr *= Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters;
01176 
01177       return(variance_pixarr);
01178 
01179     } catch(...) {
01180       cerr << "phase_covariance::variance error - could not form variance\n";
01181       throw(string("phase_covariance::variance"));
01182     }      
01183   }
01184 
01185   template<typename precision>
01186     double phase_covariance<precision, circular_aperture>::covariance(double wavelength_meters,
01187                                                                       int nsteps_in_integration,
01188                                                                       const three_point & tp1,
01189                                                                       const three_point & tp2) const {
01190     try {
01191 
01192       this->initialize_integration(nsteps_in_integration);
01193       double val;
01194       double ap_diameter_meters = this->circ_ap.get_diameter();
01195 
01196       this->initialize_integration(nsteps_in_integration);
01197 
01198       three_vector pixel_vector_1 = tp1 - static_cast<three_point>(this->circ_ap);
01199       three_vector pixel_vector_2 = tp2 - static_cast<three_point>(this->circ_ap);
01200       pixel_vector_1 *= (2/ap_diameter_meters);
01201       pixel_vector_2 *= (2/ap_diameter_meters);
01202 
01203       if((pixel_vector_1.length()-1)>-three_frame::precision){
01204         cerr << "phase_covariance::covariance error - "
01205              << "first three_point lies outside of aperture\n";
01206         throw(string("phase_covariance::covariance"));
01207       }
01208       if((pixel_vector_2.length()-1)>-three_frame::precision){
01209         cerr << "phase_covariance::covariance error - "
01210              << "second three_point lies outside of aperture\n";
01211         throw(string("phase_covariance::covariance"));
01212       }
01213 
01214       val = this->ref_atm_model.caliph_A(*(this->emtr_a), 
01215                                           *(this->emtr_b), 
01216                                           ap_diameter_meters,
01217                                           pixel_vector_1);
01218     
01219       val += this->ref_atm_model.caliph_B(*(this->emtr_a), 
01220                                            *(this->emtr_b), 
01221                                            ap_diameter_meters,
01222                                            pixel_vector_2);
01223       
01224       val -= this->ref_atm_model.caliph_C(*(this->emtr_a), 
01225                                            *(this->emtr_b), 
01226                                            ap_diameter_meters,
01227                                            pixel_vector_1,
01228                                            pixel_vector_2);
01229 
01230       val -= stored_caliph_D;
01231 
01232       return(val*Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters);
01233     } catch(...) {
01234       cerr << "phase_covariance::covariance error - could not form covariance\n";
01235       throw(string("phase_covariance::covariance"));
01236     }      
01237   }
01238 
01239   template<typename precision>
01240     pixel_array<precision> phase_covariance<precision, circular_aperture>::covariance(double pixel_scale_meters,
01241                                                                                       double wavelength_meters,
01242                                                                                       int nsteps_in_integration,
01243                                                                                       const three_point & tp,
01244                                                                                       bool first_arg) const {
01245     
01246     try {
01247       pixel_array<precision> covariance_pixarr;
01248 
01249       this->initialize_integration(nsteps_in_integration);
01250       this->initialize_pixel_scale(pixel_scale_meters);
01251 
01252       if(first_arg){
01253         covariance_pixarr = this->stored_caliph_B;
01254       } else {
01255         covariance_pixarr = this->stored_caliph_A;
01256       }
01257     
01258       vector<long> axes = covariance_pixarr.get_axes();
01259       double x_halfpix=0, y_halfpix=0;
01260       int x_extrapix=1, y_extrapix=1;
01261       if(axes[1]%2==0){
01262         x_halfpix = .5;
01263         x_extrapix = 0;
01264       }
01265       if(axes[0]%2==0){
01266         y_halfpix = .5;
01267         y_extrapix = 0;
01268       }
01269 
01270       double ap_diameter_meters = this->circ_ap.get_diameter();
01271       double normalization_factor = 2*pixel_scale_meters/ap_diameter_meters;
01272       int index;
01273       double val;
01274       double fac = Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters;
01275       three_vector pixel_vector;
01276       three_vector normalized_tv = (tp - this->circ_ap)*(2/this->circ_ap.get_diameter());
01277       if((normalized_tv.length()-1)>-three_frame::precision){
01278         cerr << "phase_covariance::covariance error - "
01279              << "three_point lies outside of aperture\n";
01280         throw(string("phase_covariance::covariance"));
01281       }
01282 
01283       for(int m=-axes[1]/2; m<axes[1]/2+x_extrapix; m++){
01284         for(int n=-axes[0]/2; n<axes[0]/2+y_extrapix; n++){
01285         
01286           index = (m+axes[1]/2)*axes[0]+n+axes[0]/2;
01287         
01288           pixel_vector = three_vector((m+x_halfpix)*normalization_factor,
01289                                       (n+y_halfpix)*normalization_factor,
01290                                       0,
01291                                       this->circ_ap);
01292         
01293           if(pixel_vector.length()<=1){
01294             if(first_arg){
01295               val = this->ref_atm_model.caliph_A(*(this->emtr_a), 
01296                                                  *(this->emtr_b), 
01297                                                  ap_diameter_meters,
01298                                                  normalized_tv);
01299               val -= this->ref_atm_model.caliph_C(*(this->emtr_a), 
01300                                                   *(this->emtr_b), 
01301                                                   ap_diameter_meters,
01302                                                   normalized_tv,
01303                                                   pixel_vector);
01304             } else {
01305               val = this->ref_atm_model.caliph_B(*(this->emtr_a), 
01306                                                  *(this->emtr_b), 
01307                                                  ap_diameter_meters,
01308                                                  normalized_tv);
01309               val -= this->ref_atm_model.caliph_C(*(this->emtr_a), 
01310                                                   *(this->emtr_b), 
01311                                                   ap_diameter_meters,
01312                                                   pixel_vector,
01313                                                   normalized_tv);
01314             }
01315             val -= stored_caliph_D;
01316             covariance_pixarr.set_data(index, fac*(covariance_pixarr.data(index) + val));
01317           }
01318         }
01319       }
01320       return(covariance_pixarr);
01321     } catch(...) {
01322       cerr << "phase_covariance::covariance error - could not form covariance\n";
01323       throw(string("phase_covariance::covariance"));
01324     }      
01325   }
01326 
01327   template<typename precision>
01328     pixel_array<precision> phase_covariance<precision, circular_aperture>::covariance(double pixel_scale_meters,
01329                                                                                       double wavelength_meters,
01330                                                                                       int nsteps_in_integration,
01331                                                                                       int xindex,
01332                                                                                       int yindex,
01333                                                                                       bool first_arg) const {
01334 
01335     try{
01336       pixel_array<precision> covariance_pixarr;
01337 
01338       this->initialize_integration(nsteps_in_integration);
01339       this->initialize_pixel_scale(pixel_scale_meters);
01340 
01341       double caliph_val;
01342       vector<long> axes = this->stored_caliph_B.get_axes();
01343       int index = (xindex+axes[1]/2)*axes[0]+yindex+axes[0]/2;
01344       if(first_arg){
01345         covariance_pixarr = this->stored_caliph_B;
01346         caliph_val = this->stored_caliph_A.data(index) - stored_caliph_D;
01347       } else {
01348         covariance_pixarr = this->stored_caliph_A;
01349         caliph_val = this->stored_caliph_B.data(index) - stored_caliph_D; 
01350       }
01351 
01352       double x_halfpix=0, y_halfpix=0;
01353       int x_extrapix=1, y_extrapix=1;
01354       if(axes[1]%2==0){
01355         x_halfpix = .5;
01356         x_extrapix = 0;
01357       }
01358       if(axes[0]%2==0){
01359         y_halfpix = .5;
01360         y_extrapix = 0;
01361       }
01362 
01363       double ap_diameter_meters = this->circ_ap.get_diameter();
01364       double normalization_factor = 2*pixel_scale_meters/ap_diameter_meters;
01365       double val;
01366       double fac = Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters;
01367 
01368       three_vector pixel_vector_one((xindex+x_halfpix)*normalization_factor,
01369                                     (yindex+y_halfpix)*normalization_factor,
01370                                     0,
01371                                     this->circ_ap);
01372       if((pixel_vector_one.length()-1)>-three_frame::precision){
01373         cerr << "phase_covariance::covariance error - "
01374              << "three_point lies outside of aperture\n";
01375         throw(string("phase_covariance::covariance"));
01376       }
01377       three_vector pixel_vector_two;
01378 
01379       int half_axes_1 = axes[1]/2;
01380       int half_axes_0 = axes[0]/2;
01381 
01382       for(int m=-half_axes_1; m<half_axes_1+x_extrapix; m++){
01383         for(int n=-half_axes_0; n<half_axes_0+y_extrapix; n++){
01384         
01385           index = (m+half_axes_1)*axes[0]+n+half_axes_0;
01386         
01387           pixel_vector_two = three_vector((m+x_halfpix)*normalization_factor,
01388                                           (n+y_halfpix)*normalization_factor,
01389                                           0,
01390                                           this->circ_ap);
01391         
01392           if(pixel_vector_two.length()<=1){
01393             val = caliph_val;
01394             if(first_arg){
01395               val -= this->ref_atm_model.caliph_C(*(this->emtr_a), 
01396                                                   *(this->emtr_b), 
01397                                                   ap_diameter_meters,
01398                                                   pixel_vector_one,
01399                                                   pixel_vector_two);
01400             } else {
01401               val -= this->ref_atm_model.caliph_C(*(this->emtr_a), 
01402                                                   *(this->emtr_b), 
01403                                                   ap_diameter_meters,
01404                                                   pixel_vector_two,
01405                                                   pixel_vector_one);
01406             }
01407             covariance_pixarr.set_data(index, fac*(covariance_pixarr.data(index) + val));
01408           }
01409         }
01410       }
01411       return(covariance_pixarr);
01412     } catch(...) {
01413       cerr << "phase_covariance::covariance error - could not form covariance\n";
01414       throw(string("phase_covariance::covariance"));
01415     }      
01416   }
01417 
01418   /*
01419   template<typename precision>
01420     phase_covariance<precision, annular_aperture>::
01421     phase_covariance(const emitter & emtr_a,
01422                      const emitter & emtr_b,
01423                      const refractive_atmospheric_model & ref_atm_model,
01424                      const annular_aperture & annular_ap) {
01425 
01426 
01427     circular_aperture circ_ap(annular_ap.get_outer_diameter());
01428     this->outer_aperture_phase_covariance = 
01429       phase_covariance<precision, circular_aperture>(emtr_a,
01430                                                      emtr_b,
01431                                                      ref_atm_model,
01432                                                      circ_ap);
01433     
01434     circ_ap = circular_aperture(annular_ap.get_inner_diameter());
01435     this->inner_aperture_phase_covariance = 
01436       phase_covariance<precision, circular_aperture>(emtr_a,
01437                                                      emtr_b,
01438                                                      ref_atm_model,
01439                                                      circ_ap);
01440     
01441   }
01442 
01443   template<typename precision>
01444     phase_covariance<precision, annular_aperture> &
01445     phase_covariance<precision, annular_aperture>::operator=(const phase_covariance & pcv) {
01446     this->outer_aperture_phase_covariance = pcv.outer_aperture_phase_covariance;
01447     this->inner_aperture_phase_covariance = pcv.inner_aperture_phase_covariance;
01448   }
01449 
01450   template<typename precision>
01451     void phase_covariance<precision, annular_aperture>::read(const char * filename){
01452     iofits iof;
01453     try{iof.open(filename);}
01454     catch(...){
01455       cerr << "phase_covariance::read - "
01456            << "error opening file " << filename << endl;
01457       throw(string("phase_covariance::read"));
01458     }
01459     try{this->read(iof);}
01460     catch(...){
01461       cerr << "phase_covariance::read - "
01462            << "error reading "
01463            << this->unique_name() << " from file " 
01464            << filename << endl;
01465       throw(string("phase_covariance::read"));
01466     }
01467   }
01468   
01469   template<typename precision>
01470     void phase_covariance<precision, annular_aperture>::read(const Arroyo::iofits & iof){
01471 
01472     string type, comment;
01473     if (!iof.key_exists("TYPE"))
01474       {
01475         cerr << this->unique_name() << "::read error - unrecognized "
01476              << "file type" << endl;
01477         throw(this->unique_name() + string("::read"));
01478       }
01479     iof.read_key("TYPE",type,comment);
01480     if(type!=this->unique_name()){
01481       cerr << this->unique_name() << "::read error - file of type: " 
01482            << type << " rather than type " << this->unique_name() << endl;
01483       throw(this->unique_name() + string("::read"));
01484     }
01485 
01486     // Move to the next HDU
01487     iof.movrel_hdu(1);
01488     
01489     try{
01490       this->outer_aperture_phase_covariance.read(iof);
01491     } catch(...){
01492       cerr << "phase_covariance::read error - could not read outer aperture phase covariance\n";
01493       throw(string("phase_covariance::read"));
01494     }
01495 
01496     try{
01497       this->inner_aperture_phase_covariance.read(iof);
01498     } catch(...){
01499       cerr << "phase_covariance::read error - could not read inner aperture phase covariance\n";
01500       throw(string("phase_covariance::read"));
01501     }
01502 
01503   }
01504 
01505   template<typename precision>
01506     void phase_covariance<precision, annular_aperture>::write(const char * filename) const {
01507 
01508     iofits iof;
01509     try{iof.create(filename);}
01510     catch(...){
01511       cerr << "phase_covariance::write - "
01512            << "error opening file " << filename << endl;
01513       throw(string("phase_covariance::write"));
01514     }
01515 
01516     try{this->write(iof);}
01517     catch(...){
01518       cerr << "phase_covariance::write - "
01519            << "error writing "
01520            << this->unique_name() << " to file " 
01521            << filename << endl;
01522       throw(string("phase_covariance::write"));
01523     }
01524   }
01525 
01526   template<typename precision>
01527     void phase_covariance<precision, annular_aperture>::write(Arroyo::iofits & iof) const {
01528 
01529     fits_header_data<double> tmphdr;
01530     tmphdr.write(iof);
01531 
01532     string type, comment;
01533 
01534     type = this->unique_name();
01535     comment = "object type";
01536     iof.write_key("TYPE", type, comment);
01537 
01538     try{this->outer_aperture_phase_covariance.write(iof);}
01539     catch(...){
01540       cerr << "phase_covariance::write error - could not write outer aperture phase covariance\n";
01541       throw(string("phase_covariance::write"));
01542     }
01543 
01544     try{this->inner_aperture_phase_covariance.write(iof);}
01545     catch(...){
01546       cerr << "phase_covariance::write error - could not write inner aperture phase covariance\n";
01547       throw(string("phase_covariance::write"));
01548     }
01549 
01550   }
01551 
01552   template<typename precision>
01553     void phase_covariance<precision, annular_aperture>::print(std::ostream & os, 
01554                                                               const char * prefix) const {
01555     
01556     int vlspc = 30;
01557     os.setf(ios::left, ios::adjustfield); 
01558     os << prefix << "TYPE       = " << setw(vlspc) << this->unique_name()
01559        << "/" << "object type" << endl;
01560     this->outer_aperture_phase_covariance.print(os, prefix);
01561     this->inner_aperture_phase_covariance.print(os, prefix);
01562   }
01563 
01564   template<typename precision>
01565     double phase_covariance<precision, annular_aperture>::
01566     aperture_averaged_variance(double wavelength_meters,
01567                                int nsteps_in_integration) const {
01568 
01569     try{
01570       return(this->outer_aperture_phase_covariance.aperture_averaged_variance(wavelength_meters,
01571                                                                               nsteps_in_integration) -
01572              this->inner_aperture_phase_covariance.aperture_averaged_variance(wavelength_meters,
01573                                                                               nsteps_in_integration));
01574     } catch(...){
01575       cerr << "phase_covariance::aperture_averaged_variance error - could not form variance\n";
01576       throw(string("phase_covariance::aperture_averaged_variance"));
01577     }      
01578 
01579   }
01580 
01581   template<typename precision>
01582     double phase_covariance<precision, annular_aperture>::variance(double wavelength_meters,
01583                                                                    int nsteps_in_integration,
01584                                                                    const three_point & tp) const {
01585 
01586     try{
01587       return(this->outer_aperture_phase_covariance.variance(wavelength_meters,
01588                                                             nsteps_in_integration,
01589                                                             tp) -
01590              this->inner_aperture_phase_covariance.variance(wavelength_meters,
01591                                                             nsteps_in_integration,
01592                                                             tp));
01593     } catch(...) {
01594       cerr << "phase_covariance::variance error - could not form variance\n";
01595       throw(string("phase_covariance::variance"));
01596     }      
01597   }
01598 
01599   template<typename precision>
01600   pixel_array<precision> 
01601   phase_covariance<precision, annular_aperture>::variance(double pixel_scale_meters,
01602                                                           double wavelength_meters,
01603                                                           int nsteps_in_integration) const {
01604     
01605     try{
01606       return(this->outer_aperture_phase_covariance.variance(pixel_scale_meters,
01607                                                             wavelength_meters,
01608                                                             nsteps_in_integration) -
01609              this->inner_aperture_phase_covariance.variance(pixel_scale_meters,
01610                                                             wavelength_meters,
01611                                                             nsteps_in_integration));
01612     } catch(...) {
01613       cerr << "phase_covariance::variance error - could not form variance\n";
01614       throw(string("phase_covariance::variance"));
01615     }      
01616   }
01617 
01618   template<typename precision>
01619     double phase_covariance<precision, annular_aperture>::covariance(double wavelength_meters,
01620                                                                      int nsteps_in_integration,
01621                                                                      const three_point & tp1,
01622                                                                      const three_point & tp2) const {
01623     try {
01624       return(this->outer_aperture_phase_covariance.covariance(wavelength_meters,
01625                                                               nsteps_in_integration,
01626                                                               tp1,
01627                                                               tp2) -
01628              this->inner_aperture_phase_covariance.covariance(wavelength_meters,
01629                                                               nsteps_in_integration,
01630                                                               tp1,
01631                                                               tp2));
01632     } catch(...) {
01633       cerr << "phase_covariance::covariance error - could not form covariance\n";
01634       throw(string("phase_covariance::covariance"));
01635     }      
01636   }
01637 
01638   template<typename precision>
01639     pixel_array<precision> phase_covariance<precision, annular_aperture>::covariance(double pixel_scale_meters,
01640                                                                                       double wavelength_meters,
01641                                                                                       int nsteps_in_integration,
01642                                                                                       const three_point & tp,
01643                                                                                       bool first_arg) const {
01644     
01645     try {
01646       return(this->outer_aperture_phase_covariance.covariance(pixel_scale_meters,
01647                                                               wavelength_meters,
01648                                                               nsteps_in_integration,
01649                                                               tp,
01650                                                               first_arg) -
01651              this->inner_aperture_phase_covariance.covariance(pixel_scale_meters,
01652                                                               wavelength_meters,
01653                                                               nsteps_in_integration,
01654                                                               tp,
01655                                                               first_arg));
01656     } catch(...) {
01657       cerr << "phase_covariance::covariance error - could not form covariance\n";
01658       throw(string("phase_covariance::covariance"));
01659     }      
01660   }
01661 
01662   template<typename precision>
01663     pixel_array<precision> phase_covariance<precision, annular_aperture>::covariance(double pixel_scale_meters,
01664                                                                                       double wavelength_meters,
01665                                                                                       int nsteps_in_integration,
01666                                                                                       int xindex,
01667                                                                                       int yindex,
01668                                                                                       bool first_arg) const {
01669 
01670     try{
01671       return(this->outer_aperture_phase_covariance.covariance(pixel_scale_meters,
01672                                                               wavelength_meters,
01673                                                               nsteps_in_integration,
01674                                                               xindex,
01675                                                               yindex,
01676                                                               first_arg) -
01677              this->inner_aperture_phase_covariance.covariance(pixel_scale_meters,
01678                                                               wavelength_meters,
01679                                                               nsteps_in_integration,
01680                                                               xindex,
01681                                                               yindex,
01682                                                               first_arg));
01683     } catch(...) {
01684       cerr << "phase_covariance::covariance error - could not form covariance\n";
01685       throw(string("phase_covariance::covariance"));
01686     }      
01687   }
01688   */
01689 
01690   template<typename precision>
01691   double tilt_covariance<precision, circular_aperture>::Xi = get_Xi();
01692   
01693   template<typename precision>
01694     void tilt_covariance<precision, circular_aperture>::
01695     initialize_integration(int nsteps_in_integration) const {
01696 
01697     try{
01698       if(this->nsteps_in_integration==nsteps_in_integration)
01699         return;
01700     
01701       if(this->emtr_a==NULL || this->emtr_b==NULL){
01702         cerr << "tilt_covariance::initialize_integration error - uninitialized emitters\n";
01703         throw(string("tilt_covariance::initialize_integration"));
01704       }
01705   
01706       this->nsteps_in_integration = nsteps_in_integration;
01707       
01708       stored_caliph_E = this->ref_atm_model.caliph_E(*(this->emtr_a), 
01709                                                      *(this->emtr_b), 
01710                                                      this->circ_ap.get_diameter(),
01711                                                      this->nsteps_in_integration);
01712       
01713       stored_caliph_F = this->ref_atm_model.caliph_F(*(this->emtr_a), 
01714                                                      *(this->emtr_b), 
01715                                                      this->circ_ap.get_diameter(),
01716                                                      this->nsteps_in_integration);      
01717       
01718       stored_caliph_F_bar = this->ref_atm_model.caliph_F_bar(*(this->emtr_a), 
01719                                                              *(this->emtr_b), 
01720                                                              this->circ_ap.get_diameter(),
01721                                                              this->nsteps_in_integration);
01722       
01723       stored_caliph_K = this->ref_atm_model.caliph_K(*(this->emtr_a), 
01724                                                      *(this->emtr_b), 
01725                                                      this->circ_ap.get_diameter(),
01726                                                      this->nsteps_in_integration);
01727       
01728       stored_caliph_L = this->ref_atm_model.caliph_L(*(this->emtr_a), 
01729                                                      *(this->emtr_b), 
01730                                                      this->circ_ap.get_diameter(),
01731                                                      this->nsteps_in_integration);
01732     } catch(...) {
01733       cerr << "tilt_covariance::initialize_integration error\n";
01734       this->emtr_a->print(cerr, "\temtra");
01735       this->emtr_b->print(cerr, "\temtrb");
01736       cout << "ap diameter " << this->circ_ap.get_diameter()
01737            << "\tnsteps in integration " << this->nsteps_in_integration
01738            << endl;
01739       throw(string("tilt_covariance::initialize_integration"));
01740     }
01741 
01742   }
01743 
01744   template<typename precision>
01745     void tilt_covariance<precision, circular_aperture>::
01746     initialize_pixel_scale(double pixel_scale_meters) const {
01747     
01748     try{
01749       if(this->pixel_scale_meters==pixel_scale_meters)
01750         return;
01751       
01752       if(this->emtr_a==NULL || this->emtr_b==NULL){
01753         cerr << "tilt_covariance::initialize_pixel_scale error - uninitialized emitters\n";
01754         throw(string("tilt_covariance::initialize_pixel_scale"));
01755       }
01756 
01757       this->pixel_scale_meters = pixel_scale_meters;
01758       stored_caliph_G = 
01759         this->ref_atm_model.template caliph_G<precision>(*(this->emtr_a),
01760                                                          *(this->emtr_b),
01761                                                          this->circ_ap.get_diameter(),
01762                                                          this->pixel_scale_meters);
01763       stored_caliph_H = 
01764         this->ref_atm_model.template caliph_H<precision>(*(this->emtr_a),
01765                                                          *(this->emtr_b),
01766                                                          this->circ_ap.get_diameter(),
01767                                                          this->pixel_scale_meters);
01768       stored_caliph_I = 
01769         this->ref_atm_model.template caliph_I<precision>(*(this->emtr_a),
01770                                                          *(this->emtr_b),
01771                                                          this->circ_ap.get_diameter(),
01772                                                          this->pixel_scale_meters);
01773       stored_caliph_J = 
01774         this->ref_atm_model.template caliph_J<precision>(*(this->emtr_a),
01775                                                          *(this->emtr_b),
01776                                                          this->circ_ap.get_diameter(),
01777                                                          this->pixel_scale_meters);
01778     } catch(...) {
01779       cerr << "tilt_covariance::initialize_pixel_scale error\n";
01780       this->emtr_a->print(cerr, "\temtra");
01781       this->emtr_b->print(cerr, "\temtrb");
01782       cout << "ap diameter " << this->circ_ap.get_diameter()
01783            << "\tnsteps in integration " << this->nsteps_in_integration
01784            << endl;
01785       throw(string("tilt_covariance::initialize_pixel_scale"));
01786     }
01787   }
01788 
01789   template<typename precision>
01790     tilt_covariance<precision, circular_aperture>::
01791     tilt_covariance(const emitter & emtr_a,
01792                     const emitter & emtr_b,
01793                     const refractive_atmospheric_model & ref_atm_model,
01794                     const circular_aperture & circ_ap) {
01795 
01796     this->emtr_a = emitter::emitter_factory(&emtr_a);
01797     this->emtr_b = emitter::emitter_factory(&emtr_b);
01798 
01799     this->ref_atm_model = ref_atm_model;
01800     
01801     this->circ_ap = circ_ap;
01802 
01803     this->stored_caliph_E = -1;
01804     this->stored_caliph_F = -1;
01805     this->stored_caliph_F_bar = -1;
01806     this->stored_caliph_K = -1;
01807     this->stored_caliph_L = -1;
01808 
01809     this->pixel_scale_meters = -1;
01810     this->nsteps_in_integration = -1;
01811 
01812     get_omega_hat(*(this->emtr_a), 
01813                   *(this->emtr_b),
01814                   this->circ_ap,
01815                   omega_hat);
01816 
01817   }
01818 
01819   template<typename precision>
01820     tilt_covariance<precision, circular_aperture> &
01821     tilt_covariance<precision, circular_aperture>::operator=(const tilt_covariance & tcv) {
01822 
01823     this->emtr_a = emitter::emitter_factory(tcv.emtr_a);
01824     this->emtr_b = emitter::emitter_factory(tcv.emtr_b);
01825 
01826     this->ref_atm_model = tcv.ref_atm_model;
01827     this->circ_ap = tcv.circ_ap;
01828     
01829     this->pixel_scale_meters = tcv.pixel_scale_meters;
01830     this->nsteps_in_integration = tcv.nsteps_in_integration;
01831 
01832     this->stored_caliph_G = tcv.stored_caliph_G;
01833     this->stored_caliph_H = tcv.stored_caliph_H;
01834     this->stored_caliph_I = tcv.stored_caliph_I;
01835     this->stored_caliph_J = tcv.stored_caliph_J;
01836 
01837     this->stored_caliph_E = tcv.stored_caliph_E;
01838     this->stored_caliph_F = tcv.stored_caliph_F;
01839     this->stored_caliph_F_bar = tcv.stored_caliph_F_bar;
01840     this->stored_caliph_K = tcv.stored_caliph_K;
01841     this->stored_caliph_L = tcv.stored_caliph_L;
01842 
01843     this->omega_hat = tcv.omega_hat;
01844   }
01845 
01846   template<typename precision>
01847     void tilt_covariance<precision, circular_aperture>::read(const char * filename){
01848     iofits iof;
01849     try{iof.open(filename);}
01850     catch(...){
01851       cerr << "tilt_covariance::read - "
01852            << "error opening file " << filename << endl;
01853       throw(string("tilt_covariance::read"));
01854     }
01855     try{this->read(iof);}
01856     catch(...){
01857       cerr << "tilt_covariance::read - "
01858            << "error reading "
01859            << this->unique_name() << " from file " 
01860            << filename << endl;
01861       throw(string("tilt_covariance::read"));
01862     }
01863   }
01864   
01865   template<typename precision>
01866     void tilt_covariance<precision, circular_aperture>::read(const Arroyo::iofits & iof){
01867     string type, comment;
01868     if (!iof.key_exists("TYPE"))
01869       {
01870         cerr << this->unique_name() << "::read error - unrecognized "
01871              << "file type" << endl;
01872         throw(this->unique_name() + string("::read"));
01873       }
01874     iof.read_key("TYPE",type,comment);
01875     if(type!=this->unique_name()){
01876       cerr << this->unique_name() << "::read error - file of type: " 
01877            << type << " rather than type " << this->unique_name() << endl;
01878       throw(this->unique_name() + string("::read"));
01879     }
01880 
01881     // Move to the next HDU
01882     iof.movrel_hdu(1);
01883 
01884     try{
01885       emtr_a = emitter::emitter_factory(iof);
01886     } catch(...){
01887       cerr << "tilt_covariance::read error - could not read first emitter\n";
01888       throw(string("tilt_covariance::read"));
01889     }
01890 
01891     try{
01892       emtr_b = emitter::emitter_factory(iof);
01893     } catch(...){
01894       cerr << "tilt_covariance::read error - could not read second emitter\n";
01895       throw(string("tilt_covariance::read"));
01896     }
01897 
01898     try{
01899       this->circ_ap.read(iof);
01900     } catch(...){
01901       cerr << "tilt_covariance::read error - could not read aperture\n";
01902       throw(string("tilt_covariance::read"));
01903     }
01904 
01905     try{
01906       this->ref_atm_model.read(iof);
01907     } catch(...){
01908       cerr << "tilt_covariance::read error - could not read refractive atmospheric model\n";
01909       throw(string("tilt_covariance::read"));
01910     }
01911 
01912   }
01913 
01914   template<typename precision>
01915     void tilt_covariance<precision, circular_aperture>::write(const char * filename) const {
01916 
01917     iofits iof;
01918     try{iof.create(filename);}
01919     catch(...){
01920       cerr << "tilt_covariance::write - "
01921            << "error opening file " << filename << endl;
01922       throw(string("tilt_covariance::write"));
01923     }
01924 
01925     try{this->write(iof);}
01926     catch(...){
01927       cerr << "tilt_covariance::write - "
01928            << "error writing "
01929            << this->unique_name() << " to file " 
01930            << filename << endl;
01931       throw(string("tilt_covariance::write"));
01932     }
01933   }
01934 
01935   template<typename precision>
01936     void tilt_covariance<precision, circular_aperture>::write(Arroyo::iofits & iof) const {
01937 
01938     fits_header_data<double> tmphdr;
01939     tmphdr.write(iof);
01940 
01941     string type, comment;
01942 
01943     type = this->unique_name();
01944     comment = "object type";
01945     iof.write_key("TYPE", type, comment);
01946 
01947     try{this->emtr_a->write(iof);}
01948     catch(...){
01949       cerr << "tilt_covariance::write error - could not write first emitter\n";
01950       throw(string("tilt_covariance::write"));
01951     }
01952       
01953     try{this->emtr_b->write(iof);}
01954     catch(...){
01955       cerr << "tilt_covariance::write error - could not write second emitter\n";
01956       throw(string("tilt_covariance::write"));
01957     }
01958 
01959     try{this->circ_ap.write(iof);}
01960     catch(...){
01961       cerr << "tilt_covariance::write error - could not write aperture\n";
01962       throw(string("tilt_covariance::write"));
01963     }
01964 
01965     try{this->ref_atm_model.write(iof);}
01966     catch(...){
01967       cerr << "tilt_covariance::write error - could not write refractive atmospheric model\n";
01968       throw(string("tilt_covariance::write"));
01969     }
01970   }
01971 
01972   template<typename precision>
01973     void tilt_covariance<precision, circular_aperture>::print(std::ostream & os, 
01974                                            const char * prefix) const {
01975 
01976     int vlspc = 30;
01977     os.setf(ios::left, ios::adjustfield); 
01978     os << prefix << "TYPE       = " << setw(vlspc) << this->unique_name()
01979        << "/" << "object type" << endl;
01980     this->emtr_a->print(os, prefix);
01981     this->emtr_b->print(os, prefix);
01982     this->circ_ap.print(os, prefix);
01983     this->ref_atm_model.print(os, prefix);
01984   }
01985 
01986   template<typename precision>
01987     double tilt_covariance<precision, circular_aperture>::aperture_averaged_variance(double wavelength_meters,
01988                                                                    int nsteps_in_integration) const {
01989 
01990     try{
01991     this->initialize_integration(nsteps_in_integration);
01992     
01993     return(Xi*pow(this->circ_ap.get_diameter(),5/3.)*
01994            4*M_PI*M_PI/wavelength_meters/wavelength_meters*
01995            (.25*stored_caliph_F - .5*stored_caliph_E));
01996     } catch(...){
01997       cerr << "tilt_covariance::aperture_averaged_variance error - could not form variance\n";
01998       throw(string("tilt_covariance::aperture_averaged_variance"));
01999     }      
02000   }
02001 
02002   template<typename precision>
02003     double tilt_covariance<precision, circular_aperture>::variance(double wavelength_meters,
02004                                                                    int nsteps_in_integration,
02005                                                                    const three_point & tp) const {
02006 
02007     try{
02008       double val;
02009       double ap_diameter_meters = this->circ_ap.get_diameter();
02010 
02011       this->initialize_integration(nsteps_in_integration);
02012 
02013       three_vector pixel_vector = tp - static_cast<three_point>(this->circ_ap);
02014       pixel_vector *= (2/ap_diameter_meters);
02015       
02016       if((pixel_vector.length()-1)>-three_frame::precision){
02017         cerr << "tilt_covariance::variance error - "
02018              << "three_point lies outside of aperture\n";
02019         cerr << "aperture diameter " << ap_diameter_meters 
02020              << " three point radius " << pixel_vector.length()*ap_diameter_meters/2. 
02021              << " difference " << ap_diameter_meters*(1 - pixel_vector.length())/2.
02022              << endl;
02023         throw(string("tilt_covariance::variance"));
02024       }
02025       
02026       double dot_prod = dot_product(pixel_vector, omega_hat);
02027 
02028       val = pixel_vector.length_squared()*
02029         (this->stored_caliph_E -
02030          this->ref_atm_model.caliph_G(*(this->emtr_a),
02031                                       *(this->emtr_b),
02032                                       ap_diameter_meters,
02033                                       pixel_vector) -
02034          this->ref_atm_model.caliph_I(*(this->emtr_a),
02035                                       *(this->emtr_b),
02036                                       ap_diameter_meters,
02037                                       pixel_vector));
02038 
02039 
02040       val -= dot_prod*dot_prod*this->stored_caliph_F;
02041 
02042       val += (dot_prod*dot_prod - cross_product(pixel_vector,omega_hat).length_squared())*
02043         this->stored_caliph_F_bar;
02044 
02045       val += dot_prod*
02046         (this->ref_atm_model.caliph_H(*(this->emtr_a), 
02047                                       *(this->emtr_b), 
02048                                       ap_diameter_meters,
02049                                       pixel_vector) -
02050          this->stored_caliph_K -
02051          this->ref_atm_model.caliph_J(*(this->emtr_a), 
02052                                       *(this->emtr_b), 
02053                                       ap_diameter_meters,
02054                                       pixel_vector) +
02055          this->stored_caliph_L);
02056 
02057       return(val*Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters);
02058     } catch(...) {
02059       cerr << "tilt_covariance::variance error - could not form variance\n";
02060       throw(string("tilt_covariance::variance"));
02061     }      
02062 
02063   }
02064 
02065   template<typename precision>
02066     pixel_array<precision> 
02067     tilt_covariance<precision, circular_aperture>::variance(double pixel_scale_meters,
02068                                                             double wavelength_meters,
02069                                                             int nsteps_in_integration) const {
02070 
02071     try{
02072       this->initialize_integration(nsteps_in_integration);
02073       this->initialize_pixel_scale(pixel_scale_meters);
02074 
02075       double ap_diameter_meters = this->circ_ap.get_diameter();
02076 
02077       vector<long> axes(2,(long)ceil(ap_diameter_meters/pixel_scale_meters));
02078       pixel_array<precision> variance_pixarr(axes);
02079 
02080       double x_halfpix=0, y_halfpix=0;
02081       int x_extrapix=1, y_extrapix=1;
02082       if(axes[1]%2==0){
02083         x_halfpix = .5;
02084         x_extrapix = 0;
02085       }
02086       if(axes[0]%2==0){
02087         y_halfpix = .5;
02088         y_extrapix = 0;
02089       }
02090 
02091       int index;
02092       double dot_prod, val;
02093       double normalization_factor = 2*pixel_scale_meters/ap_diameter_meters;
02094       double fac = 
02095         Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters;
02096       three_vector pixel_vector, cross_prod;
02097 
02098       for(int m=-axes[1]/2; m<axes[1]/2+x_extrapix; m++){
02099         for(int n=-axes[0]/2; n<axes[0]/2+y_extrapix; n++){
02100         
02101           index = (m+axes[1]/2)*axes[0]+n+axes[0]/2;
02102         
02103           pixel_vector = three_vector((m+x_halfpix)*normalization_factor,
02104                                       (n+y_halfpix)*normalization_factor,
02105                                       0,
02106                                       this->circ_ap);
02107         
02108           if(pixel_vector.length()<=1){
02109 
02110             dot_prod = dot_product(pixel_vector, omega_hat);
02111             cross_prod = cross_product(pixel_vector, omega_hat);
02112           
02113             val = pixel_vector.length_squared()*
02114               (this->stored_caliph_E -
02115                this->stored_caliph_G.data(index) -
02116                this->stored_caliph_I.data(index));
02117             val -= dot_prod*dot_prod*this->stored_caliph_F;
02118             val += (dot_prod*dot_prod - cross_prod.length_squared())*this->stored_caliph_F_bar;
02119             val += dot_prod*(stored_caliph_H.data(index) - 
02120                              stored_caliph_K - 
02121                              stored_caliph_J.data(index) + 
02122                              stored_caliph_L);
02123 
02124             variance_pixarr.set_data(index,fac*val);
02125           }
02126         }
02127       }
02128       return(variance_pixarr);
02129     } catch(...) {
02130       cerr << "tilt_covariance::variance error - could not form variance\n";
02131       throw(string("tilt_covariance::variance"));
02132     }      
02133   }
02134     
02135   template<typename precision>
02136     double tilt_covariance<precision, circular_aperture>::covariance(double wavelength_meters,
02137                                                   int nsteps_in_integration,
02138                                                   const three_point & tp1,
02139                                                   const three_point & tp2) const {
02140 
02141     try{
02142       this->initialize_integration(nsteps_in_integration);
02143       double val;
02144       double ap_diameter_meters = circ_ap.get_diameter();
02145 
02146       three_vector pixel_vector_1 = tp1 - static_cast<three_point>(this->circ_ap);
02147       three_vector pixel_vector_2 = tp2 - static_cast<three_point>(this->circ_ap);
02148       pixel_vector_1 *= (2/ap_diameter_meters);
02149       pixel_vector_2 *= (2/ap_diameter_meters);
02150 
02151       if((pixel_vector_1.length()-1)>-three_frame::precision){
02152         cerr << "tilt_covariance::covariance error - "
02153              << "first three_point lies outside of aperture\n";
02154         throw(string("tilt_covariance::covariance"));
02155       }
02156       if((pixel_vector_2.length()-1)>-three_frame::precision){
02157         cerr << "tilt_covariance::covariance error - "
02158              << "second three_point lies outside of aperture\n";
02159         throw(string("tilt_covariance::covariance"));
02160       }
02161 
02162       double dot_prod_1 = dot_product(pixel_vector_1, omega_hat);
02163       double dot_prod_2 = dot_product(pixel_vector_2, omega_hat);
02164       double cross_prod_fac = 
02165         dot_product(cross_product(pixel_vector_1, omega_hat),
02166                     cross_product(pixel_vector_2, omega_hat));
02167 
02168       val = 
02169         -dot_prod_1*dot_prod_2*this->stored_caliph_F +
02170         (dot_prod_1*dot_prod_2 - cross_prod_fac)*
02171         this->stored_caliph_F_bar;
02172       
02173       val += dot_product(pixel_vector_1, pixel_vector_2)*
02174       (this->stored_caliph_E -
02175          this->ref_atm_model.caliph_G(*(this->emtr_a), 
02176                                       *(this->emtr_b), 
02177                                       ap_diameter_meters,
02178                                       pixel_vector_2) -
02179          this->ref_atm_model.caliph_I(*(this->emtr_a), 
02180                                       *(this->emtr_b), 
02181                                       ap_diameter_meters,
02182                                       pixel_vector_1));
02183        
02184       val += dot_prod_1*
02185         (this->ref_atm_model.caliph_H(*(this->emtr_a), 
02186                                       *(this->emtr_b), 
02187                                       ap_diameter_meters,
02188                                       pixel_vector_2) -
02189          this->stored_caliph_K);
02190 
02191       val -= dot_prod_2*
02192         (this->ref_atm_model.caliph_J(*(this->emtr_a), 
02193                                       *(this->emtr_b), 
02194                                       ap_diameter_meters,
02195                                       pixel_vector_1) -
02196          this->stored_caliph_L);
02197 
02198       return(val*Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters);
02199     } catch(...) {
02200       cerr << "tilt_covariance::covariance error - could not form covariance\n";
02201       throw(string("tilt_covariance::covariance"));
02202     }      
02203   }
02204 
02205   template<typename precision>
02206     pixel_array<precision> 
02207     tilt_covariance<precision, circular_aperture>::covariance(double pixel_scale_meters,
02208                                                               double wavelength_meters,
02209                                                               int nsteps_in_integration,
02210                                                               const three_point & tp,
02211                                                               bool first_arg) const {
02212     
02213     try{
02214       this->initialize_integration(nsteps_in_integration);
02215       this->initialize_pixel_scale(pixel_scale_meters);
02216 
02217       double ap_diameter_meters = circ_ap.get_diameter();
02218       vector<long> axes(2,(long)ceil(ap_diameter_meters/pixel_scale_meters));
02219       pixel_array<precision> covariance_pixarr(axes);
02220 
02221       double x_halfpix=0, y_halfpix=0;
02222       int x_extrapix=1, y_extrapix=1;
02223       if(axes[1]%2==0){
02224         x_halfpix = .5;
02225         x_extrapix = 0;
02226       }
02227       if(axes[0]%2==0){
02228         y_halfpix = .5;
02229         y_extrapix = 0;
02230       }
02231 
02232       double normalization_factor = 2*pixel_scale_meters/ap_diameter_meters;
02233       int loop_index;
02234       double val;
02235       double fac = Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters;
02236       three_vector pixel_vector;
02237       three_vector normalized_tv = 
02238         (tp - static_cast<three_point>(this->circ_ap))*(2/ap_diameter_meters);
02239 
02240       if((normalized_tv.length()-1)>-three_frame::precision){
02241         cerr << "tilt_covariance::covariance error - "
02242              << "three_point lies outside of aperture\n";
02243         throw(string("tilt_covariance::covariance"));
02244       }
02245 
02246       double dot_prod_1 = dot_product(normalized_tv, omega_hat);
02247       double dot_prod_2;
02248       three_vector cross_prod = cross_product(normalized_tv, omega_hat);
02249       double cross_prod_fac;
02250 
02251       for(int m=-axes[1]/2; m<axes[1]/2+x_extrapix; m++){
02252         for(int n=-axes[0]/2; n<axes[0]/2+y_extrapix; n++){
02253         
02254           loop_index = (m+axes[1]/2)*axes[0]+n+axes[0]/2;
02255         
02256           pixel_vector = three_vector((m+x_halfpix)*normalization_factor,
02257                                       (n+y_halfpix)*normalization_factor,
02258                                       0,
02259                                       this->circ_ap);
02260         
02261           if(pixel_vector.length_squared()<=1){
02262 
02263             cross_prod_fac = 
02264               dot_product(cross_product(pixel_vector, omega_hat),
02265                           cross_prod);
02266             dot_prod_2 = dot_product(pixel_vector, omega_hat);
02267 
02268             val = 
02269               -dot_prod_1*dot_prod_2*this->stored_caliph_F +
02270               (dot_prod_1*dot_prod_2 - cross_prod_fac)*
02271               this->stored_caliph_F_bar;
02272 
02273             if(first_arg){
02274 
02275               val += dot_product(pixel_vector, normalized_tv)*
02276                 (this->stored_caliph_E -
02277                  this->stored_caliph_G.data(loop_index) -
02278                  this->ref_atm_model.caliph_I(*(this->emtr_a), 
02279                                               *(this->emtr_b), 
02280                                               ap_diameter_meters,
02281                                               normalized_tv));
02282 
02283               val += dot_prod_1*
02284                 (this->stored_caliph_H.data(loop_index) -
02285                  this->stored_caliph_K);
02286             
02287               val -= dot_prod_2*
02288                 (this->ref_atm_model.caliph_J(*(this->emtr_a), 
02289                                               *(this->emtr_b), 
02290                                               ap_diameter_meters,
02291                                               normalized_tv) -
02292                  this->stored_caliph_L);
02293             } else {
02294               val += dot_product(pixel_vector, normalized_tv)*
02295                 (this->stored_caliph_E -
02296                  this->ref_atm_model.caliph_G(*(this->emtr_a), 
02297                                               *(this->emtr_b), 
02298                                               ap_diameter_meters,
02299                                               normalized_tv) -
02300                  this->stored_caliph_I.data(loop_index));
02301             
02302               val += dot_prod_2*
02303                 (this->ref_atm_model.caliph_H(*(this->emtr_a), 
02304                                               *(this->emtr_b), 
02305                                               ap_diameter_meters,
02306                                               normalized_tv) -
02307                  this->stored_caliph_K);
02308 
02309               val -= dot_prod_1*
02310                 (this->stored_caliph_J.data(loop_index) -
02311                  this->stored_caliph_L);
02312             }
02313 
02314             covariance_pixarr.set_data(loop_index, fac*val);
02315           }
02316         }
02317       }
02318       return(covariance_pixarr);
02319     } catch(...) {
02320       cerr << "tilt_covariance::covariance error - could not form covariance\n";
02321       throw(string("tilt_covariance::covariance"));
02322     }      
02323   }
02324 
02325   template<typename precision>
02326     pixel_array<precision> 
02327     tilt_covariance<precision, circular_aperture>::covariance(double pixel_scale_meters,
02328                                                               double wavelength_meters,
02329                                                               int nsteps_in_integration,
02330                                                               int xindex,
02331                                                               int yindex,
02332                                                               bool first_arg) const {
02333 
02334     try{
02335       this->initialize_integration(nsteps_in_integration);
02336       this->initialize_pixel_scale(pixel_scale_meters);
02337 
02338       double ap_diameter_meters = circ_ap.get_diameter();
02339       vector<long> axes(2,(long)ceil(ap_diameter_meters/pixel_scale_meters));
02340       pixel_array<precision> covariance_pixarr(axes);
02341 
02342       double x_halfpix=0, y_halfpix=0;
02343       int x_extrapix=1, y_extrapix=1;
02344       if(axes[1]%2==0){
02345         x_halfpix = .5;
02346         x_extrapix = 0;
02347       }
02348       if(axes[0]%2==0){
02349         y_halfpix = .5;
02350         y_extrapix = 0;
02351       }
02352 
02353       double normalization_factor = 2*pixel_scale_meters/ap_diameter_meters;
02354       int arg_index = (xindex+axes[1]/2)*axes[0]+yindex+axes[0]/2;
02355       int loop_index;
02356       double val;
02357       double fac = Xi*pow(ap_diameter_meters,5/3.)*4*M_PI*M_PI/wavelength_meters/wavelength_meters;
02358       three_vector pixel_vector;
02359       three_vector normalized_tv = (three_point((xindex+x_halfpix)*normalization_factor,
02360                                                 (yindex+y_halfpix)*normalization_factor,
02361                                                 0,
02362                                                 this->circ_ap) - 
02363                                     this->circ_ap);
02364 
02365       if((normalized_tv.length()-1)>-three_frame::precision){
02366         cerr << "tilt_covariance::covariance error - "
02367              << "three_point lies outside of aperture\n";
02368         throw(string("tilt_covariance::covariance"));
02369       }
02370 
02371       double dot_prod_1 = dot_product(normalized_tv, omega_hat);
02372       double dot_prod_2;
02373       three_vector cross_prod = cross_product(normalized_tv, omega_hat);
02374       double cross_prod_fac;
02375 
02376       int half_axes_1 = axes[1]/2;
02377       int half_axes_0 = axes[0]/2;
02378 
02379       double arg_index_caliph_G = this->stored_caliph_G.data(arg_index);
02380       double arg_index_caliph_H = this->stored_caliph_H.data(arg_index);
02381       double arg_index_caliph_I = this->stored_caliph_I.data(arg_index);
02382       double arg_index_caliph_J = this->stored_caliph_J.data(arg_index);
02383 
02384 
02385       for(int m=-half_axes_1; m<half_axes_1+x_extrapix; m++){
02386         for(int n=-half_axes_0; n<half_axes_0+y_extrapix; n++){
02387         
02388           loop_index = (m+half_axes_1)*axes[0]+n+half_axes_0;
02389         
02390           pixel_vector = three_vector((m+x_halfpix)*normalization_factor,
02391                                       (n+y_halfpix)*normalization_factor,
02392                                       0,
02393                                       this->circ_ap);
02394         
02395           if(pixel_vector.length_squared()<=1){
02396 
02397             cross_prod_fac = 
02398               dot_product(cross_product(pixel_vector, omega_hat),
02399                           cross_prod);
02400             dot_prod_2 = dot_product(pixel_vector, omega_hat);
02401 
02402             val = 
02403               -dot_prod_1*dot_prod_2*this->stored_caliph_F +
02404               (dot_prod_1*dot_prod_2 - cross_prod_fac)*
02405               this->stored_caliph_F_bar;
02406 
02407             if(first_arg){
02408 
02409               val += dot_product(pixel_vector, normalized_tv)*
02410                 (this->stored_caliph_E -
02411                  this->stored_caliph_G.data(loop_index) -
02412                  arg_index_caliph_I);
02413 
02414               val += dot_prod_1*
02415                 (this->stored_caliph_H.data(loop_index) -
02416                  this->stored_caliph_K);
02417 
02418               val -= dot_prod_2*
02419                 (arg_index_caliph_J -
02420                  this->stored_caliph_L);
02421             } else {
02422               val += dot_product(pixel_vector, normalized_tv)*
02423                 (this->stored_caliph_E -
02424                  arg_index_caliph_G - 
02425                  this->stored_caliph_I.data(loop_index));
02426             
02427               val += dot_prod_2*
02428                 (arg_index_caliph_H - 
02429                  this->stored_caliph_K);
02430 
02431               val -= dot_prod_1*
02432                 (this->stored_caliph_J.data(loop_index) -
02433                  this->stored_caliph_L);
02434             }
02435 
02436             covariance_pixarr.set_data(loop_index, fac*val);
02437           }
02438         }
02439       }
02440       return(covariance_pixarr);
02441     } catch(...) {
02442       cerr << "tilt_covariance::covariance error - could not form covariance\n";
02443       throw(string("tilt_covariance::covariance"));
02444     }      
02445   }
02446 
02447   /*
02448   template<typename precision>
02449     tilt_covariance<precision, annular_aperture>::
02450     tilt_covariance(const emitter & emtr_a,
02451                     const emitter & emtr_b,
02452                     const refractive_atmospheric_model & ref_atm_model,
02453                     const annular_aperture & annular_ap) {
02454 
02455     circular_aperture circ_ap(annular_ap.get_outer_diameter());
02456     this->outer_aperture_tilt_covariance = 
02457       tilt_covariance<precision, circular_aperture>(emtr_a,
02458                                                     emtr_b,
02459                                                     ref_atm_model,
02460                                                     circ_ap);
02461     
02462     circ_ap = circular_aperture(annular_ap.get_inner_diameter());
02463     this->inner_aperture_tilt_covariance = 
02464       tilt_covariance<precision, circular_aperture>(emtr_a,
02465                                                     emtr_b,
02466                                                     ref_atm_model,
02467                                                     circ_ap);
02468 
02469   }
02470 
02471   template<typename precision>
02472     tilt_covariance<precision, annular_aperture> &
02473     tilt_covariance<precision, annular_aperture>::operator=(const tilt_covariance & tcv) {
02474 
02475     this->outer_aperture_tilt_covariance = tcv.outer_aperture_tilt_covariance;
02476     this->inner_aperture_tilt_covariance = tcv.inner_aperture_tilt_covariance;
02477   }
02478 
02479   template<typename precision>
02480     void tilt_covariance<precision, annular_aperture>::read(const char * filename){
02481     iofits iof;
02482     try{iof.open(filename);}
02483     catch(...){
02484       cerr << "tilt_covariance::read - "
02485            << "error opening file " << filename << endl;
02486       throw(string("tilt_covariance::read"));
02487     }
02488     try{this->read(iof);}
02489     catch(...){
02490       cerr << "tilt_covariance::read - "
02491            << "error reading "
02492            << this->unique_name() << " from file " 
02493            << filename << endl;
02494       throw(string("tilt_covariance::read"));
02495     }
02496   }
02497   
02498   template<typename precision>
02499     void tilt_covariance<precision, annular_aperture>::read(const Arroyo::iofits & iof){
02500     string type, comment;
02501     if (!iof.key_exists("TYPE"))
02502       {
02503         cerr << this->unique_name() << "::read error - unrecognized "
02504              << "file type" << endl;
02505         throw(this->unique_name() + string("::read"));
02506       }
02507     iof.read_key("TYPE",type,comment);
02508     if(type!=this->unique_name()){
02509       cerr << this->unique_name() << "::read error - file of type: " 
02510            << type << " rather than type " << this->unique_name() << endl;
02511       throw(this->unique_name() + string("::read"));
02512     }
02513 
02514     // Move to the next HDU
02515     iof.movrel_hdu(1);
02516 
02517 
02518     try{
02519       this->outer_aperture_tilt_covariance.read(iof);
02520     } catch(...){
02521       cerr << "tilt_covariance::read error - could not read outer aperture tilt covariance\n";
02522       throw(string("tilt_covariance::read"));
02523     }
02524 
02525     try{
02526       this->inner_aperture_tilt_covariance.read(iof);
02527     } catch(...){
02528       cerr << "tilt_covariance::read error - could not read inner aperture tilt covariance\n";
02529       throw(string("tilt_covariance::read"));
02530     }
02531 
02532   }
02533 
02534   template<typename precision>
02535     void tilt_covariance<precision, annular_aperture>::write(const char * filename) const {
02536 
02537     iofits iof;
02538     try{iof.create(filename);}
02539     catch(...){
02540       cerr << "tilt_covariance::write - "
02541            << "error opening file " << filename << endl;
02542       throw(string("tilt_covariance::write"));
02543     }
02544 
02545     try{this->write(iof);}
02546     catch(...){
02547       cerr << "tilt_covariance::write - "
02548            << "error writing "
02549            << this->unique_name() << " to file " 
02550            << filename << endl;
02551       throw(string("tilt_covariance::write"));
02552     }
02553   }
02554 
02555   template<typename precision>
02556     void tilt_covariance<precision, annular_aperture>::write(Arroyo::iofits & iof) const {
02557 
02558     fits_header_data<double> tmphdr;
02559     tmphdr.write(iof);
02560 
02561     string type, comment;
02562 
02563     type = this->unique_name();
02564     comment = "object type";
02565     iof.write_key("TYPE", type, comment);
02566 
02567     try{this->outer_aperture_tilt_covariance.write(iof);}
02568     catch(...){
02569       cerr << "tilt_covariance::write error - could not write outer aperture tilt covariance\n";
02570       throw(string("tilt_covariance::write"));
02571     }
02572       
02573     try{this->inner_aperture_tilt_covariance.write(iof);}
02574     catch(...){
02575       cerr << "tilt_covariance::write error - could not write inner aperture tilt covariance\n";
02576       throw(string("tilt_covariance::write"));
02577     }
02578       
02579   }
02580 
02581   template<typename precision>
02582     void tilt_covariance<precision, annular_aperture>::print(std::ostream & os, 
02583                                                              const char * prefix) const {
02584 
02585     int vlspc = 30;
02586     os.setf(ios::left, ios::adjustfield); 
02587     os << prefix << "TYPE       = " << setw(vlspc) << this->unique_name()
02588        << "/" << "object type" << endl;
02589     this->outer_aperture_tilt_covariance.print(os, prefix);
02590     this->inner_aperture_tilt_covariance.print(os, prefix);
02591   }
02592 
02593   template<typename precision>
02594     double tilt_covariance<precision, annular_aperture>::aperture_averaged_variance(double wavelength_meters,
02595                                                                                     int nsteps_in_integration) const {
02596     
02597     try{
02598       return(this->outer_aperture_tilt_covariance.aperture_averaged_variance(wavelength_meters,
02599                                                                              nsteps_in_integration) - 
02600              this->inner_aperture_tilt_covariance.aperture_averaged_variance(wavelength_meters,
02601                                                                              nsteps_in_integration));
02602     } catch(...){
02603       cerr << "tilt_covariance::aperture_averaged_variance error - could not form variance\n";
02604       throw(string("tilt_covariance::aperture_averaged_variance"));
02605     }      
02606   }
02607 
02608   template<typename precision>
02609     double tilt_covariance<precision, annular_aperture>::variance(double wavelength_meters,
02610                                                                   int nsteps_in_integration,
02611                                                                   const three_point & tp) const {
02612     
02613     try{
02614       return(this->outer_aperture_tilt_covariance.variance(wavelength_meters,
02615                                                            nsteps_in_integration,
02616                                                            tp) - 
02617              this->inner_aperture_tilt_covariance.variance(wavelength_meters,
02618                                                            nsteps_in_integration,
02619                                                            tp));
02620     } catch(...) {
02621       cerr << "tilt_covariance::variance error - could not form variance\n";
02622       throw(string("tilt_covariance::variance"));
02623     }      
02624 
02625   }
02626 
02627   template<typename precision>
02628     pixel_array<precision> 
02629     tilt_covariance<precision, annular_aperture>::variance(double pixel_scale_meters,
02630                                                            double wavelength_meters,
02631                                                            int nsteps_in_integration) const {
02632 
02633     try{
02634       return(this->outer_aperture_tilt_covariance.variance(pixel_scale_meters,
02635                                                            wavelength_meters,
02636                                                            nsteps_in_integration) - 
02637              this->inner_aperture_tilt_covariance.variance(pixel_scale_meters,
02638                                                            wavelength_meters,
02639                                                            nsteps_in_integration));
02640     } catch(...) {
02641       cerr << "tilt_covariance::variance error - could not form variance\n";
02642       throw(string("tilt_covariance::variance"));
02643     }      
02644   }
02645     
02646   template<typename precision>
02647     double tilt_covariance<precision, annular_aperture>::covariance(double wavelength_meters,
02648                                                                     int nsteps_in_integration,
02649                                                                     const three_point & tp1,
02650                                                                     const three_point & tp2) const {
02651     
02652     try{
02653       return(this->outer_aperture_tilt_covariance.covariance(wavelength_meters,
02654                                                              nsteps_in_integration,
02655                                                              tp1,
02656                                                              tp2) - 
02657              this->inner_aperture_tilt_covariance.covariance(wavelength_meters,
02658                                                              nsteps_in_integration,
02659                                                              tp1,
02660                                                              tp2));
02661     } catch(...) {
02662       cerr << "tilt_covariance::covariance error - could not form covariance\n";
02663       throw(string("tilt_covariance::covariance"));
02664     }      
02665   }
02666 
02667   template<typename precision>
02668     pixel_array<precision> 
02669     tilt_covariance<precision, annular_aperture>::covariance(double pixel_scale_meters,
02670                                                              double wavelength_meters,
02671                                                              int nsteps_in_integration,
02672                                                              const three_point & tp,
02673                                                              bool first_arg) const {
02674     
02675     try{
02676       return(this->outer_aperture_tilt_covariance.covariance(pixel_scale_meters,
02677                                                              wavelength_meters,
02678                                                              nsteps_in_integration,
02679                                                              tp,
02680                                                              first_arg) - 
02681              this->inner_aperture_tilt_covariance.covariance(pixel_scale_meters,
02682                                                              wavelength_meters,
02683                                                              nsteps_in_integration,
02684                                                              tp,
02685                                                              first_arg));
02686     } catch(...) {
02687       cerr << "tilt_covariance::covariance error - could not form covariance\n";
02688       throw(string("tilt_covariance::covariance"));
02689     }      
02690   }
02691 
02692   template<typename precision>
02693     pixel_array<precision> 
02694     tilt_covariance<precision, annular_aperture>::covariance(double pixel_scale_meters,
02695                                                              double wavelength_meters,
02696                                                              int nsteps_in_integration,
02697                                                              int xindex,
02698                                                              int yindex,
02699                                                              bool first_arg) const {
02700 
02701     try{
02702       return(this->outer_aperture_tilt_covariance.covariance(pixel_scale_meters,
02703                                                              wavelength_meters,
02704                                                              nsteps_in_integration,
02705                                                              xindex,
02706                                                              yindex,
02707                                                              first_arg) - 
02708              this->inner_aperture_tilt_covariance.covariance(pixel_scale_meters,
02709                                                              wavelength_meters,
02710                                                              nsteps_in_integration,
02711                                                              xindex,
02712                                                              yindex,
02713                                                              first_arg));
02714     } catch(...) {
02715       cerr << "tilt_covariance::covariance error - could not form covariance\n";
02716       throw(string("tilt_covariance::covariance"));
02717     }      
02718   }
02719   */
02720 }
02721 
02722 #endif

Generated on Thu Nov 29 17:16:28 2007 for arroyo by  doxygen 1.3.9.1