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 EMITTER_H
00032 #define EMITTER_H
00033
00034 #include <three_vector.h>
00035 #include "diffractive_wavefront.h"
00036 #include "AO_sim_base.h"
00037
00038 namespace Arroyo {
00039 class iofits;
00040 class three_point;
00041 }
00042
00043 namespace Arroyo {
00044
00045
00049
00050 class emitter :
00051 virtual public AO_sim_base {
00052
00053 public:
00054
00057 emitter(){};
00058
00061 virtual ~emitter(){};
00062
00065 virtual void read(const char * filename) = 0;
00066
00069 virtual void read(const Arroyo::iofits & iof) = 0;
00070
00073 virtual void write(const char * filename) const = 0;
00074
00077 virtual void write(Arroyo::iofits & iof) const = 0;
00078
00081 virtual void print(ostream & os, const char * prefix="") const = 0;
00082
00085 virtual diffractive_wavefront<float> emit(const diffractive_wavefront_header<float> & dwfh) const = 0;
00086
00089 virtual diffractive_wavefront<double> emit(const diffractive_wavefront_header<double> & dwfh) const = 0;
00090
00094 virtual three_vector get_emission_vector(const three_point & tp) const = 0;
00095
00098 static emitter * emitter_factory(const char * filename);
00099
00102 static emitter * emitter_factory(const iofits & iof);
00103
00106 static emitter * emitter_factory(const emitter * emtr);
00107
00108 };
00109
00113
00114 class plane_wave_emitter :
00115 public emitter,
00116 public Arroyo::three_vector {
00117
00118 private:
00119
00120 static const bool factory_registration;
00121
00124 string unique_name() const {return(string("plane wave emitter"));};
00125
00129 template<class T>
00130 diffractive_wavefront<T> private_emit(const diffractive_wavefront_header<T> & dwfh) const;
00131
00132 protected:
00133
00136 plane_wave_emitter(){};
00137
00138 public:
00139
00142 plane_wave_emitter(const three_vector & tv);
00143
00146 plane_wave_emitter(const char * filename);
00147
00150 plane_wave_emitter(const plane_wave_emitter & pwe);
00151
00154 plane_wave_emitter(const iofits & iof) {
00155 this->read(iof);
00156 };
00157
00160 ~plane_wave_emitter(){};
00161
00164 plane_wave_emitter & operator=(const plane_wave_emitter & pwe);
00165
00168 void read(const char * filename);
00169
00172 void read(const Arroyo::iofits & iof);
00173
00176 void write(const char * filename) const;
00177
00180 void write(Arroyo::iofits & iof) const;
00181
00184 void print(ostream & os, const char * prefix="") const;
00185
00188 diffractive_wavefront<float> emit(const diffractive_wavefront_header<float> & dwfh) const {
00189 return this->private_emit(dwfh);
00190 };
00191
00194 diffractive_wavefront<double> emit(const diffractive_wavefront_header<double> & dwfh) const {
00195 return this->private_emit(dwfh);
00196 };
00197
00201 three_vector get_emission_vector(const three_point & tp) const {
00202 return(*this);
00203 }
00204
00207 friend bool operator==(const plane_wave_emitter & pwe1, const plane_wave_emitter & pwe2);
00208
00209 };
00210
00211 bool operator!=(const plane_wave_emitter & pwe1, const plane_wave_emitter & pwe2);
00212
00216
00217 class spherical_wave_emitter :
00218 public emitter,
00219 public Arroyo::three_point {
00220
00221 private:
00222
00223 static const bool factory_registration;
00224
00225 Arroyo::three_vector emission_direction;
00226
00229 string unique_name() const {return(string("spherical wave emitter"));};
00230
00234 template<class T>
00235 diffractive_wavefront<T> private_emit(const diffractive_wavefront_header<T> & dwfh) const;
00236
00237 protected:
00238
00241 spherical_wave_emitter(){};
00242
00243 public:
00244
00247 spherical_wave_emitter(const three_point & tp);
00248
00251 spherical_wave_emitter(const char * filename);
00252
00255 spherical_wave_emitter(const spherical_wave_emitter & swe);
00256
00259 spherical_wave_emitter(const iofits & iof) {
00260 this->read(iof);
00261 };
00262
00265 ~spherical_wave_emitter(){};
00266
00269 spherical_wave_emitter & operator=(const spherical_wave_emitter & swe);
00270
00273 void read(const char * filename);
00274
00277 void read(const Arroyo::iofits & iof);
00278
00281 void write(const char * filename) const;
00282
00285 void write(Arroyo::iofits & iof) const;
00286
00289 void print(ostream & os, const char * prefix="") const;
00290
00294 three_vector get_emission_vector(const three_point & tp) const {
00295 if(operator==(tp, static_cast<const three_point>(*this))){
00296 std::cerr << "spherical_wave_emitter::get_emission_vector error - "
00297 << "cannot get an emission vector at the location of the "
00298 << "spherical wave emitter\n";
00299 throw(string("spherical_wave_emitter::get_emission_vector"));
00300 }
00301 three_vector tv = tp - *this;
00302 tv = tv*(1/tv.length());
00303 return(tv);
00304 };
00305
00308 diffractive_wavefront<float> emit(const diffractive_wavefront_header<float> & dwfh) const {
00309 return this->private_emit(dwfh);
00310 };
00311
00314 diffractive_wavefront<double> emit(const diffractive_wavefront_header<double> & dwfh) const {
00315 return this->private_emit(dwfh);
00316 };
00317
00320 friend bool operator==(const spherical_wave_emitter & swe1, const spherical_wave_emitter & swe2);
00321
00322 };
00323
00324 bool operator!=(const spherical_wave_emitter & swe1, const spherical_wave_emitter & swe2);
00325
00326 template<class T>
00327 diffractive_wavefront<T> plane_wave_emitter::private_emit(const diffractive_wavefront_header<T> & dwfh) const {
00328
00329
00330 if(cross_product(*this, dwfh.z()).length()>1e-6){
00331 cerr << "plane_wave_emitter::private_emit error - "
00332 << "three_frame of diffractive wavefront header misaligned with the emission direction of this emitter\n";
00333 this->three_vector::print(cerr, "emitter vector ");
00334 dwfh.z().print(cerr, "header vector ");
00335 cerr << "cross product " << cross_product(*this, dwfh.z()).length() << endl;
00336 throw(string("plane_wave_emitter::emit"));
00337 }
00338 diffractive_wavefront<T> dwf(dwfh);
00339
00340
00341 complex<T> c(1,0);
00342 dwf += c;
00343 return(dwf);
00344 }
00345
00346 template<class T>
00347 diffractive_wavefront<T> spherical_wave_emitter::private_emit(const diffractive_wavefront_header<T> & dwfh) const {
00348
00349 diffractive_wavefront<T> dwf(dwfh);
00350
00351
00352 if((*this - dwfh).length()<three_frame::precision){
00353 cerr << "spherical_wave_emitter::private_emit error -"
00354 << "cannot emit wavefront at the location of the spherical wave emitter since curvature would be infinite\n";
00355 throw(string("spherical_wave_emitter::private_emit"));
00356 }
00357 dwf.set_curvature(1/(*this - dwfh).length());
00358
00359
00360 complex<T> c(1,0);
00361 dwf += c;
00362 return(dwf);
00363 }
00364 }
00365
00366 #endif