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 REFRACTIVE_ATMOSPHERE_H
00032 #define REFRACTIVE_ATMOSPHERE_H
00033
00034 #include <three_frame.h>
00035 #include <region_base.h>
00036 #include <computational_geometry.h>
00037 #include "AO_sim_base.h"
00038 #include "fits_header_data.h"
00039 #include "pixel_array.h"
00040 #include "power_spectrum.h"
00041 #include "propagation_plan.h"
00042 #include "aperture.h"
00043 #include "emitter.h"
00044 #include "special_functions.h"
00045
00046 namespace Arroyo {
00047
00048 using std::vector;
00049 using std::ostream;
00050
00051 class subharmonic_method;
00052
00059
00060 class refractive_atmospheric_model :
00061 virtual public AO_sim_base {
00062
00063 private:
00064
00065 static const bool factory_registration;
00066
00069 string unique_name() const {return(string("refractive atmospheric model"));};
00070
00071 protected:
00072
00074 vector<power_spectrum *> power_spectra_;
00075
00077 vector<double> layer_heights_;
00078
00080 three_frame ground_ref_frame_;
00081
00087 void read_common_data(const iofits & iof);
00088
00094 void write_common_data(iofits & iof) const;
00095
00096 public:
00097
00100 refractive_atmospheric_model(){};
00101
00104 refractive_atmospheric_model(const refractive_atmospheric_model & ref_atm_model);
00105
00108 refractive_atmospheric_model(const char * filename);
00109
00112 refractive_atmospheric_model(const iofits & iof);
00113
00121 refractive_atmospheric_model(const vector<power_spectrum *> & power_spectra,
00122 const vector<double> & layer_heights,
00123 const three_frame & ground_ref_frame);
00124
00127 ~refractive_atmospheric_model();
00128
00131 refractive_atmospheric_model &
00132 operator=(const refractive_atmospheric_model & ref_atm_model);
00133
00138 virtual refractive_atmospheric_model * clone() const {
00139 return new refractive_atmospheric_model(*this);
00140 };
00141
00144 void read(const char * filename);
00145
00148 void read(const iofits & iof);
00149
00152 void write(const char * filename) const;
00153
00156 void write(iofits & iof) const;
00157
00160 void print(ostream & os, const char * prefix="") const;
00161
00164 long get_number_of_layers() const {return layer_heights_.size();};
00165
00168 vector<double> get_layer_heights() const {return layer_heights_;};
00169
00173 vector<power_spectrum *> get_power_spectra() const {
00174 vector<power_spectrum *> pspec(this->power_spectra_.size());
00175 for(int i=0; i<pspec.size(); i++)
00176 pspec[i] = power_spectrum::power_spectrum_factory(this->power_spectra_[i]);
00177 return(pspec);
00178 };
00179
00182 three_frame get_three_frame() const {return this->ground_ref_frame_;};
00183
00193 double turbulence_moment(double moment,
00194 double zenith_angle_degrees=0) const;
00195
00209 double velocity_moment(const vector<three_vector> & layer_wind_velocities_meters_per_sec,
00210 double moment,
00211 double azimuth_angle_degrees=0,
00212 double zenith_angle_degrees=0) const;
00213
00222 double fried_parameter(double wavelength_meters,
00223 double zenith_angle_degrees=0,
00224 double guide_star_height_meters=-1) const;
00225
00234 double seeing(double wavelength_meters,
00235 double zenith_angle_degrees=0) const;
00236
00245 double isoplanatic_angle(double wavelength_meters,
00246 double zenith_angle_degrees=0) const;
00247
00256 double isokinetic_angle(double wavelength_meters,
00257 double aperture_diameter_meters,
00258 double zenith_angle_degrees=0) const;
00259
00272 double greenwood_frequency(vector<three_vector> & layer_wind_velocities_meters_per_sec,
00273 double wavelength_meters,
00274 double azimuth_angle_degrees=0,
00275 double zenith_angle_degrees=0) const;
00276
00285 double d_0(double guide_star_height_meters,
00286 double wavelength_meters,
00287 double zenith_angle_degrees=0) const;
00288
00289
00292 double Tyler_F_1(double x) const;
00293
00296 double Tyler_H(double & rho,
00297 double & omega,
00298 vector<double> & numerator_args,
00299 vector<double> & denominator_args) const;
00300
00303 double Tyler_K_1(double rho, double q) const;
00304
00307 double Tyler_F_2(double q,
00308 double omega,
00309 int nsamples_in_integration) const;
00310
00313 double Tyler_G_hat(double rho) const;
00314
00317 double Tyler_G_1(three_vector r1,
00318 three_vector r2) const;
00319
00322 double Tyler_G_2(three_vector r,
00323 double q,
00324 three_vector omega,
00325 int nsamples_in_integration) const;
00326
00329 double Tyler_G_3(double q,
00330 double omega,
00331 int nsamples_in_integration) const;
00332
00335 double Tyler_G_4(three_vector r1,
00336 three_vector r2,
00337 double q,
00338 three_vector omega,
00339 int nsamples_in_integration) const;
00340
00343 void Tyler_get_constants(const emitter & emtr_a,
00344 const emitter & emtr_b,
00345 const three_frame & tf,
00346 double aperture_diameter_meters,
00347 double & secant_zenith_angle,
00348 double & max_range_meters,
00349 double & min_range_meters,
00350 three_vector & little_omega) const;
00351
00356 vector<double> get_cn2_coefficients() const;
00357
00362 double caliph_A(const emitter & emtr_a,
00363 const emitter & emtr_b,
00364 double aperture_diameter_meters,
00365 const three_vector & rho) const;
00366
00369 template<class T>
00370 pixel_array<T> caliph_A(const emitter & emtr_a,
00371 const emitter & emtr_b,
00372 double aperture_diameter_meters,
00373 double pixel_scale_meters) const;
00374
00379 double caliph_B(const emitter & emtr_a,
00380 const emitter & emtr_b,
00381 double aperture_diameter_meters,
00382 const three_vector & rho) const;
00383
00386 template<class T>
00387 pixel_array<T> caliph_B(const emitter & emtr_a,
00388 const emitter & emtr_b,
00389 double aperture_diameter_meters,
00390 double pixel_scale_meters) const;
00391
00397 double caliph_C(const emitter & emtr_a,
00398 const emitter & emtr_b,
00399 double aperture_diameter_meters,
00400 const three_vector & rho_1,
00401 const three_vector & rho_2) const;
00402
00405 template<class T>
00406 pixel_array<T> caliph_C(const emitter & emtr_a,
00407 const emitter & emtr_b,
00408 double aperture_diameter_meters,
00409 double pixel_scale_meters) const;
00410
00413 double caliph_D(const emitter & emtr_a,
00414 const emitter & emtr_b,
00415 double aperture_diameter_meters,
00416 int nsteps_in_integration) const;
00417
00420 double caliph_E(const emitter & emtr_a,
00421 const emitter & emtr_b,
00422 double aperture_diameter_meters,
00423 int nsteps_in_integration) const;
00424
00427 double caliph_F(const emitter & emtr_a,
00428 const emitter & emtr_b,
00429 double aperture_diameter_meters,
00430 int nsteps_in_integration) const;
00431
00434 double caliph_F_bar(const emitter & emtr_a,
00435 const emitter & emtr_b,
00436 double aperture_diameter_meters,
00437 int nsteps_in_integration) const;
00438
00439
00442
00443
00444
00445
00446
00449
00450
00451
00452
00453
00456
00457
00458
00459
00460
00461
00466 double caliph_G(const emitter & emtr_a,
00467 const emitter & emtr_b,
00468 double aperture_diameter_meters,
00469 const three_vector & rho) const;
00470
00473 template<class T>
00474 pixel_array<T> caliph_G(const emitter & emtr_a,
00475 const emitter & emtr_b,
00476 double aperture_diameter_meters,
00477 double pixel_scale_meters) const;
00478
00483 double caliph_H(const emitter & emtr_a,
00484 const emitter & emtr_b,
00485 double aperture_diameter_meters,
00486 const three_vector & rho) const;
00487
00490 template<class T>
00491 pixel_array<T> caliph_H(const emitter & emtr_a,
00492 const emitter & emtr_b,
00493 double aperture_diameter_meters,
00494 double pixel_scale_meters) const;
00495
00500 double caliph_I(const emitter & emtr_a,
00501 const emitter & emtr_b,
00502 double aperture_diameter_meters,
00503 const three_vector & rho) const;
00504
00507 template<class T>
00508 pixel_array<T> caliph_I(const emitter & emtr_a,
00509 const emitter & emtr_b,
00510 double aperture_diameter_meters,
00511 double pixel_scale_meters) const;
00512
00517 double caliph_J(const emitter & emtr_a,
00518 const emitter & emtr_b,
00519 double aperture_diameter_meters,
00520 const three_vector & rho) const;
00521
00524 template<class T>
00525 pixel_array<T> caliph_J(const emitter & emtr_a,
00526 const emitter & emtr_b,
00527 double aperture_diameter_meters,
00528 double pixel_scale_meters) const;
00529
00532 double caliph_K(const emitter & emtr_a,
00533 const emitter & emtr_b,
00534 double aperture_diameter_meters,
00535 int nsteps_in_integration) const;
00536
00539 double caliph_L(const emitter & emtr_a,
00540 const emitter & emtr_b,
00541 double aperture_diameter_meters,
00542 int nsteps_in_integration) const;
00543
00546 double caliph_M(const emitter & emtr_a,
00547 const emitter & emtr_b,
00548 double aperture_diameter_meters) const;
00549
00562 double aperture_averaged_phase_covariance(const emitter & emtr_a,
00563 const emitter & emtr_b,
00564 const aperture & ap,
00565 double wavelength_meters,
00566 int nsteps_in_integration=1000) const;
00567
00580 double aperture_averaged_tilt_phase_covariance(const emitter & emtr_a,
00581 const emitter & emtr_b,
00582 const aperture & ap,
00583 double wavelength_meters,
00584 int nsteps_in_integration=1000) const;
00585
00596 double aperture_averaged_parallel_tilt_phase_covariance(const emitter & emtr_a,
00597 const emitter & emtr_b,
00598 const aperture & ap,
00599 double wavelength_meters,
00600 int nsteps_in_integration=1000) const;
00601
00612 double aperture_averaged_perpendicular_tilt_phase_covariance(const emitter & emtr_a,
00613 const emitter & emtr_b,
00614 const aperture & ap,
00615 double wavelength_meters,
00616 int nsteps_in_integration=1000) const;
00617
00633 double phase_covariance(const emitter & emtr_a,
00634 const three_point & pupil_location_one,
00635 const emitter & emtr_b,
00636 const three_point & pupil_location_two,
00637 const aperture & ap,
00638 double wavelength_meters,
00639 int nsteps_in_integration=1000) const;
00640
00656 double tilt_phase_covariance(const emitter & emtr_a,
00657 const three_point & pupil_location_one,
00658 const emitter & emtr_b,
00659 const three_point & pupil_location_two,
00660 const aperture & ap,
00661 double wavelength_meters,
00662 int nsteps_in_integration=1000) const;
00663
00681 template<class T>
00682 diffractive_wavefront_header<T> get_diffractive_wavefront_header(double wavelength,
00683 double pixscale,
00684 const emitter * emtr,
00685 const aperture * ap,
00686 bool layer_foreshortening,
00687 propagation_plan * pplan) const;
00688
00689
00716 template<class T, class U>
00717 void get_refractive_atmospheric_layers(const vector<double> & layer_pixscales,
00718 const subharmonic_method & subm,
00719 const vector<diffractive_wavefront_header<T> > dwfhdrs,
00720 const vector<three_vector> layer_wind_vectors,
00721 double time_interval,
00722 bool layer_axes_wind_vector_aligned,
00723 bool layer_foreshortening,
00724 vector<refractive_atmospheric_layer<U> > & ref_atm_layers) const;
00725
00726 static int verbose_level;
00727
00728 };
00729
00730
00731
00732 namespace {
00733
00734 void check_wavelength(double wavelength_meters){
00735 if(wavelength_meters<=0){
00736 cerr << "check_wavelength error\n"
00737 << "wavelength "
00738 << wavelength_meters
00739 << " out of range\n";
00740 throw(string("check_wavelength"));
00741 }
00742 }
00743
00744 void check_zenith(double zenith_angle_degrees){
00745 if(zenith_angle_degrees<0 ||
00746 zenith_angle_degrees>=90){
00747 cerr << "check_zenith error\n"
00748 << "zenith angle "
00749 << zenith_angle_degrees
00750 << " out of range\n";
00751 throw(string("check_zenith"));
00752 }
00753 }
00754
00755 void check_wavelength_zenith(double wavelength_meters,
00756 double zenith_angle_degrees){
00757 check_wavelength(wavelength_meters);
00758 check_zenith(zenith_angle_degrees);
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 double get_cn2_coefficient(double power_law_coefficient){
00777 static double fac = 2*M_PI*5*gamma_function(5/6.)/pow(2,4/3.)/pow(M_PI,3/2.)/9./gamma_function(2/3.);
00778 return(power_law_coefficient/fac);
00779 }
00780 }
00781
00782
00783
00784 template<class T>
00785 pixel_array<T> refractive_atmospheric_model::caliph_A(const emitter & emtr_a,
00786 const emitter & emtr_b,
00787 double aperture_diameter_meters,
00788 double pixel_scale_meters) const {
00789
00790 if(aperture_diameter_meters<=0){
00791 cerr << "refractive_atmospheric_model::caliph_A error - \n"
00792 << "invalid aperture diameter "
00793 << aperture_diameter_meters
00794 << " passed to this function\n";
00795 throw(string("refractive_atmospheric_model::caliph_A"));
00796 }
00797
00798 if(pixel_scale_meters<=0){
00799 cerr << "refractive_atmospheric_model::caliph_A error -\n"
00800 << "pixel scale "
00801 << pixel_scale_meters
00802 << " out of range\n";
00803 throw(string("refractive_atmospheric_model::caliph_A"));
00804 }
00805
00806 T * data;
00807 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
00808 try{
00809 data = new T[axes[0]*axes[1]];
00810 } catch(...) {
00811 cerr << "refractive_atmospheric_model::caliph_A - error allocating memory\n";
00812 throw(string("refractive_atmospheric_model::caliph_A"));
00813 }
00814
00815 try{
00816 double secant_zenith_angle;
00817 double max_range_meters;
00818 double min_range_meters;
00819 three_vector little_omega;
00820
00821 Tyler_get_constants(emtr_a,
00822 emtr_b,
00823 this->ground_ref_frame_,
00824 aperture_diameter_meters,
00825 secant_zenith_angle,
00826 max_range_meters,
00827 min_range_meters,
00828 little_omega);
00829
00830 double val;
00831
00832 double Q;
00833
00834 double x_halfpix=0, y_halfpix=0;
00835 int x_extrapix=1, y_extrapix=1;
00836 if(axes[1]%2==0){
00837 x_halfpix = .5;
00838 x_extrapix = 0;
00839 }
00840 if(axes[0]%2==0){
00841 y_halfpix = .5;
00842 y_extrapix = 0;
00843 }
00844
00845 three_vector pixel_vector;
00846 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
00847 int index;
00848
00849 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
00850 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
00851 pixel_vector =
00852 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
00853 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
00854
00855 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
00856
00857 if(pixel_vector.length_squared()>1)
00858 data[index]=0;
00859 else {
00860 val = 0;
00861 for(int k=0; k<this->power_spectra_.size(); k++){
00862 if(layer_heights_[k]>min_range_meters) continue;
00863
00864 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
00865 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
00866
00867 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
00868 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
00869 pow(Q,5/3.) *
00870 Tyler_F_1((pixel_vector +
00871 (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length()
00872 /Q);
00873 }
00874 data[index] = val;
00875 }
00876 }
00877 }
00878 } catch(...) {
00879 cerr << "refractive_atmospheric_model::caliph_A error\n";
00880 throw(string("refractive_atmospheric_model::caliph_A"));
00881 }
00882
00883 pixel_array<T> pixarr(axes,data);
00884 delete [] data;
00885 return(pixarr);
00886 }
00887
00888 template<class T>
00889 pixel_array<T> refractive_atmospheric_model::caliph_B(const emitter & emtr_a,
00890 const emitter & emtr_b,
00891 double aperture_diameter_meters,
00892 double pixel_scale_meters) const {
00893
00894 if(aperture_diameter_meters==0){
00895 cerr << "refractive_atmospheric_model::caliph_B error - \n"
00896 << "invalid aperture diameter "
00897 << aperture_diameter_meters
00898 << " passed to this function\n";
00899 throw(string("refractive_atmospheric_model::caliph_B"));
00900 }
00901
00902 if(pixel_scale_meters<=0){
00903 cerr << "refractive_atmospheric_model::caliph_B error -\n"
00904 << "pixel scale "
00905 << pixel_scale_meters
00906 << " out of range\n";
00907 throw(string("refractive_atmospheric_model::caliph_B"));
00908 }
00909
00910 T * data;
00911 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
00912 try{
00913 data = new T[axes[0]*axes[1]];
00914 } catch(...) {
00915 cerr << "refractive_atmospheric_model::caliph_B - error allocating memory\n";
00916 throw(string("refractive_atmospheric_model::caliph_B"));
00917 }
00918
00919 try{
00920 double secant_zenith_angle;
00921 double max_range_meters;
00922 double min_range_meters;
00923 three_vector little_omega;
00924
00925 Tyler_get_constants(emtr_a,
00926 emtr_b,
00927 this->ground_ref_frame_,
00928 aperture_diameter_meters,
00929 secant_zenith_angle,
00930 max_range_meters,
00931 min_range_meters,
00932 little_omega);
00933
00934 double val;
00935
00936 double Q;
00937
00938 double x_halfpix=0, y_halfpix=0;
00939 int x_extrapix=1, y_extrapix=1;
00940 if(axes[1]%2==0){
00941 x_halfpix = .5;
00942 x_extrapix = 0;
00943 }
00944 if(axes[0]%2==0){
00945 y_halfpix = .5;
00946 y_extrapix = 0;
00947 }
00948
00949 three_vector pixel_vector;
00950 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
00951 int index;
00952
00953 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
00954 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
00955 pixel_vector =
00956 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
00957 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
00958
00959 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
00960 if(pixel_vector.length_squared()>1)
00961 data[index]=0;
00962 else {
00963 val = 0;
00964 for(int k=0; k<this->power_spectra_.size(); k++){
00965 if(layer_heights_[k]>min_range_meters) continue;
00966
00967 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
00968 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
00969
00970 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
00971 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
00972 Tyler_F_1(((Q*pixel_vector) -
00973 (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length());
00974 }
00975 data[index] = val;
00976 }
00977 }
00978 }
00979 } catch(...) {
00980 cerr << "refractive_atmospheric_model::caliph_B error\n";
00981 throw(string("refractive_atmospheric_model::caliph_B"));
00982 }
00983 pixel_array<T> pixarr(axes,data);
00984 delete [] data;
00985 return(pixarr);
00986 }
00987
00988 template<class T>
00989 pixel_array<T> refractive_atmospheric_model::caliph_C(const emitter & emtr_a,
00990 const emitter & emtr_b,
00991 double aperture_diameter_meters,
00992 double pixel_scale_meters) const {
00993
00994 if(aperture_diameter_meters==0){
00995 cerr << "refractive_atmospheric_model::caliph_C error - \n"
00996 << "invalid aperture diameter "
00997 << aperture_diameter_meters
00998 << " passed to this function\n";
00999 throw(string("refractive_atmospheric_model::caliph_C"));
01000 }
01001
01002 if(pixel_scale_meters<=0){
01003 cerr << "refractive_atmospheric_model::caliph_C error -\n"
01004 << "pixel scale "
01005 << pixel_scale_meters
01006 << " out of range\n";
01007 throw(string("refractive_atmospheric_model::caliph_C"));
01008 }
01009
01010 T * data;
01011 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
01012 try{
01013 data = new T[axes[0]*axes[1]];
01014 } catch(...) {
01015 cerr << "refractive_atmospheric_model::caliph_C - error allocating memory\n";
01016 throw(string("refractive_atmospheric_model::caliph_C"));
01017 }
01018
01019 try{
01020 double secant_zenith_angle;
01021 double max_range_meters;
01022 double min_range_meters;
01023 three_vector little_omega;
01024
01025 Tyler_get_constants(emtr_a,
01026 emtr_b,
01027 this->ground_ref_frame_,
01028 aperture_diameter_meters,
01029 secant_zenith_angle,
01030 max_range_meters,
01031 min_range_meters,
01032 little_omega);
01033
01034 double val;
01035
01036 double Q;
01037
01038 double x_halfpix=0, y_halfpix=0;
01039 int x_extrapix=1, y_extrapix=1;
01040 if(axes[1]%2==0){
01041 x_halfpix = .5;
01042 x_extrapix = 0;
01043 }
01044 if(axes[0]%2==0){
01045 y_halfpix = .5;
01046 y_extrapix = 0;
01047 }
01048
01049 three_vector pixel_vector;
01050 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
01051 int index;
01052
01053 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
01054 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
01055 pixel_vector =
01056 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
01057 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
01058
01059 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
01060
01061 if(pixel_vector.length_squared()>1)
01062 data[index]=0;
01063 else {
01064 val = 0;
01065 for(int k=0; k<this->power_spectra_.size(); k++){
01066 if(layer_heights_[k]>min_range_meters) continue;
01067
01068 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
01069 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
01070
01071 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
01072 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
01073 pow((pixel_vector*(1 - Q) +
01074 (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length(),5/3.);
01075
01076 }
01077 data[index] = val;
01078 if(!finite(val)){
01079 cerr << "refractive_atmospheric_model::caliph_C error - value "
01080 << val
01081 << " not finite\n";
01082 throw(string("refractive_atmospheric_model::caliph_C"));
01083 }
01084 }
01085 }
01086 }
01087 } catch(...) {
01088 cerr << "refractive_atmospheric_model::caliph_C error\n";
01089 throw(string("refractive_atmospheric_model::caliph_C"));
01090 }
01091 pixel_array<T> pixarr(axes,data);
01092 delete [] data;
01093 return(pixarr);
01094 }
01095
01096 template<class T>
01097 pixel_array<T> refractive_atmospheric_model::caliph_G(const emitter & emtr_a,
01098 const emitter & emtr_b,
01099 double aperture_diameter_meters,
01100 double pixel_scale_meters) const {
01101
01102 if(aperture_diameter_meters==0){
01103 cerr << "refractive_atmospheric_model::caliph_G error - \n"
01104 << "invalid aperture diameter "
01105 << aperture_diameter_meters
01106 << " passed to this function\n";
01107 throw(string("refractive_atmospheric_model::caliph_G"));
01108 }
01109
01110 if(pixel_scale_meters<=0){
01111 cerr << "refractive_atmospheric_model::caliph_G error -\n"
01112 << "pixel scale "
01113 << pixel_scale_meters
01114 << " out of range\n";
01115 throw(string("refractive_atmospheric_model::caliph_G"));
01116 }
01117
01118 T * data;
01119 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
01120 try{
01121 data = new T[axes[0]*axes[1]];
01122 } catch(...) {
01123 cerr << "refractive_atmospheric_model::caliph_G - error allocating memory\n";
01124 throw(string("refractive_atmospheric_model::caliph_G"));
01125 }
01126
01127 try{
01128 double secant_zenith_angle;
01129 double max_range_meters;
01130 double min_range_meters;
01131 three_vector little_omega;
01132
01133 Tyler_get_constants(emtr_a,
01134 emtr_b,
01135 this->ground_ref_frame_,
01136 aperture_diameter_meters,
01137 secant_zenith_angle,
01138 max_range_meters,
01139 min_range_meters,
01140 little_omega);
01141
01142 double ghat_arg;
01143 double val;
01144
01145 double Q;
01146
01147 double x_halfpix=0, y_halfpix=0;
01148 int x_extrapix=1, y_extrapix=1;
01149 if(axes[1]%2==0){
01150 x_halfpix = .5;
01151 x_extrapix = 0;
01152 }
01153 if(axes[0]%2==0){
01154 y_halfpix = .5;
01155 y_extrapix = 0;
01156 }
01157
01158 three_vector pixel_vector;
01159 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
01160 int index;
01161
01162 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
01163 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
01164 pixel_vector =
01165 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
01166 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
01167
01168 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
01169
01170 if(pixel_vector.length_squared()>1)
01171 data[index]=0;
01172 else {
01173 val = 0;
01174 for(int k=0; k<this->power_spectra_.size(); k++){
01175 if(layer_heights_[k]>min_range_meters) continue;
01176
01177 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
01178 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
01179
01180 ghat_arg =
01181 ((pixel_vector*Q) - (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length();
01182
01183 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
01184 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
01185 Q * Tyler_G_hat(ghat_arg);
01186 }
01187
01188 data[index] = 4*val;
01189 }
01190 }
01191 }
01192 } catch(...) {
01193 cerr << "refractive_atmospheric_model::caliph_G error\n";
01194 throw(string("refractive_atmospheric_model::caliph_G"));
01195 }
01196 pixel_array<T> pixarr(axes,data);
01197 delete [] data;
01198 return(pixarr);
01199 }
01200
01201 template<class T>
01202 pixel_array<T> refractive_atmospheric_model::caliph_H(const emitter & emtr_a,
01203 const emitter & emtr_b,
01204 double aperture_diameter_meters,
01205 double pixel_scale_meters) const {
01206
01207 if(aperture_diameter_meters==0){
01208 cerr << "refractive_atmospheric_model::caliph_H error - \n"
01209 << "invalid aperture diameter "
01210 << aperture_diameter_meters
01211 << " passed to this function\n";
01212 throw(string("refractive_atmospheric_model::caliph_H"));
01213 }
01214
01215 if(pixel_scale_meters<=0){
01216 cerr << "refractive_atmospheric_model::caliph_H error -\n"
01217 << "pixel scale "
01218 << pixel_scale_meters
01219 << " out of range\n";
01220 throw(string("refractive_atmospheric_model::caliph_H"));
01221 }
01222
01223 T * data;
01224 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
01225 try{
01226 data = new T[axes[0]*axes[1]];
01227 } catch(...) {
01228 cerr << "refractive_atmospheric_model::caliph_H - error allocating memory\n";
01229 throw(string("refractive_atmospheric_model::caliph_H"));
01230 }
01231
01232 try{
01233 double secant_zenith_angle;
01234 double max_range_meters;
01235 double min_range_meters;
01236 three_vector little_omega;
01237
01238 Tyler_get_constants(emtr_a,
01239 emtr_b,
01240 this->ground_ref_frame_,
01241 aperture_diameter_meters,
01242 secant_zenith_angle,
01243 max_range_meters,
01244 min_range_meters,
01245 little_omega);
01246
01247 double ghat_arg;
01248 double val;
01249
01250 double Q;
01251
01252 double x_halfpix=0, y_halfpix=0;
01253 int x_extrapix=1, y_extrapix=1;
01254 if(axes[1]%2==0){
01255 x_halfpix = .5;
01256 x_extrapix = 0;
01257 }
01258 if(axes[0]%2==0){
01259 y_halfpix = .5;
01260 y_extrapix = 0;
01261 }
01262
01263 three_vector pixel_vector;
01264 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
01265 int index;
01266
01267 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
01268 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
01269 pixel_vector =
01270 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
01271 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
01272
01273 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
01274
01275 if(pixel_vector.length_squared()>1)
01276 data[index]=0;
01277 else {
01278 val = 0;
01279 for(int k=0; k<this->power_spectra_.size(); k++){
01280 if(layer_heights_[k]>min_range_meters) continue;
01281
01282 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
01283 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
01284
01285 ghat_arg =
01286 ((pixel_vector*Q) - (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length();
01287
01288 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
01289 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
01290 little_omega.length()*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters))
01291 * Tyler_G_hat(ghat_arg);
01292 }
01293 data[index] = 4*val;
01294 }
01295 }
01296 }
01297 } catch(...) {
01298 cerr << "refractive_atmospheric_model::caliph_H error\n";
01299 throw(string("refractive_atmospheric_model::caliph_H"));
01300 }
01301 pixel_array<T> pixarr(axes,data);
01302 delete [] data;
01303 return(pixarr);
01304 }
01305
01306 template<class T>
01307 pixel_array<T> refractive_atmospheric_model::caliph_I(const emitter & emtr_a,
01308 const emitter & emtr_b,
01309 double aperture_diameter_meters,
01310 double pixel_scale_meters) const {
01311
01312 if(aperture_diameter_meters==0){
01313 cerr << "refractive_atmospheric_model::caliph_I error - \n"
01314 << "invalid aperture diameter "
01315 << aperture_diameter_meters
01316 << " passed to this function\n";
01317 throw(string("refractive_atmospheric_model::caliph_I"));
01318 }
01319
01320 if(pixel_scale_meters<=0){
01321 cerr << "refractive_atmospheric_model::caliph_I error -\n"
01322 << "pixel scale "
01323 << pixel_scale_meters
01324 << " out of range\n";
01325 throw(string("refractive_atmospheric_model::caliph_I"));
01326 }
01327
01328 T * data;
01329 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
01330 try{
01331 data = new T[axes[0]*axes[1]];
01332 } catch(...) {
01333 cerr << "refractive_atmospheric_model::caliph_I - error allocating memory\n";
01334 throw(string("refractive_atmospheric_model::caliph_I"));
01335 }
01336
01337 try{
01338 double secant_zenith_angle;
01339 double max_range_meters;
01340 double min_range_meters;
01341 three_vector little_omega;
01342
01343 Tyler_get_constants(emtr_a,
01344 emtr_b,
01345 this->ground_ref_frame_,
01346 aperture_diameter_meters,
01347 secant_zenith_angle,
01348 max_range_meters,
01349 min_range_meters,
01350 little_omega);
01351
01352 double ghat_arg;
01353 double val;
01354
01355 double Q;
01356
01357 double x_halfpix=0, y_halfpix=0;
01358 int x_extrapix=1, y_extrapix=1;
01359 if(axes[1]%2==0){
01360 x_halfpix = .5;
01361 x_extrapix = 0;
01362 }
01363 if(axes[0]%2==0){
01364 y_halfpix = .5;
01365 y_extrapix = 0;
01366 }
01367
01368 three_vector pixel_vector;
01369 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
01370 int index;
01371
01372 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
01373 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
01374 pixel_vector =
01375 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
01376 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
01377
01378 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
01379
01380 if(pixel_vector.length_squared()>1)
01381 data[index]=0;
01382 else {
01383 val = 0;
01384 for(int k=0; k<this->power_spectra_.size(); k++){
01385 if(layer_heights_[k]>min_range_meters) continue;
01386
01387 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
01388 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
01389
01390 ghat_arg =
01391 (pixel_vector + (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length()/Q;
01392
01393 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
01394 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
01395 pow(Q,2/3.) *
01396 Tyler_G_hat(ghat_arg);
01397 }
01398 data[index] = 4*val;
01399 }
01400 }
01401 }
01402 } catch(...) {
01403 cerr << "refractive_atmospheric_model::caliph_I error\n";
01404 throw(string("refractive_atmospheric_model::caliph_I"));
01405 }
01406 pixel_array<T> pixarr(axes,data);
01407 delete [] data;
01408 return(pixarr);
01409 }
01410
01411 template<class T>
01412 pixel_array<T> refractive_atmospheric_model::caliph_J(const emitter & emtr_a,
01413 const emitter & emtr_b,
01414 double aperture_diameter_meters,
01415 double pixel_scale_meters) const {
01416
01417 if(aperture_diameter_meters==0){
01418 cerr << "refractive_atmospheric_model::caliph_J error - \n"
01419 << "invalid aperture diameter "
01420 << aperture_diameter_meters
01421 << " passed to this function\n";
01422 throw(string("refractive_atmospheric_model::caliph_J"));
01423 }
01424
01425 if(pixel_scale_meters<=0){
01426 cerr << "refractive_atmospheric_model::caliph_J error -\n"
01427 << "pixel scale "
01428 << pixel_scale_meters
01429 << " out of range\n";
01430 throw(string("refractive_atmospheric_model::caliph_J"));
01431 }
01432
01433 T * data;
01434 vector<long> axes(2,(long)ceil(aperture_diameter_meters/pixel_scale_meters));
01435 try{
01436 data = new T[axes[0]*axes[1]];
01437 } catch(...) {
01438 cerr << "refractive_atmospheric_model::caliph_J - error allocating memory\n";
01439 throw(string("refractive_atmospheric_model::caliph_J"));
01440 }
01441
01442 try{
01443 double secant_zenith_angle;
01444 double max_range_meters;
01445 double min_range_meters;
01446 three_vector little_omega;
01447
01448 Tyler_get_constants(emtr_a,
01449 emtr_b,
01450 this->ground_ref_frame_,
01451 aperture_diameter_meters,
01452 secant_zenith_angle,
01453 max_range_meters,
01454 min_range_meters,
01455 little_omega);
01456
01457 double ghat_arg;
01458 double val;
01459
01460 double Q;
01461
01462 double x_halfpix=0, y_halfpix=0;
01463 int x_extrapix=1, y_extrapix=1;
01464 if(axes[1]%2==0){
01465 x_halfpix = .5;
01466 x_extrapix = 0;
01467 }
01468 if(axes[0]%2==0){
01469 y_halfpix = .5;
01470 y_extrapix = 0;
01471 }
01472
01473 three_vector pixel_vector;
01474 double normalization_factor = 2*pixel_scale_meters/aperture_diameter_meters;
01475 int index;
01476
01477 for(int i=-axes[1]/2; i<axes[1]/2+x_extrapix; i++){
01478 for(int j=-axes[0]/2; j<axes[0]/2+y_extrapix; j++){
01479 pixel_vector =
01480 this->ground_ref_frame_.x()*((i+x_halfpix)*normalization_factor) +
01481 this->ground_ref_frame_.y()*((j+y_halfpix)*normalization_factor);
01482
01483 index = (i+axes[1]/2)*axes[0]+j+axes[0]/2;
01484
01485 if(pixel_vector.length_squared()>1)
01486 data[index]=0;
01487 else {
01488 val = 0;
01489 for(int k=0; k<this->power_spectra_.size(); k++){
01490 if(layer_heights_[k]>min_range_meters) continue;
01491
01492 Q = (1 - layer_heights_[k]*secant_zenith_angle/min_range_meters) /
01493 (1 - layer_heights_[k]*secant_zenith_angle/max_range_meters);
01494
01495 ghat_arg =
01496 (pixel_vector + (little_omega*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)))).length()/Q;
01497
01498 val += secant_zenith_angle*get_cn2_coefficient(power_spectra_[k]->get_coefficient()) *
01499 pow((1 - layer_heights_[k]*secant_zenith_angle/max_range_meters),5/3.) *
01500 pow(Q, 2/3.) *
01501 little_omega.length()*(layer_heights_[k]/(1-layer_heights_[k]/max_range_meters)) *
01502 Tyler_G_hat(ghat_arg);
01503 }
01504 data[index] = 4*val;
01505 }
01506 }
01507 }
01508 } catch(...) {
01509 cerr << "refractive_atmospheric_model::caliph_J error\n";
01510 throw(string("refractive_atmospheric_model::caliph_J"));
01511 }
01512 pixel_array<T> pixarr(axes,data);
01513 delete [] data;
01514 return(pixarr);
01515 }
01516
01517 template<class T>
01518 diffractive_wavefront_header<T>
01519 refractive_atmospheric_model::get_diffractive_wavefront_header(double wavelength,
01520 double pixscale,
01521 const emitter * emtr,
01522 const aperture * ap,
01523 bool layer_foreshortening,
01524 propagation_plan * pplan) const {
01525
01526
01527
01528 three_vector emitter_direction_vector = -1*emtr->get_emission_vector(*ap);
01529
01530 double cos_angle = dot_product(-1*emitter_direction_vector, ap->z());
01531 three_frame wf_frame(*ap-(layer_heights_[0]/cos_angle)*emitter_direction_vector,
01532 -1*ground_ref_frame_.x(),
01533 -1*ground_ref_frame_.y(),
01534 -1*ground_ref_frame_.z());
01535 if(layer_foreshortening) {
01536 three_vector axis_in_layer = cross_product(ground_ref_frame_.z(), emitter_direction_vector);
01537 if(axis_in_layer.length()>three_frame::precision){
01538 wf_frame = three_frame(*ap-(layer_heights_[0]/cos_angle)*emitter_direction_vector,
01539 cross_product(axis_in_layer, emitter_direction_vector),
01540 axis_in_layer,
01541 emitter_direction_vector);
01542 }
01543 } else {
01544 three_vector rotation_vector = cross_product(emitter_direction_vector,
01545 wf_frame.z());
01546 if(rotation_vector.length()!=0){
01547 three_rotation trot(wf_frame,
01548 rotation_vector,
01549 rotation_vector.length());
01550 trot.transform(wf_frame);
01551 }
01552 }
01553
01554
01555
01556
01557 rectangular_region wf_region = ap->get_covering_region(wf_frame);
01558 wf_region = rectangular_region(wf_region, pixscale);
01559
01560
01561
01562 vector<three_point> region_corners = wf_region.get_corners();
01563 long dimen = (long)ceil((region_corners[1]-region_corners[0]).length()/pixscale);
01564 if((region_corners[3]-region_corners[0]).length() >
01565 (region_corners[1]-region_corners[0]).length())
01566 dimen = (long)ceil((region_corners[3]-region_corners[0]).length()/pixscale);
01567
01568 vector<long> wf_axes(2, dimen);
01569
01570
01571 double curvature = 0;
01572 double init_pixscale = pixscale;
01573 const spherical_wave_emitter * swe;
01574 if(swe=dynamic_cast<const spherical_wave_emitter *>(emtr)){
01575 curvature = 1/(wf_frame-*swe).length();
01576 init_pixscale *= (wf_frame-*swe).length()/(*ap-*swe).length();
01577 }
01578
01579
01580 diffractive_wavefront_header<T> dwf(wf_axes, wf_frame, wavelength, init_pixscale);
01581
01582 dwf.set_curvature(curvature);
01583
01584
01585
01586 diffractive_wavefront_header<T> padded_dwf = pplan->pad(dwf, layer_heights_[0]);
01587
01588 return(padded_dwf);
01589 }
01590
01591 template<class T, class U>
01592 void refractive_atmospheric_model::
01593 get_refractive_atmospheric_layers(const vector<double> & layer_pixscales,
01594 const subharmonic_method & subm,
01595 const vector<diffractive_wavefront_header<T> > dwfhdrs,
01596 const vector<three_vector> layer_wind_vectors,
01597 double time_interval,
01598 bool layer_axes_wind_vector_aligned,
01599 bool layer_foreshortening,
01600 vector<refractive_atmospheric_layer<U> > & ref_atm_layers) const {
01601
01602 if(time_interval < 0){
01603 cerr << "refractive_atmospheric_model::get_refractive_atmospheric_layers error - "
01604 << "time interval " << time_interval << " provided to this function "
01605 << "is less than or equal to zero\n";
01606 throw(string("refractive_atmospheric_model::get_refractive_atmospheric_layers"));
01607 }
01608
01609 if(layer_pixscales.size() != power_spectra_.size()){
01610 cerr << "refractive_atmospheric_model::get_refractive_atmospheric_layers error - "
01611 << layer_pixscales.size() << " layer pixel scales were provided, but there are "
01612 << power_spectra_.size() << " layers in the model\n";
01613 throw(string("refractive_atmospheric_model::get_refractive_atmospheric_layers"));
01614 }
01615
01616 if(layer_wind_vectors.size()!=this->get_number_of_layers()){
01617 cerr << "refractive_atmospheric_model::get_refractive_atmospheric_layers error - "
01618 << "number of layer wind vectors " << layer_wind_vectors.size()
01619 << " does not match the number of layers " << this->get_number_of_layers()
01620 << " in the atmospheric model\n";
01621 throw(string("refractive_atmospheric_model::get_refractive_atmospheric_layers"));
01622 }
01623
01624
01625
01626
01627
01628 int nlayers = power_spectra_.size();
01629 vector<three_frame> layer_three_frames(nlayers, ground_ref_frame_);
01630 vector<rectangular_region> layer_rec_regions;
01631 double windspeed, x_wind_cmpnt, y_wind_cmpnt, angle;
01632 for(int i=0; i<nlayers; i++){
01633
01634 if(refractive_atmospheric_model::verbose_level)
01635 cout << "refractive_atmospheric_model::get_refractive_atmospheric_layers - initializing layer three frame...";
01636
01637
01638
01639 if(layer_axes_wind_vector_aligned){
01640 layer_three_frames[i] = three_frame(ground_ref_frame_,
01641 cross_product(layer_wind_vectors[i], ground_ref_frame_.z()),
01642 layer_wind_vectors[i],
01643 ground_ref_frame_.z());
01644 }
01645
01646
01647 layer_three_frames[i] += layer_heights_[i]*ground_ref_frame_.z();
01648
01649 if(refractive_atmospheric_model::verbose_level) cout << " initializing rectangular region...";
01650
01651
01652
01653
01654 diffractive_wavefront_header<T> tmp_header = dwfhdrs[0];
01655 if(refractive_atmospheric_model::verbose_level) cout << "getting distance...";
01656 tmp_header.three_point::operator=(get_ray_plane_intersection(tmp_header, tmp_header.z(),
01657 layer_three_frames[i], layer_three_frames[i].z()));
01658
01659 if(refractive_atmospheric_model::verbose_level) cout << "making rec region...";
01660 layer_rec_regions.push_back(tmp_header.get_covering_region(layer_three_frames[i], layer_foreshortening));
01661
01662 if(refractive_atmospheric_model::verbose_level) cout << "initialization complete\n";
01663 }
01664
01665
01666
01667
01668 vector<three_point> tp;
01669 ref_atm_layers.clear();
01670 vector<long> layer_axes(2);
01671 diffractive_wavefront_header<T> tmp_header;
01672 for(int i=0; i<nlayers; i++){
01673 if(refractive_atmospheric_model::verbose_level) cout << "Layer " << i << " constructing rectangular region...";
01674 for(int j=1; j<dwfhdrs.size(); j++){
01675
01676
01677 tmp_header = dwfhdrs[j];
01678 tmp_header.three_point::operator=(get_ray_plane_intersection(dwfhdrs[j], dwfhdrs[j].z(),
01679 layer_three_frames[i], layer_three_frames[i].z()));
01680
01681 layer_rec_regions[i] =
01682 region_union(layer_rec_regions[i],
01683 tmp_header.get_covering_region(layer_three_frames[i], layer_foreshortening));
01684 }
01685
01686 if(refractive_atmospheric_model::verbose_level) cout << " enlarging region for simulation...";
01687
01688
01689
01690 three_vector lateral_displacement = time_interval*layer_wind_vectors[i];
01691 tp = layer_rec_regions[i].get_corners();
01692 for(int j=0; j<4; j++) tp[j] -= lateral_displacement;
01693 layer_rec_regions[i] = region_union(layer_rec_regions[i], rectangular_region(tp));
01694
01695 if(refractive_atmospheric_model::verbose_level)
01696 layer_rec_regions[i].print(cout, "lrr ");
01697
01698 if(refractive_atmospheric_model::verbose_level) cout << " rounding up region...";
01699
01700
01701
01702 layer_rec_regions[i] = rectangular_region(layer_rec_regions[i], layer_pixscales[i]);
01703 layer_three_frames[i].three_point::operator=(layer_rec_regions[i].get_center());
01704
01705 if(refractive_atmospheric_model::verbose_level)
01706 layer_three_frames[i].print(cout, "layer three frame ");
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718 if(refractive_atmospheric_model::verbose_level) cout << " getting layer axes...";
01719 double padding_factor = 1.2;
01720 tp = layer_rec_regions[i].get_corners();
01721 three_vector tva = tp[1]-tp[0];
01722 three_vector tvb = tp[3]-tp[0];
01723 layer_axes[0] = (long)(padding_factor*(1+ceil(tvb.length()/layer_pixscales[i])));
01724 layer_axes[1] = (long)(padding_factor*(1+ceil(tva.length()/layer_pixscales[i])));
01725 if(layer_axes_wind_vector_aligned){
01726 if(cross_product(tva, layer_wind_vectors[i]).length()<three_frame::precision){
01727 layer_axes[0] = (long)(padding_factor*(1+ceil(tva.length()/layer_pixscales[i])));
01728 layer_axes[1] = (long)(padding_factor*(1+ceil(tvb.length()/layer_pixscales[i])));
01729 }
01730 } else {
01731 if(cross_product(tva, ground_ref_frame_.x()).length()<three_frame::precision){
01732 layer_axes[0] = (long)(padding_factor*(1+ceil(tva.length()/layer_pixscales[i])));
01733 layer_axes[1] = (long)(padding_factor*(1+ceil(tvb.length()/layer_pixscales[i])));
01734 }
01735 }
01736
01737
01738 if(refractive_atmospheric_model::verbose_level)
01739 cout << "making layer " << ref_atm_layers.size()
01740 << " of size " << layer_axes[0] << " x " << layer_axes[1]
01741 << " with pixscale " << layer_pixscales[i] << endl;
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753 ref_atm_layers.push_back(refractive_atmospheric_layer<U>(power_spectra_[i],
01754 subm,
01755 layer_axes,
01756 layer_pixscales[i]));
01757 ref_atm_layers[i].set_wind_vector(layer_wind_vectors[i]);
01758 ref_atm_layers[i].three_frame::operator=(layer_three_frames[i]);
01759 ref_atm_layers[i].set_foreshortening(false);
01760 }
01761 }
01762
01763
01764
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01780
01781
01782
01783
01786
01787
01790
01791
01794
01795
01798
01799
01802
01803
01804
01805
01806
01809
01810
01813
01814
01817
01818
01821
01822
01825
01826
01829
01830
01833
01834
01837
01838
01841
01842
01843
01844
01845
01846
01847
01848
01849 }
01850
01851 #endif