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 OPTIC_H
00032 #define OPTIC_H
00033
00034 #include "AO_sim_base.h"
00035 #include "fits_header_data.h"
00036 #include "three_frame.h"
00037
00038 namespace Arroyo {
00039
00040 using std::ostream;
00041 using std::vector;
00042 using std::string;
00043
00044 class iofits;
00045 class rectangular_region;
00046 class three_vector;
00047 class three_scaling;
00048 class wavefront_header;
00049 template<typename T> class diffractive_wavefront;
00050
00054
00055 class optic :
00056 virtual public AO_sim_base {
00057
00058 protected:
00059
00065 bool foreshortening;
00066
00067 public:
00068
00071 optic(){foreshortening = true;};
00072
00075 optic(const optic & op);
00076
00079 virtual ~optic(){};
00080
00083 optic & operator=(const optic & op);
00084
00089 bool get_foreshortening() const {return(foreshortening);};
00090
00095 void set_foreshortening(bool fshrtn) {foreshortening = fshrtn;};
00096
00099 virtual void read(const iofits & iof);
00100
00103 virtual void write(iofits & iof) const;
00104
00107 virtual void print(ostream & os, const char * prefix="") const;
00108
00125 virtual rectangular_region get_covering_region(const three_frame & tf) const = 0;
00126
00134 virtual three_point get_point_of_intersection(const three_point & tp,
00135 const three_vector & tv) const = 0;
00136
00139 static int verbose_level;
00140
00143 static optic * optic_factory(const char * filename);
00144
00147 static optic * optic_factory(const iofits & iof);
00148
00149 };
00150
00154
00155 class plane_optic :
00156 virtual public optic,
00157 public three_frame {
00158
00159 protected:
00160
00163 template<class T>
00164 void get_projected_wavefront_pixel_spacing(const diffractive_wavefront<T> & wf,
00165 three_vector & origin_offset,
00166 three_vector & dx,
00167 three_vector & dy) const;
00168
00169 public:
00170
00173 plane_optic(){};
00174
00177 plane_optic(const plane_optic & plane_op);
00178
00181 virtual ~plane_optic(){};
00182
00185 plane_optic & operator=(const plane_optic & plane_op);
00186
00189 virtual void read(const iofits & iof);
00190
00193 virtual void write(iofits & iof) const;
00194
00197 virtual void print(ostream & os, const char * prefix="") const;
00198
00206 virtual three_point get_point_of_intersection(const three_point & tp,
00207 const three_vector & tv) const;
00208
00211 static plane_optic * plane_optic_factory(const char * filename);
00212
00215 static plane_optic * plane_optic_factory(const iofits & iof);
00216
00217 };
00218
00219 template<class T>
00220 void plane_optic::get_projected_wavefront_pixel_spacing(const diffractive_wavefront<T> & wf,
00221 three_vector & origin_offset,
00222 three_vector & dx,
00223 three_vector & dy) const {
00224
00225
00226
00227 if(fabs(dot_product(wf.three_frame::z(), this->three_frame::z()))<three_frame::precision){
00228 cerr << "plane_optic::get_projected_wavefront_pixel_spacing error - "
00229 << "diffractive_wavefront orthogonal to circular plane_optic normal\n";
00230 throw(string("plane_optic::get_projected_wavefront_pixel_spacing"));
00231 }
00232
00233
00234
00235 origin_offset = static_cast<three_point>(wf) - static_cast<const three_point>(*this);
00236
00237 if(fabs(dot_product(origin_offset, this->three_frame::z()))>three_frame::precision){
00238 cerr << "plane_optic::get_projected_wavefront_pixel_spacing error - "
00239 << "diffractive_wavefront center not in transverse plane of circular plane_optic\n";
00240 throw(string("plane_optic::get_projected_wavefront_pixel_spacing"));
00241 }
00242
00243 double wf_pixel_scale = wf.get_pixel_scale();
00244 dx = wf.three_frame::x()*wf_pixel_scale;
00245 dy = wf.three_frame::y()*wf_pixel_scale;
00246
00247 try{
00248 dx = parallel_projection(dx, this->z(), wf.z());
00249 dy = parallel_projection(dy, this->z(), wf.z());
00250 } catch(...){
00251 cerr << "plane_optic::get_projected_wavefront_pixel_spacing error - "
00252 << "could not form parallel projection\n";
00253 throw(string("plane_optic::get_projected_wavefront_pixel_spacing"));
00254 }
00255
00256
00257
00258 if(!foreshortening){
00259 dx = (wf_pixel_scale/dx.length())*dx;
00260 dy = (wf_pixel_scale/dy.length())*dy;
00261 }
00262 }
00263
00264
00269
00270 class one_to_one_optic :
00271 virtual public optic {
00272
00273 protected:
00274
00286 template<class T>
00287 T * get_wavefront_data(diffractive_wavefront<T> & wf) const {
00288 return(wf.wfdata);
00289 };
00290
00298 template<class T>
00299 bool is_real_imag_storage(const diffractive_wavefront<T> & wf) const {
00300 return(wf.real_imag);
00301 };
00302
00310 template<class T>
00311 bool is_interleaved_storage(const diffractive_wavefront<T> & wf) const {
00312 return(wf.interleaved);
00313 };
00314
00318 template<class T>
00319 void wavefont_real_imag_conversion(diffractive_wavefront<T> & wf) const {
00320 wf.real_imag_conversion();
00321 };
00322
00326 template<class T>
00327 void wavefront_amp_phase_conversion(diffractive_wavefront<T> & wf) const {
00328 wf.amp_phase_conversion();
00329 };
00330
00337
00338
00339 public:
00340
00343 one_to_one_optic(){};
00344
00347 virtual ~one_to_one_optic(){};
00348
00352 virtual void transform(diffractive_wavefront<float> & wf) const = 0;
00353
00357 virtual void transform(diffractive_wavefront<double> & wf) const = 0;
00358
00362
00363
00364 };
00365
00370
00371 class one_to_many_optic :
00372 virtual public optic {
00373
00374 protected:
00375
00391 template<class T>
00392 const T * const get_wavefront_data(const diffractive_wavefront<T> & wf) const {
00393 return(wf.wfdata);
00394 };
00395
00403 template<class T>
00404 bool real_imag_storage(const diffractive_wavefront<T> & wf) const {
00405 return(wf.real_imag);
00406 };
00407
00415 template<class T>
00416 bool interleaved_storage(const diffractive_wavefront<T> & wf) const {
00417 return(wf.interleaved);
00418 };
00419
00420 public:
00421
00424 one_to_many_optic(){};
00425
00428 virtual ~one_to_many_optic(){};
00429
00434 virtual long number_of_outputs() const = 0;
00435
00443
00447 virtual vector<diffractive_wavefront<float> > transform(const diffractive_wavefront<float> & wf) const = 0;
00448
00452 virtual vector<diffractive_wavefront<double> > transform(const diffractive_wavefront<double> & wf) const = 0;
00453
00457
00458
00459 };
00460
00465
00466 }
00467
00468 #endif
00469