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

optic.h

Go to the documentation of this file.
00001 /*
00002 Arroyo - software for the simulation of electromagnetic wave propagation
00003 through turbulence and optics.
00004 
00005 Copyright (c) 2000-2004 California Institute of Technology.  Written by
00006 Dr. Matthew Britton.  For comments or questions about this software,
00007 please contact the author at mbritton@astro.caltech.edu.
00008 
00009 This program is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as  published by the
00011 Free Software Foundation; either version 2 of the License, or (at your
00012 option) any later version.
00013 
00014 This program is provided "as is" and distributed in the hope that it
00015 will be useful, but WITHOUT ANY WARRANTY; without even the implied
00016 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  In no
00017 event shall California Institute of Technology be liable to any party
00018 for direct, indirect, special, incidental or consequential damages,
00019 including lost profits, arising out of the use of this software and its
00020 documentation, even if the California Institute of Technology has been
00021 advised of the possibility of such damage.   The California Institute of
00022 Technology has no obligation to provide maintenance, support, updates,
00023 enhancements or modifications.  See the GNU General Public License for
00024 more details.
00025 
00026 You should have received a copy of the GNU General Public License along
00027 with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00029 */
00030 
00031 #ifndef 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     // First, ensure that wavefront normal is not orthogonal to the
00226     // plane_optic normal
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     // Next, ensure that the wavefront origin lies in the transverse
00234     // frame of the optic.
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     // If there's no foreshortening, we explicitly set the length to be
00257     // equal to the wf pixel scale
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     // geometric_ray * get_wavefront_data(const geometric_wavefront & gwf) const;
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     //virtual void transform(geometric_wavefront & gwf) const = 0;
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     //virtual vector<geometric_wavefront> transform(const geometric_wavefront & gwf) const = 0;
00458 
00459   };
00460 
00465 
00466 }
00467 
00468 #endif
00469 

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