def DetectorThunk(conn,dir='C:/PAPA Control/',datacount=1000): """An infinite loop for controlling the detector Keyword arguments: conn -- a connection stream for communicating with the main process dir -- the directory in which to save data datacount -- the number of data points to attempts to read at a time The function loops through, either sleeping or recording data. It polls its communication stream and expects a two element tuple. The first element is an event code and the second is a tuple with the arguments for the event. """ det = Detector() #detector object running = False paused = False runnumber = -1 stream = None count = 0 while True: if (not running) and (not conn.poll()): sleep(0.01) continue if conn.poll(): cmd,args=conn.recv() if cmd==QUIT: break elif cmd==START: if runnumber<=0: logging.error("Error: Invalid Run #") continue if not running: stream = open(dir+("%04d"%runnumber)+'.pel','wb') stream.write(det.makeHeader()) det.start() running = True count=0 elif cmd==STOP: if running: det.stop() det.clear() running = False stream.close() stream=None continue elif cmd==PAUSE: logging.info("Pausing Detector") det.stop()#Do NOT clear running = False paused = True elif cmd==RESUME: if paused: logging.info("Resuming") det.start() running = True else: logging.warning("Cannot resume: detector not paused") elif cmd==RUNNUMBER: runnumber = args[0] conn.send("Run # set to %d"%runnumber) elif cmd==DIRECTORY: dir = args[0] elif cmd == N_COUNT: conn.send(count/2)#Correction Needed for 64 Bit Mode elif cmd==PARAM: opt,val=args det.setParam(opt,val) elif cmd == QUERY: conn.send(det.status[args[0]]) #print det.status[args[0]] else: logging.warning("Did not recognize command %d"%cmd) if running: if stream is None: continue try: #Get the number of data points and the data #note that num is the number of 32 bit data #points given by the detector, which may or #may not be the actual number of neutrons, #depending on if the detector is in 32 or #64 bit mode (num,data)=det.read(datacount) except RuntimeError,(err): logging.error(err) break count += num #Pull only the actual data from the buffer if num < datacount: data=data[:num] stream.write(data.tostring()) if num < datacount: stream.flush() sleep(0.01)