#!/usr/bin/env python import sys import math import time import signal from BCALModule import SubDetector us = None # Global variable. Will be used by main() and interupt_handler(). ds = None # Global variable. Will be used by main() and interupt_handler(). def main(): start = time.time() global us,ds wait_time = 0.05 # retry delay (s) sides, quadrants, single,freq, width, npulses, temp, offset, led_bias = option_handler(sys.argv) print signal.signal(signal.SIGINT,interrupt_handler) print "Initializing..." # Setting default parameters temp: 18 C, offset: 1.2 V, led_width: 200 ns, led_frequancy: 100 Hz, led_npulses: 100, led_bias = 6 V, led_lv = 5 V us = SubDetector('U',sim=False) ds = SubDetector('D',sim=False) sdDict = {'U':us,'D':ds} print "Setting configuration ......" us.configure(led_bias=led_bias,led_frequency=freq,led_width=width,led_npulses=npulses,temp=temp,offset=offset) ds.configure(led_bias=led_bias,led_frequency=freq,led_width=width,led_npulses=npulses,temp=temp,offset=offset) print "Turning on LV for LED ......" us.turn_led_lv_on() # Turn on +5V on LED, -5V # MPPC and LED ds.turn_led_lv_on() # Turn on +5V on LED, -5V # MPPC and LED print "Turning on LV for MPPC ......" us.turn_mppc_lv_on() # Turn on +5V, -5V (MPPC) ds.turn_mppc_lv_on() # Turn on +5V, -5V (MPPC) print "Turning on BIAS for LED ......" us.turn_led_bias_on()# Turn on bias (LED) ds.turn_led_bias_on()# Turn on bias (LED) print "Turning LED pulser OFF ......" us.turn_led_pulser_off() # Turn off LED pulser ds.turn_led_pulser_off() # Turn off LED pulser #print "Turning off BIAS for MPPC ......" #us.turn_mppc_bias_off()# Turn off all bias (MPPC) #ds.turn_mppc_bias_off()# Turn off all bias (MPPC) for s in sides: # Select Upstream or Downstream. sub_detector = sdDict[s] if not single: while not us.is_led_lv_on() and not us.is_led_bias_on() and not us.is_mppc_lv_on(): # Wait until MPPC and LED low voltage, and LED bias are on time.sleep(wait_time) while not ds.is_led_lv_on() and not ds.is_led_bias_on() and not ds.is_mppc_lv_on(): # Wait until MPPC and LED low voltage, and LED bias are on time.sleep(wait_time) else: while not sub_detector.is_led_lv_on() and not sub_detector.is_led_bias_on() and not sub_detector.is_mppc_lv_on(): # Wait until MPPC and LED low voltage, and LED bias are on time.sleep(wait_time) while not sub_detector.is_led_lv_on() and not sub_detector.is_led_bias_on() and not sub_detector.is_mppc_lv_on(): # Wait until MPPC and LED low voltage, and LED bias are on time.sleep(wait_time) for q in quadrants: # Start loop for Quadrant for bias_ch in range(1,5): # Start loop for MPPCbias @T # T: input (18 C) quad = sub_detector.quadrant[q] print "Turning off BIAS for MPPC on the Quadrant......" quad.turn_mppc_bias_off()# Turn off all bias (MPPC). Uquad = us.quadrant[q] # Retrieving upstream quadrant. Dquad = ds.quadrant[q] # Retrieving downstream quadrant. Uquad.turn_mppc_bias_off()# Turn off all bias (MPPC). Dquad.turn_mppc_bias_off()# Turn off all bias (MPPC). if not single: Uquad.turn_mppc_bias_on(ch=bias_ch) # Turn on bias channel number for all the modules in the quadrant. Dquad.turn_mppc_bias_on(ch=bias_ch) # Turn on bias channel number for all the modules in the quadrant. else: quad.turn_mppc_bias_on(ch=bias_ch) if not single: for number, m in sorted(Uquad.module.items()): # Start loop for module check upstream. while (not m.is_bias_on(bias_ch)) or (not ( sum( m.is_bias_off(i) for i in range(1,5) ) == 3 )): # Wait until bias channel number is turned on only. time.sleep(wait_time) for number, m in sorted(Dquad.module.items()): # Start loop for module check downstream while (not m.is_bias_on(bias_ch)) or (not ( sum( m.is_bias_off(i) for i in range(1,5) ) == 3 )): # Wait until bias channel number is turned on only. time.sleep(wait_time) else: for number, m in sorted(quad.module.items()): # Start loop for module check downstream while (not m.is_bias_on(bias_ch)) or (not ( sum( m.is_bias_off(i) for i in range(1,5) ) == 3 )): # Wait until bias channel number is turned on only. time.sleep(wait_time) for number, l in sorted(quad.led.items()): # Start loop for columns in selected detector side. l.turn_pulser_on() time.sleep(float(l.npulses_set)/float(l.frequency_set)*1.2+0.1) # Wait over 20% more time than the estimated pulsing time. Minimum waiting time 0.1 s while l.is_pulser_on(): # Wait until pulser is turned off time.sleep(wait_time) l.turn_pulser_off() # Set corresponding start mask to 0. This function return after the pulser is off. Double check. if not single: Uquad.turn_mppc_bias_off(ch=bias_ch) # Turn off bias channel number for all the modules in the quadrant. Dquad.turn_mppc_bias_off(ch=bias_ch) # Turn off bias channel number for all the modules in the quadrant. else: quad.turn_mppc_bias_off(ch=bias_ch) # Turn off bias channel number for all the modules in the quadrant. # Turning everything off before exit. us.turn_led_lv_off() us.turn_led_bias_off() #us.turn_mppc_lv_off() ds.turn_led_lv_off() ds.turn_led_bias_off() #ds.turn_mppc_lv_off() end = time.time() print "All done!\nElapsed time: %f (min)" % (float(end-start)/60.0) def option_handler(argv): sides=['U','D'] quadrants = range(1,5) single = False freq = 100 width = 200 npulses = 1 temp = 18.0 offset = 1.2 led_bias = 6.0 if len(argv) > 1: if '-s' in argv: try: s = argv[argv.index('-s')+1] except IndexError: print "Error: missing side (U or D) after [-s] option" sys.exit(1) if s in sides: sides = s else: print "Error: side must be U or D" sys.exit(1) if '-q' in argv: try: q = argv[argv.index('-q')+1] except IndexError: print "Error: missing quadrant (1 to 4) after [-q] option" sys.exit(1) try : q = map(lambda x: int(x),q.split(',')) except ValueError: print "quadrant must be integers from 1 to 4" sys.exit(1) if reduce(lambda x,y: x and y, map(lambda x: x in quadrants,q)): quadrants = q else: print "Error: quadrant must contain integers in [1,4] separated by ','" sys.exit(1) if '-f' in argv: try: freq = float(argv[argv.index('-f')+1]) except (IndexError, ValueError): print "Error: missing frequency after [-f] option" sys.exit(1) if (freq < 0.047) or (freq > 100e6): print "Error: Frequency must be in [0.047, 100e6] Hz." sys.exit(1) if '-w' in argv: try: width = int(argv[argv.index('-w')+1]) except (IndexError, ValueError): print "Error: missing width after [-w] option" sys.exit(1) if (width < 10) or (width > 1000): print "Error: Width must be in [10, 1000] ns. Resolution 10 ns." sys.exit(1) if '-n' in argv: try: npulses = int(argv[argv.index('-n')+1]) except (IndexError, ValueError): print "Error: missing npulses after [-n] option" sys.exit(1) if (npulses < 1) or (npulses > 2.147483647e9): print "Error: Number of pulses must be in [1, 2.147483647e9]." sys.exit(1) if '-t' in argv: try: temp = float(argv[argv.index('-t')+1]) except (IndexError, ValueError): print "Error: missing temperature after [-t] option" sys.exit(1) if (temp < 5) or (temp > 30): print "Error: Temperature must be in [5, 30] C." sys.exit(1) if '-o' in argv: try: offset = float(argv[argv.index('-o')+1]) except (IndexError, ValueError): print "Error: missing offset after [-o] option" sys.exit(1) if (offset < 0) or (offset > 1.5): print "Error: Offset must be in [0, 1.5] V." sys.exit(1) if '-b' in argv: try: led_bias = float(argv[argv.index('-b')+1]) except (IndexError, ValueError): print "Error: missing led bias after [-b] option" sys.exit(1) if (led_bias < 0) or (led_bias > 10): print "Error: LED bias must be in [0, 10] V." sys.exit(1) if '--single' in argv: single = True if '-h' in argv or '--help' in argv: print''' %s [option value] options: -s < U | D >: Select side U for upstream or D for downstream. If this option is not given, it will run through both sides. -q < q_1,q_2,... >: Select quadrants with numbers 'q_i' in {1,...,4}. If this option is not given, it will run through all quadrants. -f < freq >: Set pulser frequency in Hz, range [0.047, 100e6]. Default value %.1f Hz -w < width >: Set pulser width in ns, range [10, 1000] in 10 ns steps. Default value %d ns -n < npulses >: Set pulser number of pulses before stop, range [1, 2.147483647e9]. Default value %d -t < temperature >: Set mppc temperature in C, range [5, 30]. Will be used in small temperature corrections. Default value %.1f C -o < offset >: Set mppc voltage above breakdown, range [0, 1.5]. Default value %.1f V -b < led_bias >: Set led bias voltage, range [0, 10]. Default value %.1f V --single: Turn on mppc bias in one side only. -h,--help: Show this help. Note: Ctrl-c interruption handled, it will turn all off and then exit. Example: %s -s U -q 2,3 -f 100 -w 200 -n 1 Autor: Orlando Soto, April, 2014 '''%(argv[0],freq,width,npulses, temp, offset, led_bias, argv[0]) sys.exit(0) return sides,quadrants,single,freq,width,npulses,temp,offset,led_bias def interrupt_handler(signum,frame): signal.signal(signal.SIGINT,signal.SIG_DFL) start_red_color = '\033[91;1m' default_color = '\033[0m' print start_red_color + 'Ctrl-c pressed, turning off everything...' try: us.turn_led_lv_off() us.turn_led_bias_off() us.turn_mppc_lv_off() us.turn_mppc_bias_off() ds.turn_led_lv_off() ds.turn_led_bias_off() ds.turn_mppc_lv_off() ds.turn_mppc_bias_off() except NameError: print 'us and ds objects not created yet, nothing to do' except AttributeError: print 'us and ds objects empty' print default_color + 'Bye' sys.exit(0) return if __name__=="__main__": main()