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 SHACK_HARTMANN_CENTROIDS_H
00032 #define SHACK_HARTMANN_CENTROIDS_H
00033
00034 #include <iostream>
00035 #include <vector>
00036 #include "AO_sim_base.h"
00037 #include "diffractive_wavefront.h"
00038
00039 namespace Arroyo {
00040
00041
00045
00046 class Shack_Hartmann_centroids :
00047 public AO_sim_base,
00048 public pixel_array<double> {
00049
00050 private:
00051
00052 static const bool factory_registration;
00053
00056 string unique_name() const {return(string("Shack Hartmann centroids"));};
00057
00058 public:
00059
00062 Shack_Hartmann_centroids(){};
00063
00066 ~Shack_Hartmann_centroids(){};
00067
00070 Shack_Hartmann_centroids(const Shack_Hartmann_centroids & shcentroids){
00071 this->operator=(shcentroids);
00072 };
00073
00076 Shack_Hartmann_centroids(const char * filename){
00077 this->read(filename);
00078 };
00079
00082 Shack_Hartmann_centroids(const iofits & iof){
00083 this->read(iof);
00084 };
00085
00088 Shack_Hartmann_centroids(const vector<long> & lenslet_axes);
00089
00092 template<class T>
00093 Shack_Hartmann_centroids(const vector<long> & lenslet_axes, const diffractive_wavefront<T> & dwf);
00094
00098
00099
00102 Shack_Hartmann_centroids & operator=(const Shack_Hartmann_centroids & iznke);
00103
00106 void read(const char * filename);
00107
00110 void read(const Arroyo::iofits & iof);
00111
00114 void write(const char * filename) const;
00115
00118 void write(Arroyo::iofits & iof) const;
00119
00122 void print(std::ostream & os, const char * prefix = "") const;
00123
00124 static int verbose_level;
00125
00126 };
00127
00128 template<class T>
00129 Shack_Hartmann_centroids::Shack_Hartmann_centroids(const vector<long> & lenslet_axes,
00130 const diffractive_wavefront<T> & dwf){
00131
00132
00133 if(lenslet_axes.size()!=2 || lenslet_axes[0]<=0 || lenslet_axes[1]<=0){
00134 cerr << "Shack_Hartmann_centroids::Shack_Hartmann_centroids error - "
00135 << "invalid lenslet dimensions\n";
00136 throw(string("Shack_Hartmann_centroids::Shack_Hartmann_centroids"));
00137 }
00138
00139 vector<long> wf_axes = dwf.get_axes();
00140 if(lenslet_axes[0]*(wf_axes[0]/lenslet_axes[0])!=wf_axes[0] ||
00141 lenslet_axes[1]*(wf_axes[1]/lenslet_axes[1])!=wf_axes[1]){
00142 cerr << "Shack_Hartmann_centroids::Shack_Hartmann_centroids error - "
00143 << "wavefront axes not evenly divisible by lenslet axes\n";
00144 cerr << "wavefront dimensions " << wf_axes[0] << "x" << wf_axes[1] << endl;
00145 cerr << "lenslet dimensions " << lenslet_axes[0] << "x" << lenslet_axes[1] << endl;
00146 throw(string("Shack_Hartmann_centroids::Shack_Hartmann_centroids"));
00147 }
00148
00149 vector<long> pixarr_axes(lenslet_axes);
00150 pixarr_axes[1]*=2;
00151
00152 this->set_axes(pixarr_axes);
00153
00154 long xpix_per_lenslet = wf_axes[1]/lenslet_axes[1];
00155 long ypix_per_lenslet = wf_axes[0]/lenslet_axes[0];
00156
00157
00158 double x_halfpix=0, y_halfpix=0;
00159 int x_extrapix=1, y_extrapix=1;
00160 if(xpix_per_lenslet%2==0){
00161 x_halfpix = .5;
00162 x_extrapix = 0;
00163 }
00164 if(ypix_per_lenslet%2==0){
00165 y_halfpix = .5;
00166 y_extrapix = 0;
00167 }
00168
00169 long nlenslets = lenslet_axes[0]*lenslet_axes[1];
00170 double xcentroid, ycentroid, total, intensity;
00171 for(int i=0; i<lenslet_axes[1]; i++){
00172 for(int j=0; j<lenslet_axes[0]; j++){
00173 xcentroid = ycentroid = total = 0;
00174 for(int k=0; k<xpix_per_lenslet; k++){
00175 for(int l=0; l<ypix_per_lenslet; l++){
00176 intensity = norm(dwf.data((i*xpix_per_lenslet+k)*wf_axes[0]+j*ypix_per_lenslet+l));
00177 total+=intensity;
00178 xcentroid += intensity*(k-xpix_per_lenslet/2+x_halfpix);
00179 ycentroid += intensity*(l-ypix_per_lenslet/2+y_halfpix);
00180 }
00181 }
00182 total==0 ? pixeldata[i*lenslet_axes[0]+j] = 0 :
00183 pixeldata[i*lenslet_axes[0]+j] = xcentroid/total;
00184 total==0 ? pixeldata[i*lenslet_axes[0]+j+nlenslets] = 0 :
00185 pixeldata[i*lenslet_axes[0]+j+nlenslets] = ycentroid/total;
00186 if(Shack_Hartmann_centroids::verbose_level)
00187 cout << i << "\t" << j
00188 << "\t" << pixeldata[i*lenslet_axes[0]+j]
00189 << "\t" << pixeldata[i*lenslet_axes[0]+j+nlenslets]
00190 << endl;
00191
00192 }
00193 }
00194 }
00195 }
00196
00197 #endif