def goifpc(nexp=1): """ Take an exposure or a sequence of exposures with the focal plane camera. If the keywords sequence and trigtime are set, then takes a sequence. Parameters ---------- nexp : int Desired number of exposure. Examples -------- Take a single exposure with the blue camera >>> Blue.goifpc(1) """ numberOfExposures = nexp # start keyword monitoring server = 'kfcs' try: loutfile = ktl.cache(server,'LASTFILE') startex = ktl.cache(server,'STARTEX') stopex = ktl.cache(server,'STOPEX') ttime = ktl.cache(server,'EXPTIME') status = ktl.cache(server,'STATUS') trigtime = ktl.cache(server,'TRIGTIME') sequence = ktl.cache(server,'SEQUENCE') counter = ktl.cache(server,'COUNTER') closed = ktl.cache(server,'CLOSED') except: raise RuntimeError("Failed to read detector keywords. KFCS might not be running") monitoredKeywords = (loutfile, startex, stopex, ttime, status, trigtime, sequence, counter, closed) setupMonitoring(monitoredKeywords, wait=True) n = 0 errcnt = 0 # is FPC open (not closed)? if closed == 0: # main loop while n< numberOfExposures and errcnt < 2: # wait for current exposure to end status.waitFor('!=Busy') exposureTime = ttime imno = counter ctim = time.asctime() say ('%s: Taking %.3f s exposure %d of %d (image # %d)' % (ctim, exposureTime, n+1, numberOfExposures, imno)) # start a new exposure startex.write(1) say("Exposing") # what is the wait time? seq = sequence triggerTime = trigtime waitTime = (exposureTime+triggerTime)*seq if waitTime < 1: waitTime = 1 time.sleep(waitTime+1) status.waitFor('!=Busy') stat = status if stat == 'OK': say('Last file is: ' + loutfile['ascii']) say("Readout complete") n += 1 else: say("Error reading out, aborting!") stopex.write(1) errcnt += 1 say('Exposure sequence complete') else: say('Cannot take exposure, camera closed.')
def pwaveb(pwave=None, cwave=None, move=True, quiet=False): """ Show or set the peak wavelength Parameters ---------- cwave : float Desired central wavelength in Angstroms pwave : float Peak wavelength move : boolean Set to false to only modify the target without moving the stages quiet : boolean Set to true to disable progress bar Examples -------- set the peak wavelength to 6700 Angstrom >>> Blue.pwaveb(pwave=6700) """ server = 'kcwi' cwavetarg = ktl.cache(server,'BCWAVETARG') pwavetarg = ktl.cache(server,'BPWAVETARG') monitoredKeywords = (cwavetarg, pwavetarg) setupMonitoring(monitoredKeywords, wait=True) # retrieve the name of the current grating currentgrating = gratingb() if currentgrating == None or currentgrating == 'None': say("There is no grating in the beam") return # instantiate a grating object g = grating(currentgrating) if pwave is not None and is_in_filling_position() != False: say("KCWI might be in filling position, moves are not allowed") return if pwave is not None: pwavetarg.write(pwave) cwave = cwaveb() # calculate the required angles g.calc_from_wavelengths(cwave=cwave, pwave=pwave) # use multiprocesing to run camera and grating at the same time # camera angle camangleb(angvalue=g.camang, move=move, quiet=quiet) # grating angle grangleb(angvalue=g.grangle, move=move, quiet=quiet) # return values return pwave #, pwave #, g.camang, g.grangle else: # the function was called without a requested wavelength, # so we return the calculated wavelength based on angles camangle = float(camangleb()) grangle = float(grangleb()) g.calc_from_angles(camang=camangle, grangle=grangle) return g.pwave #, g.pwave, camangle, grangle
def goib(nexp, dark=False): """ Take an exposure or a sequence of exposures with the blue camera. Parameters ---------- nexp : int Desired number of exposure. dark : boolean If True, do not open shutter imtype : string twiflat will set the parameters for a sky flat Examples -------- Take a single exposure with the blue camera >>> Blue.goib(1) """ numberOfExposures = int(nexp) # start keyword monitoring server = 'kbds' try: exposeip = ktl.cache(server,'EXPOSIP') rdoutip = ktl.cache(server,'RDOUTIP') loutfile = ktl.cache(server,'LOUTFILE') startex = ktl.cache(server,'STARTEX') todisk = ktl.cache(server,'TODISK') ttime = ktl.cache(server,'TTIME') autoshut = ktl.cache(server,'AUTOSHUT') frameno = ktl.cache(server,'FRAMENO') imtype = ktl.cache(server,'IMTYPE') groupidk = ktl.cache(server,'GROUPID') except: raise RuntimeError("Failed to read detector keywords. KBDS might not be running") # get the date obs try: dateobsk = ktl.cache('dcs','DATE-OBS') dateobs = dateobsk.read() except: dateobs = 'UNKNOWN' monitoredKeywords = (exposeip, rdoutip, loutfile, startex, todisk, ttime, autoshut, frameno,imtype, groupidk) setupMonitoring(monitoredKeywords, wait=True) n = 0 td = int(todisk['ascii']) # create GROUPID keyword groupid = "%s-%d" % (dateobs,frameno) groupidk.write(groupid) if not td: say("WARNING: todisk keyword prevents saving images") if dark==True and float(ttime.read())>0: say("Disabling autoshutter: images will be dark") imtype.write('DARK') autoshut.write(0) if float(ttime.read()) == 0: say("Exposure time is zero: images will be biases") imtype.write('BIAS') while n < numberOfExposures: # wait for current exposure to end startex.waitFor('==0') exposeip.waitFor('==0') rdoutip.waitFor('==0') loutstart=loutfile['ascii'] cond = "!='"+loutfile['ascii']+"'" ctim = time.asctime() exposureTime = ttime imno = frameno say ('%s: Taking %.3f s exposure %d of %d (image # %d)' % (ctim, exposureTime, int(n+1), int(numberOfExposures), imno)) # start a new exposure startex.write(1) # wait for exposure to start exposeip.waitFor('==1',timeout=20) say("Exposing") # what is the exposure time? exposureTime=float(ttime['ascii']) # wait for readout rdoutip.waitFor('==1',timeout=exposureTime+10) say("Reading out") # wait for readout rdoutip.waitFor('==0',timeout=450) say("Readout complete") # only test if writing to disk if td: # wait for last file to change loutfile.waitFor(cond, timeout=120) say('Last file is: '+loutfile['ascii']) n=n+1 say('Exposure sequence complete') if dark==True: autoshut.write(1)
def nsmaskb(target=None, move=True, quiet=True): """ Reads or modify the position of the nod and shuffle mask Parameters ---------- target : string Desired position. Valid values are: "Open", "Test", "Mask" move : boolean Set to false to only modify the target without moving the N&S mask quiet : boolean Set to disable progress bar Examples -------- Prints the position of the nod and shuffle mask >>> Blue.nsmasbk() Set the nod and shuffle mask to Mask >>> Blue.nsmaskb(target="Mask") """ server = 'kbms' nasname = ktl.cache(server, 'NASNAME') # current nastargn = ktl.cache(server, 'NASTARGN') # target nasmove = ktl.cache(server, 'NASMOVE') # initiate the move nasstatus = ktl.cache(server, 'NASSTATUS') # values? monitoredKeywords = (nasname, nastargn,nasmove,nasstatus) # set wait = False if you can accept undefined keywords (for simulation, for example) setupMonitoring(monitoredKeywords, wait=True) # if called with an empty string, return the current slicer if target==None: nas = nasname.ascii lg.info("kcwiServer: Returning nod and shuffle value '%s'" % (nas)) return nas # if the requested target is the same as the current, do not move if target==nasname.ascii and move==True: say("N&S: Target is the same as requested. No move needed.") return # check if move is possible checkIfMoveIsPossible(nasstatus) # initiate the move nastargn.write(target) # if move is True, then force a move if move==True: nasmove.write(1) if not quiet: p = AnimatedProgressBar(end=100, width=standardWidth) ktl.monitor(server,'NASPROG',ProgressCallback,p) # fmove expressions moving = '$kbms.nasmove == 1' not_moving = '$kbms.nasmove == 0' target_reached = '$kbms.nasname == $kbms.nastargn' moving = ktl.Expression(moving) not_moving = ktl.Expression(not_moving) target_reached = ktl.Expression(target_reached) # wait for moving result = moving.wait(timeout = timeOutMove) if result == False: raise RuntimeError("Mechanism %s did not start moving within %d seconds" % ("N&S Mask", timeOutMove)) # wait for not moving not_moving.wait(timeout=240) # check for successful move time.sleep(5) checkSuccess(statusKeyword=nasstatus, mechanism="N&S Mask", targetReachedExpression=target_reached, successStatus="OK")
def cwaveb(cwave=None, pwave=None, move=True, quiet=False): """ Show or set the central (and optionally the peak) wavelength Parameters ---------- cwave : float Desired central wavelength in Angstroms pwave : float Peak wavelength (if desired and different from cwave) move : boolean Set to false to only modify the target without moving the stages quiet : boolean Set to true to disable progress bar Examples -------- set the central wavelength to 6700 Angstrom >>> Blue.cwaveb(cwave=6700) """ server = 'kcwi' cwavetarg = ktl.cache(server,'BCWAVETARG') pwavetarg = ktl.cache(server,'BPWAVETARG') monitoredKeywords = (cwavetarg, pwavetarg) setupMonitoring(monitoredKeywords, wait=True) # retrieve the name of the current grating currentgrating = gratingb() if currentgrating == None or currentgrating == 'None': say("There is no grating in the beam") return # instantiate a grating object g = grating(currentgrating) if cwave is not None and is_in_filling_position() != False: say("KCWI might be in filling position, moves are not allowed") return if cwave is not None: # update target cwavetarg.write(cwave) if pwave is not None: pwavetarg.write(pwave) else: pwavetarg.write(cwave) # calculate the required angles g.calc_from_wavelengths(cwave=cwave, pwave=pwave) # camera angle p1 = threading.Thread(target = camangleb, args = (g.camang, True, quiet)) # grating angle p2 = threading.Thread(target = grangleb, args = (g.grangle, True, quiet)) p1.start() say("Camera motion started") p2.start() say("Grating motion started") p1.join() p2.join() # return values return cwave #, pwave #, g.camang, g.grangle else: # the function was called without a requested wavelength, # so we return the calculated wavelength based on angles camangle = float(camangleb()) grangle = float(grangleb()) g.calc_from_angles(camang=camangle, grangle=grangle) return g.cwave #, g.pwave, camangle, grangle
def grangleb(angvalue=None, move=True, quiet=False): """ Reads or set the blue channel grating angle Parameters ---------- angvalue : float Desired grating angle in degrees move : boolean Set to false to only modify the target without moving the grangle quiet : boolean Set to disable progress bar Examples -------- Prints the name of the current camangle >>> Blue.grangleb() Go to 10 degrees >>> Blue.grangleb(angvalue=10) """ timeOutComplete = 180. # extra time for grating angle server = 'kbes' grtargp = ktl.cache(server,'GRTARGP') # target position (0,1 or 2) grangle = ktl.cache(server,'GRANGLE') # current angle grtrgang = ktl.cache(server,'GRTRGANG') # target angle grstatus = ktl.cache(server,'GRSTATUS') gstatus = ktl.cache(server,'GSTATUS') grmove = ktl.cache(server,'GRMOVE') monitoredKeywords = (grtargp, grangle, grtrgang, grstatus,gstatus, grmove) # set wait = False if you can accept undefined keywords (for simulation, for example) setupMonitoring(monitoredKeywords, wait=True) # if called with an empty string, return the current filter, otherwise set the filter if angvalue==None: result = grangle.ascii lg.info("kcwiServer: Returning grating angle '%s'" % (result)) return result # if the requested target is the same as the current, do not move if abs(float(angvalue)-grangle) < 0.01: say("Grating angle: Target equals current, no move needed.") return grangle.ascii # check if move is possible checkIfMoveIsPossible(gstatus) checkIfMoveIsPossible(grstatus) # set the target. This is done both for move=True and move=False grtrgang.write(angvalue) # stop here if we are not asking for a move if move == False: return # check that we are in angle mode # if we are not in angle mode, changing the angle mode initiates a move # if we are in angle mode, we need to issue a move command if grtargp != 2: sys.stdout.write("Setting grating rotator to angle mode\n") grtargp.write(2) grmove.write(1) # move expressions moving = '$kbes.grstatus == "Moving"' not_moving = '$kbes.grstatus == "Move complete"' target_reached = '$kbes.grposerr < $kbes.grtolopt' moving = ktl.Expression(moving) not_moving = ktl.Expression(not_moving) target_reached = ktl.Expression(target_reached) # wait for moving result = moving.wait(timeout = timeOutMove) if not quiet: p = AnimatedProgressBar(end=100, width=standardWidth) ktl.monitor(server,'GRPROG',ProgressCallback,p) if result == False: raise RuntimeError("Mechanism %s did not start moving within %d seconds" % ("Grating rotator", timeOutMove)) # wait for not moving not_moving.wait(timeout=timeOutComplete) # check for successful move time.sleep(2) checkSuccess(statusKeyword=grstatus, mechanism="Grating rotator", targetReachedExpression=target_reached, successStatus="Move") #if abs(artposerr) > arttol: # say("Warning: The required encoder position has NOT been reached") # return value result = grangle.ascii return result
def camangleb(angvalue=None, move=True, quiet=False): """ Reads or set the blue channel articulation stage angle Parameters ---------- angvalue : float Desired camera angle in degrees move : boolean Set to false to only modify the target without moving the camangle quiet : boolean Set to disable progress bar Examples -------- Prints the name of the current camangle >>> Blue.camangleb() Go to 10 degrees >>> Blue.camangleb(angvalue=10) Modify the camangle target keyword but do not move >>> Blue.camangleb(angvalue=10, move=False) """ timeOutComplete = 180. # extra time for cam angle server = 'kbms' #gname = ktl.cache(server,'GNAME') # current grating arttarg = ktl.cache(server,'ARTTARG') # target encoder arttargang = ktl.cache(server,'ARTTARGANG') # target angle artmove = ktl.cache(server,'ARTMOVE') # initiate the move artstatus = ktl.cache(server,'ARTSTATUS') artenc = ktl.cache(server,'ARTENC') artang = ktl.cache(server,'ARTANG') artposerr = ktl.cache(server,'ARTPOSERR') arttol = ktl.cache(server,'ARTTOL') monitoredKeywords = (arttarg,arttargang,artmove,artstatus,artenc,artang,artposerr,arttol) # set wait = False if you can accept undefined keywords (for simulation, for example) setupMonitoring(monitoredKeywords, wait=True) # if called with an empty string, return the current filter, otherwise set the filter if angvalue==None: result = artang.ascii lg.info("kcwiServer: Returning camera angle '%s'" % (result)) return result # if the requested target is the same as the current, do not move if abs(float(angvalue)-artang) < 0.001 and move==True: say("Articulation stage: Target equals current, no move needed.") return artang.ascii # check if move is possible checkIfMoveIsPossible(artstatus) # check if we are in filling position if is_in_filling_position() != False: say("KCWI might be in filling position, moves are not allowed") return -1 # set the target. This is done both for move=True and move=False arttargang.write(angvalue) # if move is True, then force a move if move==True: artmove.write(1) # move expressions moving = '$kbms.artmove == 1' not_moving = '$kbms.artmove == 0' target_reached = '$kbms.artang == $kbms.arttargang' moving = ktl.Expression(moving) not_moving = ktl.Expression(not_moving) target_reached = ktl.Expression(target_reached) # wait for moving result = moving.wait(timeout = timeOutMove) if not quiet: p = AnimatedProgressBar(end=100, width=standardWidth) ktl.monitor(server,'ARTPROG',ProgressCallback,p) if result == False: raise RuntimeError("Mechanism %s did not start moving within %d seconds" % ("Articulation stage", timeOutMove)) # wait for not moving not_moving.wait(timeout=timeOutComplete) # check for successful move time.sleep(5) checkSuccess(statusKeyword=artstatus, mechanism="Articulation stage", targetReachedExpression=None, successStatus="OK") if abs(artposerr) > arttol: say("Warning: The required angle has NOT been reached") # return value result = artang.ascii lg.info("kcwiServer: Returning articulation stage angle '%s'" % (result)) return result
def gratingb(target=None, move=True): """ Reads or set the blue channel grating Parameters ---------- target : string Desired grating. Values are: TBD move : boolean Set to false to only modify the target without moving the grating Examples -------- Prints the name of the current grating >>> Blue.gratingb() Insert the L grating >>> Blue.gratingb(target="L") Modify the grating target keyword but do not move >>> Blue.gratingb(target="H2", move=False) """ timeOutComplete = 360. # extra time for grating exchange server = 'kbes' gname = ktl.cache(server,'GNAME') # current grating gtargn = ktl.cache(server,'GTARGN') # target grating gmove = ktl.cache(server,'GMOVE') # initiate the move gstatus = ktl.cache(server,'GSTATUS') movemode = ktl.cache(server,'MOVEMODE') monitoredKeywords = (gname, gtargn, gstatus, gmove, movemode) # set wait = False if you can accept undefined keywords (for simulation, for example) setupMonitoring(monitoredKeywords, wait=True) # if called with an empty string, return the current filter, otherwise set the filter if target==None: grating = gname.ascii lg.info("kcwiServer: Returning grating value '%s'" % (grating)) return grating # if the requested target is the same as the current, do not move if target==gname.ascii and move==True: say("Grating: Target equals current, no move needed.") return gname.ascii # check if move is possible checkIfMoveIsPossible(gstatus) # reset move mode to 0 currentMoveMode = movemode.ascii changeMoveMode(movemode=movemode,mode=0) # set the target. This is done both for move=True and move=False gtargn.write(target) # if move is True, then force a move if move==True: gmove.write(1) # fmove expressions moving = '$kbes.gmove == 1' not_moving = '$kbes.gmove == 0' target_reached = '$kbes.gname == $kbes.gtargn' moving = ktl.Expression(moving) not_moving = ktl.Expression(not_moving) target_reached = ktl.Expression(target_reached) # wait for moving result = moving.wait(timeout = timeOutMove) if result == False: raise RuntimeError("Mechanism %s did not start moving within %d seconds" % ("Grating", timeOutMove)) # wait for not moving not_moving.wait(timeout=timeOutComplete) # check for successful move time.sleep(2) checkSuccess(statusKeyword=gstatus, mechanism="Grating", targetReachedExpression=target_reached, successStatus="Success:") # return value grating = gname.ascii lg.info("kcwiServer: Returning grating value '%s'" %grating) return grating # reset move mode if currentMoveMode == 1: changeMoveMode(movemode=movemode, mode=1)
def filterb(target=None, move=True): """ Reads or set the blue channel filter Parameters ---------- target : string Desired filter. Values are: TBD move : boolean Set to false to only modify the target without moving the filter Examples -------- Prints the name of the current filter >>> Blue.filterb() Insert the B1 filter >>> Blue.filterb(target="B1") Modify the filter target keyword but do not move >>> Blue.filterb(target="B1", move=False) """ timeOutComplete = 180. # extra time for filter exchange server = 'kbes' fname = ktl.cache(server, 'FNAME') # current filter ftargn = ktl.cache(server, 'FTARGN') # target filter fmove = ktl.cache(server, 'FMOVE') # initiate the move fstatus = ktl.cache(server, 'FSTATUS') # values: OK, MOVING, ERROR, INIT_ERROR movemode = ktl.cache(server, 'MOVEMODE') monitoredKeywords = (fname, ftargn, fstatus, fmove, movemode) # set wait = False if you can accept undefined keywords (for simulation, for example) setupMonitoring(monitoredKeywords, wait=True) # if called with an empty string, return the current filter, otherwise set the filter if target==None: filter = fname.ascii lg.info("kcwiServer: Returning filter value '%s'" %filter) return filter # if the requested target is the same as the current, do not move if target==fname.ascii and move==True: say("Filter: Target equals current, no move needed.") return fname.ascii # check if move is possible checkIfMoveIsPossible(fstatus) # reset move mode to 0 currentMoveMode = movemode.ascii changeMoveMode(movemode=movemode,mode=0) # initiate the move ftargn.write(target) # if move is True, then force a move if move==True: fmove.write(1) # fmove expressions moving = '$kbes.fmove == 1' not_moving = '$kbes.fmove == 0' target_reached = '$kbes.fname == $kbes.ftargn' moving = ktl.Expression(moving) not_moving = ktl.Expression(not_moving) target_reached = ktl.Expression(target_reached) # wait for moving result = moving.wait(timeout = timeOutMove) if result == False: raise RuntimeError("Mechanism %s did not start moving within %d seconds" % ("Filter", timeOutMove)) # wait for not moving not_moving.wait(timeout=timeOutComplete) # check for successful move time.sleep(2) checkSuccess(statusKeyword=fstatus, mechanism="Filter", targetReachedExpression=target_reached, successStatus="Success:") # return value filter = fname.ascii lg.info("kcwiServer: Returning filter value '%s'" %filter) return filter # reset move mode if currentMoveMode == 1: changeMoveMode(movemode=movemode, mode=1)
def focusb(target=None, move=True, quiet=False): """ Reads or set the blue camera focus Parameters ---------- target : float Desired focus value in mm. move : boolean Set to False to just set target quiet : boolean Set to disable progress bar Examples -------- Print the current focus value >>> Blue.focusb Set the current focus value to 1.5mm >>> Blue.focusb(target=1.5) """ server = 'kbms' foctargmm = ktl.cache(server,'FOCTARGMM') # target encoder focmove = ktl.cache(server,'FOCMOVE') # initiate the move focstatus = ktl.cache(server,'FOCSTATUS') focmm = ktl.cache(server,'FOCMM') focposerr = ktl.cache(server,'FOCPOSERR') focmmerr = ktl.cache(server,'FOCMMERR') foctol = ktl.cache(server,'FOCTOL') focenc = ktl.cache(server,'FOCENC') foctarg = ktl.cache(server,'FOCTARG') monitoredKeywords = (foctargmm,focmove,focstatus,focmm,focposerr,focmmerr,foctol,focenc,foctarg) # set wait = False if you can accept undefined keywords (for simulation, for example) setupMonitoring(monitoredKeywords, wait=True) # if called with an empty string, return the current value if target==None: result = focmm.ascii lg.info("kcwiServer: Returning focus value '%s'" % (result)) return result # set the target. This is done both for move=True and move=False foctargmm.write(target,wait=True) time.sleep(2) # if the requested target is the same as the current, do not move #print(float(focenc.ascii)) #print(abs(float(focenc.ascii)-float(foctarg.ascii))) #print(float(foctarg.ascii)) #time.sleep(2) if abs(float(focenc.ascii)-float(foctarg.ascii)) < float(foctol.ascii) and move==True: say("Focus: Target equals current, no move needed.") return focmm.ascii # check if move is possible checkIfMoveIsPossible(focstatus) # if move is True, then force a move if move==True: focmove.write(1) # move expressions moving = '$kbms.focmove == 1' not_moving = '$kbms.focmove == 0' moving = ktl.Expression(moving) not_moving = ktl.Expression(not_moving) # wait for moving result = moving.wait(timeout = timeOutMove) if not quiet: p = AnimatedProgressBar(end=100, width=standardWidth) ktl.monitor(server,'FOCPROG',ProgressCallback,p) if result == False: raise RuntimeError("Mechanism %s did not start moving within %d seconds" % ("Blue camera focus", timeOutMove)) # wait for not moving not_moving.wait(timeout=timeOutComplete) # check for successful move time.sleep(4) checkSuccess(statusKeyword=focstatus, mechanism="Blue Camera focus", targetReachedExpression=None, successStatus="OK") if abs(focposerr) > foctol: say("Warning: The required focus has NOT been reached") # return value result = focmm.ascii lg.info("kcwiServer: Returning blue camera focus '%s'" % (result)) return result