00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00251
00252
00253
00254
00255
00256
00257
00260
00261
00262
00263
00264
00265
00266
00269
00270
00273
00274
00275
00276
00277
00280
00281
00284
00285
00286
00287
00290
00291
00292
00293
00296
00297
00298
00299
00302
00303
00306
00307
00310
00311
00314
00315
00318
00319
00322
00323
00326
00327
00328
00329
00332
00333
00334
00335
00336
00337
00338
00341
00342
00343
00344
00347
00348
00349
00350
00353
00354
00355
00359
00360
00361
00362
00365
00366
00367
00368
00372
00373
00374
00375
00376
00380
00381
00382
00383
00384
00385
00390
00391
00392
00393
00394
00395
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
00609
00610
00611
00612
00613
00614
00615
00618
00619
00620
00621
00622
00623
00624
00625
00626
00629
00630
00633
00634
00635
00636
00637
00640
00641
00644
00645
00646
00647
00650
00651
00652
00653
00656
00657
00658
00659
00662
00663
00666
00667
00670
00671
00674
00675
00678
00679
00682
00683
00686
00687
00688
00689
00692
00693
00694
00695
00696
00697
00698
00701
00702
00703
00704
00707
00708
00709
00710
00713
00714
00715
00719
00720
00721
00722
00725
00726
00727
00728
00732
00733
00734
00735
00736
00740
00741
00742
00743
00744
00745
00750
00751
00752
00753
00754
00755
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
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
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
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
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
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720 }
02721
02722 #endif