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 DEFORMABLE_MIRROR_H
00032 #define DEFORMABLE_MIRROR_H
00033
00034 #include <iostream>
00035 #include <string>
00036 #include <iomanip>
00037 #include <complex>
00038 #include <region_base.h>
00039 #include <three_transformation.h>
00040 #include "aperture.h"
00041 #include "diffractive_wavefront.h"
00042
00043 namespace Arroyo
00044 {
00045 using std::string;
00046 using std::vector;
00047 using std::ostream;
00048
00052
00053 class deformable_mirror_base :
00054 virtual public plane_optic,
00055 virtual public one_to_one_optic {
00056
00057 public:
00058
00061 deformable_mirror_base(){};
00062
00065 virtual ~deformable_mirror_base(){};
00066
00068
00069
00071
00074 virtual void read(const char* filename) = 0;
00075
00078 virtual void read(const iofits& iof) = 0;
00079
00082 virtual void write(const char* filename) const = 0;
00083
00086 virtual void write(iofits& iof) const = 0;
00087
00090 virtual void print(ostream& os, const char* prefix="") const = 0;
00091
00094 static deformable_mirror_base* deformable_mirror_base_factory(const char* filename);
00095
00098 static deformable_mirror_base* deformable_mirror_base_factory(const iofits& iof);
00099 };
00100
00143
00144 template<class aperture_type>
00145 class ideal_deformable_mirror :
00146 public deformable_mirror_base,
00147 public aperture_type {
00148
00149 private:
00150
00151 static const bool factory_registration;
00152 string unique_name() const
00153 {
00154 return(string("ideal deformable mirror"));
00155 };
00156
00157 protected:
00158
00160 double mirror_actuator_pitch;
00161
00166 double mirror_timestamp;
00167
00169 double mirror_actuator_velocity;
00170
00176 pixel_array<double> mirror_actuator_commands;
00177
00180 pixel_array<double> mirror_actuator_positions;
00181
00188 template<class T>
00189 void private_transform(diffractive_wavefront<T>& wf) const;
00190
00193 ideal_deformable_mirror();
00194
00195 public:
00196
00199 ideal_deformable_mirror(const ideal_deformable_mirror& ideal_dm);
00200
00203 ideal_deformable_mirror(const aperture& ap,
00204 const vector<long> & nact,
00205 const double pitch,
00206 const double vel,
00207 const double ts=0);
00208
00211 ideal_deformable_mirror(const char *filename);
00212
00215 ideal_deformable_mirror(const iofits &iof);
00216
00219 virtual ~ideal_deformable_mirror(){};
00220
00223 ideal_deformable_mirror& operator=(const ideal_deformable_mirror& ideal_dm);
00224
00227 virtual void read(const char* filename);
00228
00231 virtual void read(const iofits& iof);
00232
00235 void write(const char* filename) const;
00236
00239 void write(iofits& iof) const;
00240
00243 void print(ostream& os, const char* prefix="") const;
00244
00249 vector<long> get_axes(void) const
00250 {
00251 return mirror_actuator_commands.get_axes();
00252 }
00253
00258 double get_actuator_pitch(void) const
00259 {
00260 return mirror_actuator_pitch;
00261 }
00262
00267 void set_actuator_pitch(double act_pitch);
00268
00273 double get_actuator_velocity(void) const
00274 {
00275 return mirror_actuator_velocity;
00276 }
00277
00282 void set_actuator_velocity(double act_velocity);
00283
00286 pixel_array<double> get_actuator_commands() const {
00287 return(mirror_actuator_commands);
00288 }
00289
00296 pixel_array<double> get_actuator_positions(double timestamp) const;
00297
00301 void update(const pixel_array<double>& pixarr, double timestamp);
00302
00305 void transform(diffractive_wavefront<float> & wf) const;
00306
00309 void transform(diffractive_wavefront<double> & wf) const;
00310
00315 double get_timestamp() const {return(mirror_timestamp);};
00316
00317 };
00318
00319 template<class aperture_type>
00320 ideal_deformable_mirror<aperture_type>::
00321 ideal_deformable_mirror()
00322 {
00323 mirror_actuator_pitch = 0.;
00324 mirror_actuator_velocity = 0.;
00325 mirror_timestamp = 0.;
00326 }
00327
00328 template<class aperture_type>
00329 ideal_deformable_mirror<aperture_type>::
00330 ideal_deformable_mirror(const ideal_deformable_mirror<aperture_type> &ideal_dm)
00331 {
00332 this->operator=(ideal_dm);
00333 }
00334
00335 template<class aperture_type>
00336 ideal_deformable_mirror<aperture_type>::
00337 ideal_deformable_mirror(const char *filename)
00338 {
00339 this->read(filename);
00340 }
00341
00342 template<class aperture_type>
00343 ideal_deformable_mirror<aperture_type>::
00344 ideal_deformable_mirror(const iofits &iof)
00345 {
00346 this->read(iof);
00347 }
00348
00349 template<class aperture_type>
00350 ideal_deformable_mirror<aperture_type>::
00351 ideal_deformable_mirror(const aperture& ap,
00352 const vector<long> & actuator_dimensions,
00353 const double actuator_pitch,
00354 const double actuator_velocity,
00355 const double actuator_timestamp)
00356 {
00357 const aperture_type* aptype;
00358 try{aptype = dynamic_cast<const aperture_type*>(&ap);}
00359 catch(...) {
00360 cerr << "ideal_deformable_mirror::ideal_deformable_mirror error -\n"
00361 << "clash between instantiated type of "
00362 << "mirror and aperture " << endl;
00363 cerr << "provided to constructor" << endl;
00364 ap.print(cerr,"ap provided to constructor");
00365 throw(this->unique_name() + string("::ideal_deformable_mirror constructor"));
00366 }
00367 this->aperture_type::operator=(*aptype);
00368
00369
00370 if(actuator_dimensions.size()!=2){
00371 cerr << "ideal_deformable_mirror::ideal_deformable_mirror error -\n"
00372 << " cannot instantiate deformable mirror with "
00373 << actuator_dimensions.size() << " actuator dimensions\n";
00374 throw(string("ideal_deformable_mirror::ideal_deformable_mirror"));
00375 }
00376 if(actuator_dimensions[0]<=0 || actuator_dimensions[1]<=0){
00377 cerr << "ideal_deformable_mirror::ideal_deformable_mirror error -\n"
00378 << " cannot instantiate deformable mirror with actuator dimensions "
00379 << actuator_dimensions[0] << "x" << actuator_dimensions[1] << endl;
00380 throw(string("ideal_deformable_mirror::ideal_deformable_mirror"));
00381 }
00382
00383 mirror_actuator_pitch = actuator_pitch;
00384 mirror_actuator_velocity = actuator_velocity;
00385 mirror_timestamp = actuator_timestamp;
00386
00387 mirror_actuator_positions = pixel_array<double>(actuator_dimensions);
00388 mirror_actuator_commands = pixel_array<double>(actuator_dimensions);
00389 }
00390
00391 template<class aperture_type>
00392 ideal_deformable_mirror<aperture_type> &
00393 ideal_deformable_mirror<aperture_type>::
00394 operator=(const ideal_deformable_mirror<aperture_type>& ideal_dm)
00395 {
00396 if(this == &ideal_dm) return(*this);
00397 this->aperture_type::operator=(*this);
00398 mirror_actuator_pitch = ideal_dm.mirror_actuator_pitch;
00399 mirror_actuator_velocity = ideal_dm.mirror_actuator_velocity;
00400 mirror_timestamp = ideal_dm.mirror_timestamp;
00401 mirror_actuator_positions = ideal_dm.mirror_actuator_positions;
00402 mirror_actuator_commands = ideal_dm.mirror_actuator_commands;
00403 return(*this);
00404 }
00405
00406 template<class aperture_type>
00407 void ideal_deformable_mirror<aperture_type>::
00408 read(const char* filename)
00409 {
00410 iofits iof;
00411 try
00412 {
00413 iof.open(filename);
00414 }
00415 catch(...)
00416 {
00417 cerr << this->unique_name() << "::read - error opening file "
00418 << filename << endl;
00419 throw(this->unique_name() + string("::read"));
00420 }
00421
00422 try
00423 {
00424 this->read(iof);
00425 }
00426 catch(...)
00427 {
00428 cerr << this->unique_name() << "::read - error reading "
00429 << this->unique_name() << " from file " << filename << endl;
00430 throw(this->unique_name() + string("::read"));
00431 }
00432 }
00433
00434 template<class aperture_type>
00435 void ideal_deformable_mirror<aperture_type>::
00436 read(const iofits& iof)
00437 {
00438 string type, comment;
00439 if (!iof.key_exists("TYPE"))
00440 {
00441 cerr << this->unique_name() << "::read error - unrecognized "
00442 << "file type" << endl;
00443 throw(this->unique_name() + string("::read"));
00444 }
00445 iof.read_key("TYPE",type,comment);
00446 if (type != "ideal_deformable_mirror")
00447 {
00448 cerr << this->unique_name() << "::read error - file of type: "
00449 << type << " rather than type " << this->unique_name() << endl;
00450 throw(this->unique_name() + string("::read"));
00451 }
00452
00453 iof.read_key("ACTPITCH",mirror_actuator_pitch,comment);
00454 iof.read_key("ACT_VEL",mirror_actuator_velocity,comment);
00455 iof.read_key("TIMESTMP",mirror_timestamp,comment);
00456
00457 mirror_actuator_positions.read(iof);
00458
00459
00460
00461 mirror_actuator_commands.read(iof);
00462
00463
00464
00465
00466 this->aperture_type::read(iof);
00467
00468
00469 if(iof.get_hdu_num()!=iof.get_num_hdus()) iof.movrel_hdu(1);
00470 }
00471
00472 template<class aperture_type>
00473 void ideal_deformable_mirror<aperture_type>::
00474 write(const char* filename) const
00475 {
00476 iofits iof;
00477 try
00478 {
00479 iof.create(filename);
00480 }
00481 catch(...)
00482 {
00483 cerr << this->unique_name() << "::write - error creating file "
00484 << filename << endl;
00485 throw(this->unique_name() + string("::write"));
00486 }
00487
00488 try
00489 {
00490 this->write(iof);
00491 }
00492 catch(...)
00493 {
00494 cerr << this->unique_name() << "::write - error writing "
00495 << this->unique_name() << " to file " << filename << endl;
00496 throw(this->unique_name() + string("::write"));
00497 }
00498 }
00499
00500 template<class aperture_type>
00501 void ideal_deformable_mirror<aperture_type>::
00502 write(iofits & iof) const
00503 {
00504 string type, comment;
00505 vector<long> axes = mirror_actuator_positions.get_axes();
00506
00507 fits_header_data<double> tmphdr(axes);
00508 tmphdr.write(iof);
00509
00510 type = "ideal_deformable_mirror";
00511 comment = "object type";
00512 iof.write_key("TYPE", type, comment);
00513 comment = "actuator pitch (meters)";
00514 iof.write_key("ACTPITCH",mirror_actuator_pitch,comment);
00515 comment = "actuator velocity (meters/secs)";
00516 iof.write_key("ACT_VEL",mirror_actuator_velocity,comment);
00517 comment = "timestamp (secs)";
00518 iof.write_key("TIMESTMP",mirror_timestamp,comment);
00519
00520 mirror_actuator_positions.write(iof);
00521
00522
00523 tmphdr.write(iof);
00524 mirror_actuator_commands.write(iof);
00525
00526
00527 this->aperture_type::write(iof);
00528
00529 }
00530
00531 template<class aperture_type>
00532 void ideal_deformable_mirror<aperture_type>::
00533 print(ostream & os, const char * prefix) const
00534 {
00535 int vlspc = 30;
00536 vector<long> axes = mirror_actuator_positions.get_axes();
00537
00538 os.setf(std::ios::left, std::ios::adjustfield);
00539 os << prefix << "TYPE = " << setw(vlspc)
00540 << this->unique_name() << "/" << "object type" << endl;
00541 fits_header_data<double> tmphdr(axes);
00542 tmphdr.print(os, prefix);
00543 os << prefix << "ACTPITCH = " << setw(vlspc) << mirror_actuator_pitch
00544 << " actuator pitch (meters)" << endl;
00545 os << prefix << "ACT_VEL = " << setw(vlspc) << mirror_actuator_velocity
00546 << " actuator velocity (meters/secs)" << endl;
00547 os << prefix << "TIMESTMP = " << setw(vlspc)
00548 << mirror_timestamp
00549 << " actuators time_stamp (secs)" << endl;
00550 this->aperture_type::print(os, prefix);
00551 }
00552
00553 template<class aperture_type>
00554 void ideal_deformable_mirror<aperture_type>::
00555 set_actuator_pitch(double actuator_pitch)
00556 {
00557 if(actuator_pitch<0){
00558 cerr << "ideal_deformable_mirror::set_actuator_pitch error - "
00559 << " cannot set actuator pitch to value " << actuator_pitch << endl;
00560 throw(string("ideal_deformable_mirror::set_actuator_pitch"));
00561 }
00562 mirror_actuator_pitch = actuator_pitch;
00563 }
00564
00565 template<class aperture_type>
00566 void ideal_deformable_mirror<aperture_type>::
00567 set_actuator_velocity(double actuator_velocity)
00568 {
00569 if(actuator_velocity<0){
00570 cerr << "ideal_deformable_mirror::set_actuator_velocity error - "
00571 << " cannot set actuator velocity to value " << actuator_velocity << endl;
00572 throw(string("ideal_deformable_mirror::set_actuator_velocity"));
00573 }
00574 mirror_actuator_velocity = actuator_velocity;
00575 }
00576
00577 template<class aperture_type>
00578 pixel_array<double> ideal_deformable_mirror<aperture_type>::
00579 get_actuator_positions(double timestamp) const
00580 {
00581 if (timestamp < this->mirror_timestamp)
00582 {
00583 cerr << this->unique_name() << "::get_actuator_positions error - timestamp: "
00584 << timestamp << " predates the internal ideal_deformable_mirror timestamp "
00585 << mirror_timestamp << endl;
00586 throw(this->unique_name() + string("::get_actuator_positions"));
00587 }
00588
00589 vector<long> axes = mirror_actuator_positions.get_axes();
00590 pixel_array<double> new_actuator_positions(axes);
00591
00592 double displacement_magnitude = mirror_actuator_velocity*(timestamp-mirror_timestamp);
00593 double last_actuator_position, actuator_command_position, new_actuator_position;
00594 int nelem = mirror_actuator_positions.total_space();
00595 for (int i=0; i<nelem; i++)
00596 {
00597 last_actuator_position = mirror_actuator_positions.data(i);
00598 actuator_command_position = mirror_actuator_commands.data(i);
00599 if(last_actuator_position<actuator_command_position)
00600 new_actuator_position =
00601 last_actuator_position+displacement_magnitude<actuator_command_position ?
00602 last_actuator_position+displacement_magnitude : actuator_command_position;
00603 else
00604 new_actuator_position =
00605 last_actuator_position-displacement_magnitude>actuator_command_position ?
00606 last_actuator_position-displacement_magnitude : actuator_command_position;
00607
00608 new_actuator_positions.set_data(i,new_actuator_position);
00609 }
00610 return(new_actuator_positions);
00611 }
00612
00613 template<class aperture_type>
00614 void ideal_deformable_mirror<aperture_type>::
00615 update(const pixel_array<double>& act_cmds, double timestamp)
00616 {
00617 mirror_actuator_positions = this->get_actuator_positions(timestamp);
00618 mirror_actuator_commands = act_cmds;
00619 mirror_timestamp = timestamp;
00620 }
00621
00622 template<class aperture_type>
00623 void ideal_deformable_mirror<aperture_type>::
00624 transform(diffractive_wavefront<float> & wf) const
00625 {
00626 try
00627 {
00628 this->private_transform(wf);
00629 }
00630 catch(...)
00631 {
00632 cerr << this->unique_name() << "::transform error - "
00633 << "error transforming a float instantiation " << endl;
00634 cerr << "of diffractive_wavefront" << endl;
00635 throw(this->unique_name() + string("::transform"));
00636 }
00637 }
00638
00639 template<class aperture_type>
00640 void ideal_deformable_mirror<aperture_type>::
00641 transform(diffractive_wavefront<double> & wf) const
00642 {
00643 try
00644 {
00645 this->private_transform(wf);
00646 }
00647 catch(...)
00648 {
00649 cerr << this->unique_name() << "::transform error - "
00650 << "error transforming a double instantiation " << endl;
00651 cerr << "of diffractive_wavefront" << endl;
00652 throw(this->unique_name() + string("::transform"));
00653 }
00654 }
00655
00656
00657 template<class aperture_type>
00658 template<class T> void
00659 ideal_deformable_mirror<aperture_type>::
00660 private_transform(diffractive_wavefront<T> & wf) const {
00661 three_vector origin_offset, dx, dy;
00662
00663
00664
00665
00666 if (cross_product(this->z(),wf.z()).length() >
00667 three_frame::precision && foreshortening) {
00668 cerr << this->unique_name() << "::private_transform error - "
00669 << "The wavefront is not normally " << endl;
00670 cerr << "incident onto the deformable_mirror. Aborting..." << endl;
00671 wf.z().print(cerr, "wf z ");
00672 this->z().print(cerr, "tt z ");
00673 throw(this->unique_name()+string("::private_transform"));
00674 }
00675
00676 if (dot_product(wf.z(),this->z()) >= 0.) {
00677 cerr << this->unique_name() << "::private_transform error - "
00678 << "The wavefront provided to this function is " << endl;
00679 cerr << "travelling in the wrong direction, i.e., is "
00680 << "not incident on the reflective side of "
00681 << "the mirror." << endl;
00682 wf.z().print(cerr, "wf z ");
00683 this->z().print(cerr, "tt z ");
00684 throw(this->unique_name()+string("::private_transform"));
00685 }
00686
00687 if (wf.get_timestamp() < mirror_timestamp) {
00688 cerr << this->unique_name() << "::private_transform error - "
00689 << "deformable_mirror last timestamp postdates wavefront " << endl;
00690 cerr << "timestamp: " << wf.get_timestamp() << " provided "
00691 << "to this function." << endl;
00692 throw(string(this->unique_name()+"::private_transform"));
00693 }
00694
00695 if (wf.get_pixel_scale() > mirror_actuator_pitch) {
00696 cerr << this->unique_name() << "::private_transform error - "
00697 << "actuator pitch: " << mirror_actuator_pitch
00698 << " is larger than " << endl;
00699 cerr << "the wavefront pixel scale: " << wf.get_pixel_scale()
00700 << endl;
00701 throw(this->unique_name()+string("::private_transform"));
00702 }
00703
00704 try{get_projected_wavefront_pixel_spacing(wf, origin_offset, dx, dy);}
00705 catch(...){
00706 cerr << this->unique_name()
00707 << "::get_projected_wavefront_pixel_spacing error - "
00708 << endl;
00709 cerr << "could not get a projected pixel scale" << endl;
00710 throw(this->unique_name()+string("::private_transform"));
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720 this->aperture_type::transform(wf);
00721
00722
00723
00724
00725
00726
00727 pixel_array<double> current_actuator_positions(this->get_actuator_positions(wf.get_timestamp()));
00728
00729
00730 vector<long> wf_axes = wf.get_axes();
00731 vector<long> dm_axes = mirror_actuator_positions.get_axes();
00732
00733 int wf_X_min = -wf_axes[1]/2;
00734 int wf_X_max = wf_axes[1]/2 + wf_axes[1]%2;
00735 int wf_Y_min = -wf_axes[0]/2;
00736 int wf_Y_max = wf_axes[0]/2 + wf_axes[0]%2;
00737 double wf_X_hpix = ((wf_axes[1]%2==0) ? 0.5 : 0.);
00738 double wf_Y_hpix = ((wf_axes[0]%2==0) ? 0.5 : 0.);
00739
00740 wavefront_amp_phase_conversion(wf);
00741 T *wfdata = get_wavefront_data(wf);
00742
00743 three_point center_pixel;
00744 double act_X_hpix = ((dm_axes[1]%2==0) ? 0.5 : 0.);
00745 int act_X_extrapix = ((dm_axes[1]%2==0) ? 0 : 1);
00746 double act_Y_hpix = ((dm_axes[0]%2==0) ? 0.5 : 0.);
00747 int act_Y_extrapix = ((dm_axes[0]%2==0) ? 0 : 1);
00748
00749 int iact, jact;
00750 int stride = is_interleaved_storage(wf) ? 2 : 1;
00751 int wf_amp_index = -stride;
00752 int wf_phase_index = is_interleaved_storage(wf) ? 1-stride : wf_axes[0]*wf_axes[1]-stride;
00753 double a, b, x, y;
00754 vector<int> actuator_index(4);
00755 vector<double> actuator_weight(4);
00756 double kvector = 2*M_PI/wf.get_wavelength();
00757
00758 for(int i=wf_X_min; i<wf_X_max; i++){
00759 for(int j=wf_Y_min; j<wf_Y_max; j++){
00760
00761 wf_amp_index += stride;
00762 wf_phase_index += stride;
00763
00764
00765 if(wfdata[wf_amp_index]==0) continue;
00766
00767 center_pixel = *this+(origin_offset + +(i+wf_X_hpix)*dx + (j+wf_Y_hpix)*dy);
00768
00769
00770 x = center_pixel.x(*this)/mirror_actuator_pitch;
00771 y = center_pixel.y(*this)/mirror_actuator_pitch;
00772
00773
00774
00775
00776
00777 if(fabs(x)>dm_axes[1]/2+act_X_extrapix+act_X_hpix ||
00778 fabs(y)>dm_axes[0]/2+act_Y_extrapix+act_Y_hpix){
00779 continue;
00780 }
00781
00782
00783
00784
00785
00786 if(fabs(x)<dm_axes[1]/2-act_X_hpix &&
00787 fabs(y)<dm_axes[0]/2-act_Y_hpix){
00788
00789 iact = (int)(x+dm_axes[1]/2-act_X_hpix);
00790 jact = (int)(y+dm_axes[0]/2-act_Y_hpix);
00791
00792 a = fabs(x+dm_axes[1]/2-act_X_hpix-iact);
00793 b = fabs(y+dm_axes[0]/2-act_Y_hpix-jact);
00794
00795 actuator_weight[0] = (1-a)*(1-b);
00796 actuator_weight[1] = a*(1-b);
00797 actuator_weight[2] = (1-a)*b;
00798 actuator_weight[3] = a*b;
00799 actuator_index[0] = jact*dm_axes[0]+iact;
00800 actuator_index[1] = actuator_index[0]+1;
00801 actuator_index[2] = (jact+1)*dm_axes[0]+iact;
00802 actuator_index[3] = actuator_index[2]+1;
00803
00804 try{
00805 for(int k=0; k<4; k++){
00806 wfdata[wf_phase_index] -=
00807 2*kvector*current_actuator_positions.data(actuator_index[k])*actuator_weight[k];
00808 }
00809 } catch(...) {
00810 cerr << "ideal_deformable_mirror::private_transform error - first error\n";
00811 for(int k=0; k<4; k++)
00812 cerr << "actuator " << k
00813 << "\tindex " << actuator_index[k]
00814 << "\tactuator position axes " << current_actuator_positions.get_axes()[0]
00815 << "x" << current_actuator_positions.get_axes()[1]
00816 << endl;
00817 throw(string("ideal_deformable_mirror::private_transform"));
00818 }
00819 } else {
00820
00821
00822
00823
00824
00825
00826
00827
00828 try{
00829 if(x<-dm_axes[1]/2+act_X_hpix && y<-dm_axes[0]/2+act_Y_hpix){
00830 wfdata[wf_phase_index] -=
00831 2*kvector*current_actuator_positions.data(0)*
00832 (1+dm_axes[1]/2-act_X_hpix+x)*(1+dm_axes[0]/2-act_Y_hpix+y);
00833 } else if(x<-dm_axes[1]/2+act_X_hpix && y>dm_axes[0]/2-act_Y_hpix){
00834 wfdata[wf_phase_index] -=
00835 2*kvector*current_actuator_positions.data(dm_axes[1]*(dm_axes[0]-1))*
00836 (1+dm_axes[1]/2-act_X_hpix+x)*(1+dm_axes[0]/2-act_Y_hpix-y);
00837 } else if(x>dm_axes[1]/2-act_X_hpix && y<-dm_axes[0]/2+act_Y_hpix){
00838 wfdata[wf_phase_index] -=
00839 2*kvector*current_actuator_positions.data(dm_axes[0]-1)*
00840 (1+dm_axes[1]/2-act_X_hpix-x)*(1+dm_axes[0]/2-act_Y_hpix+y);
00841 } else if(x>dm_axes[1]/2-act_X_hpix && y>dm_axes[0]/2-act_Y_hpix){
00842 wfdata[wf_phase_index] -=
00843 2*kvector*current_actuator_positions.data(dm_axes[0]*dm_axes[1]-1)*
00844 (1+dm_axes[1]/2-act_X_hpix-x)*(1+dm_axes[0]/2-act_Y_hpix-y);
00845 }
00846
00847
00848 else {
00849 if(x<-dm_axes[0]/2+act_X_hpix){
00850 jact = (int)(y+dm_axes[0]/2-act_Y_hpix);
00851 a = -dm_axes[1]/2+act_X_hpix-x;
00852 b = fabs(y+dm_axes[0]/2-act_Y_hpix-jact);
00853 actuator_weight[0] = (1-a)*(1-b);
00854 actuator_weight[1] = (1-a)*b;
00855 actuator_index[0] = jact*dm_axes[0];
00856 actuator_index[1] = (jact+1)*dm_axes[0];
00857 } else if(x>dm_axes[1]/2-act_X_hpix){
00858 jact = (int)(y+dm_axes[0]/2-act_Y_hpix);
00859 a = -dm_axes[1]/2+act_X_hpix+x;
00860 b = fabs(y+dm_axes[0]/2-act_Y_hpix-jact);
00861 actuator_weight[0] = (1-a)*(1-b);
00862 actuator_weight[1] = (1-a)*b;
00863 actuator_index[0] = (jact+1)*dm_axes[0]-1;
00864 actuator_index[1] = (jact+2)*dm_axes[0]-1;
00865 } else if(y<-dm_axes[0]/2+act_Y_hpix){
00866 iact = (int)(x+dm_axes[1]/2-act_X_hpix);
00867 a = fabs(x+dm_axes[1]/2-act_X_hpix-iact);
00868 b = -dm_axes[0]/2+act_Y_hpix-y;
00869 actuator_weight[0] = (1-a)*(1-b);
00870 actuator_weight[1] = a*(1-b);
00871 actuator_index[0] = iact;
00872 actuator_index[1] = iact+1;
00873 } else if(y>dm_axes[0]/2-act_Y_hpix){
00874 iact = (int)(x+dm_axes[1]/2-act_X_hpix);
00875 a = fabs(x+dm_axes[1]/2-act_X_hpix-iact);
00876 b = -dm_axes[0]/2+act_Y_hpix+y;
00877 actuator_weight[0] = (1-a)*(1-b);
00878 actuator_weight[1] = a*(1-b);
00879 actuator_index[0] = (dm_axes[1]-1)*dm_axes[0]+iact;
00880 actuator_index[1] = (dm_axes[1]-1)*dm_axes[0]+iact+1;
00881 }
00882
00883 for(int k=0; k<2; k++)
00884 wfdata[wf_phase_index] -=
00885 2*kvector*current_actuator_positions.data(actuator_index[k])*actuator_weight[k];
00886 }
00887 } catch(...) {
00888 cerr << "ideal_deformable_mirror::private_transform error - third error\n";
00889 throw(string("ideal_deformable_mirror::private_transform"));
00890 }
00891 }
00892 }
00893 }
00894
00895 three_reflection tref(wf, this->z());
00896 tref.transform(wf);
00897 }
00898 }
00899 #endif