The VisAO Camera
focusops.py
1 """
2  FocusOps
3 
4  The FocusOps python module contains several scripts related to the focus stage..
5 """
6 
7 import visao
8 import visaoutils
9 import numpy
10 import time
11 from Numeric import *
12 import os
13 import _idl
14 
15 def calibration(p = 0):
16  """
17  Script to calibrate the focus stage step-ratio. Requires manual input of a micrometer measurement, in mm.
18 
19  Moves to the front or back of the travel range, whichever is closer when invoked.
20  """
21  foc = vis.FocusCtrl()
22  foc.take_control()
23 
24  if p == 0:
25  d = foc.get_pos()
26  if d > 5500.:
27  poss = 11500. - array(range(9))*2500.
28  else:
29  poss = -9500. + array(range(9))*2500.
30  else:
31  poss = p
32 
33  cal_pos = list()
34  meas_pos = list()
35 
36  for i in range(len(poss)):
37  print "************************"
38  print "Moving to %f microns." % poss[i]
39 
40  resp = foc.pos(poss[i])
41 
42  if(resp != 1):
43  break
44 
45  resp = foc.wait_move()
46 
47  if(resp != 1):
48  break
49 
50  pos = foc.get_pos()
51 
52  print "At %f microns." % pos
53  meas = float(raw_input("Enter measurement (in mm): "))
54  print "%f %f" % (pos, meas)
55 
56 
57  cal_pos.append(pos)
58  meas_pos.append(meas)
59 
60 
61  x = array(cal_pos)
62  y = array(meas_pos)*1000.
63  A = numpy.vstack([x, ones(len(x))]).T
64 
65  m,b = numpy.linalg.lstsq(A,y)[0]
66 
67  yfit = m*x + b
68  resid = yfit-y
69  print "\n\nCalibration Complete\n\n"
70  print "y = %f + %fx" % (b, m)
71  print "\nStd dev of residuals: %f microns\n" % numpy.std(resid)
72  print "Data:\nPosition\tMeasured\tResidual"
73  for i in range(len(cal_pos)):
74  print "%f\t%f\t%f" %(cal_pos[i], meas_pos[i], resid[i])
75 
76  foc.giveup_control()
77 
78 
79 
80 def focus_old(start, end, stepsz, ims=5, settle_delay = 1.):
81  """
82  Peform a focus measurement.
83 
84  First take darks, saving 5*ims images with gimbal in dark position. The moves from position start to end, in steps of size stepsz. At each position, the script pauses for settle_delay to allow vibrations to dissipate, and then take ims images. Images are saved in a sub-directory with the start time (standard VisAO filename) in the name. The visao_focuscurve.pro idl procedure is called to analyze the data, and the preset is updated.
85 
86  start = the starting focus position (microns)
87  end = the ending focus position (microns)
88  stepsz = size of steps to take between focus positions (microns)
89  ims = number of images to save at each position
90  settle_delay = the time, in seconds, to pause after each move to settle vibrations
91  """
92  try:
93  foc = vis.FocusCtrl()
94  foc.take_control()
95 
96  ccd = vis.CCD47Ctrl()
97  ccd.take_control()
98 
99  gimb = vis.Gimbal()
100  gimb.take_control()
101 
102  _idl.ex(".reset")
103 
104  dist = abs( end - start)
105 
106  if abs(stepsz) < 5.:
107  print "Stepsize too small."
108  return
109 
110  if end < start:
111  if stepsz > 0:
112  stepsz = stepsz * -1.
113  else:
114  if stepsz < 0:
115  stepsz = stepsz * -1.
116 
117  if ims <= 0:
118  print "Number of images must be > 0."
119  return
120 
121 
122  sd = vis.get_visao_filename_now("focus_")
123 
124  print "Moving focus stage to %f microns." % start
125  resp = foc.pos(start)
126 
127  if(resp != 1):
128  print "Focus motor error. "
129  return
130 
131 
132 
133  print "************************"
134  print "Taking CCD 47 Darks"
135 
136  darksd = "%s/darks" % sd
137  ccd.subdir(darksd)
138 
139  gimbx = gimb.get_xpos()
140  gimby = gimb.get_ypos()
141 
142  print "Gimbal start position: %f %f" % (gimbx, gimby)
143 
144  gimb.dark()
145 
146  gimb.wait_move()
147 
148  print "Saving %i dark images" % (ims*5)
149 
150  resp = ccd.save(ims*5)
151  if(resp != 0):
152  print "CCD47 error. "
153  return
154 
155  resp = ccd.wait_save()
156  if(resp != 1):
157  print "CCD47 error. "
158  return
159 
160  print "Saving complete."
161 
162  print "Moving gimbal to %f %f" % (gimbx, gimby)
163 
164  resp = gimb.move_xabs(gimbx)
165  if(resp != 0):
166  print "Gimbal error. (moving x) "
167  return
168 
169  resp = gimb.move_yabs(gimby)
170  if(resp != 0):
171  print "Gimbal error. (moving y) "
172  return
173 
174  resp = gimb.wait_move()
175  if(resp != 0):
176  print "Gimbal error (wait_move()). "
177  return
178 
179  print "Gimbal move complete"
180 
181  resp = foc.wait_move()
182 
183  if(resp != 1):
184  print "Focus motor error. "
185  return
186 
187  pos = foc.get_pos()
188 
189  print "At %f microns.\n\nBeginning focus curve acquisition . . ." % pos
190 
191  nextpos = pos
192 
193  ccd.subdir(sd)
194 
195  while abs(nextpos - start) < (dist + .1*abs(stepsz)):
196  print "************************"
197  print "Moving to %f microns . . ." % nextpos
198 
199  resp = foc.pos(nextpos)
200 
201  if(resp != 1):
202  print "Focus motor error."
203  return
204 
205  resp = foc.wait_move()
206 
207  if(resp != 1):
208  print "Focus motor error."
209  return
210 
211  pos = foc.get_pos()
212 
213  print "Move complete. Settling for %f seconds . . ." % settle_delay
214 
215  t = time.mktime(time.localtime())
216  while(time.mktime(time.localtime()) - t < settle_delay):
217  time.sleep(settle_delay)
218 
219  print "Saving %i images at %f microns." % (ims, pos)
220 
221  resp = ccd.save(ims)
222  if(resp != 0):
223  print "CCD47 error. "
224  return
225 
226  resp = ccd.wait_save()
227  if(resp != 1):
228  print "CCD47 error. "
229  return
230 
231  print "Saving complete."
232 
233  nextpos = pos + stepsz
234 
235  ccd.subdir(".")
236  foc.giveup_control()
237  ccd.giveup_control()
238  gimb.giveup_control()
239 
240  print "\n\nFocus Curve acquistion complete.\n\n"
241  print "Analyzing . . .\n"
242 
243  idlcmd = "visao_focuscurve, /interact, subdir='" + os.getenv('VISAO_ROOT') + "/data/ccd47/" + sd + "/'"
244 
245  _idl.ex(idlcmd)
246  except:
247  print '******************\nSomething bad happened\n******************\n'
248  vis.visao_alert(1)
249  raise
250 
251 def focus(start, end, stepsz, ims=5, settle_delay = 1., ndarks=-1):
252  """
253  Peform a focus measurement.
254 
255  First take darks, saving 5*ims images with gimbal in dark position. The moves from position start to end, in steps of size stepsz. At each position, the script pauses for settle_delay to allow vibrations to dissipate, and then take ims images. Images are saved in a sub-directory with the start time (standard VisAO filename) in the name. The visao_focuscurve.pro idl procedure is called to analyze the data, and the preset is updated.
256 
257  start = the starting focus position (microns)
258  end = the ending focus position (microns)
259  stepsz = size of steps to take between focus positions (microns)
260  ims = number of images to save at each position
261  settle_delay = the time, in seconds, to pause after each move to settle vibrations
262  """
263  try:
264 
265  _idl.ex(".reset")
266 
267  if ndarks == -1:
268  ndarks = ims
269 
270  vis = visao.VisAO()
271 
272  vis.take_control()
273 
274  visao.visao_wait(.25)
275 
276  dist = abs( end - start)
277 
278  if abs(stepsz) < 5.:
279  print "Stepsize too small."
280  return
281 
282  if end < start:
283  if stepsz > 0:
284  stepsz = stepsz * -1.
285  else:
286  if stepsz < 0:
287  stepsz = stepsz * -1.
288 
289  if ims <= 0:
290  print "Number of images must be > 0."
291  return
292 
294  vis.ccd47.subdir(sd)
295 
296  print "Moving focus stage to %f microns." % start
297  resp = vis.focus.pos(start)
298 
299  if(resp != 1):
300  print "Focus motor error. "
301  return
302 
303  vis.take_darks(ndarks)
304 
305  resp = vis.focus.wait_move()
306 
307  if(resp != 1):
308  print "Focus motor error. "
309  return
310 
311  pos = vis.focus.get_pos()
312 
313  print "At %f microns.\n\nBeginning focus curve acquisition . . ." % pos
314 
315  nextpos = pos
316 
317  while abs(nextpos - start) < (dist + .1*abs(stepsz)):
318  print "************************"
319  print "Moving to %f microns . . ." % nextpos
320 
321  resp = vis.focus.pos(nextpos)
322 
323  if(resp != 1):
324  print "Focus motor error."
325  return
326 
327  resp = vis.focus.wait_move()
328 
329  if(resp != 1):
330  print "Focus motor error."
331  return
332 
333  pos = vis.focus.get_pos()
334 
335  print "Move complete. Settling for %f seconds . . ." % settle_delay
336 
337  visao.visao_wait(settle_delay)
338 
339 
340  print "Saving %i images at %f microns." % (ims, pos)
341 
342  vis.take_science(ims)
343 
344  print "Saving complete."
345 
346  nextpos = pos + stepsz
347 
348  vis.ccd47.subdir(".")
349 
350  vis.giveup_control()
351 
352  visao.visao_alert(1)
353  print "\n\nFocus Curve acquistion complete.\n\n"
354  print "Analyzing . . .\n"
355 
356  idlcmd = "visao_focuscurve, /interact, subdir='" + os.getenv('VISAO_ROOT') + "/data/ccd47/" + sd + "/'"
357 
358  _idl.ex(idlcmd)
359  except:
360  print '******************\nSomething bad happened\n******************\n'
361  visao.visao_alert(1)
362  raise
363 
364 def visao_focus(stepsz = 1000., ims = 5, settle_delay=1.):
365 
366  foc = vis.FocusCtrl()
367  foc.take_control()
368 
369 
370  d = foc.get_pos()
371 
372  if(fabs(d-9000) > fabs(d+9000)):
373  start = -9000
374  end = 9000
375  else:
376  start = 9000
377  end = -9000
378 
379  return focus(start, end, stepsz, ims, settle_delay)
380 
381 
382 def filter2_focus(filters=["SDSS r'", "SDSS i'", "SDSS z'", "950 Long Pass"], homefirst=0, stepsz=1000, ims=5, settle_delay = 1.):
383  """
384  Peform a focus measurement, in each of a sequence of filter wheel 2 positions.
385 
386  The filters are specified as a python list, i.e. ["SDSS r'", "SDSS i'", "SDSS z'"]
387 
388  If homefirst is true, the wheel is homed before beginning.
389 
390  In each filter, the focus script is executed.
391  """
392  fw2 = vis.FilterWheel2()
393 
394  fw2.take_control()
395 
396  if homefirst:
397  print "Homing FilterWheel2. . ."
398  resp = fw2.home()
399 
400  resp = fw2.wait_home()
401  time.sleep(5)
402  print "Homing complete."
403 
404  for i in range(len(filters)):
405 
406  print "Changing filter to %s . . ." % filters[i]
407  resp = fw2.set_filter(filters[i])
408 
409 
410  resp = fw2.wait_move()
411  time.sleep(2)
412  filt = fw2.get_filter()
413 
414  print "In filter %s . . ." % filt
415 
416  if filt!= filters[i]:
417  print "Filter not correct."
418  return
419 
420  visao_focus(stepsz, ims, settle_delay)
421 
422  fw2.giveup_control()
423 
def get_visao_filename_now(prefix)
Definition: visaoutils.py:33
def focus_old
Definition: focusops.py:80
def calibration
Definition: focusops.py:15
def filter2_focus
Definition: focusops.py:382
def focus
Definition: focusops.py:251