''' Author: Federica Lionetto Date: March 5th, 2015 Description: Automated measurement for CCE scan (bias voltage, attenuation, and delay). The script takes a pedestal run, moves the laser to the starting position along x and z and then takes care of the data acquisitions with the Alibava system. After the measurement, the position of the laser along x and z is reset. Parameters: - <sensor>, the type of sensor; - <measurement>, the type of measurement; - <firstpar>, the first value of the parameter identifying the measurement; - <lastpar>, the last value of the parameter identifying the measurement; - <steppar>, the step size along the value of the parameter identifying the measurement; - <z>, the z position; - <firstx>, the first x position; - <lastx>, the last x position; - <stepx>, the step size along x; - <yyyymmdd>, the date according to the yyyymmdd format. Some more information about <par>. If <measurement> = <CCEBiasVoltageScan>, <firstpar> = 100 && <lastpar> = 200 && <steppar> = 20 means that the measurement is taken from 100 V to 200 V in 20 V steps. If <measurement> = <CCEAttenuationScan>, <firstpar> = 21.0 && <lastpar> = 25.0 && <steppar> = 0.5 means that the measurement is taken from 21.0 dB to 25.0 dB in 0.5 dB steps. If <measurement> = <CCEDelayScan>, <firstpar> = 67 && <lastpar> = 75 && <steppar> = 1 means that the measurement is taken from 67 ns to 75 ns in 1 ns steps. More functionalities can be implemented. Meaurements of type "CCEBiasVoltageScan" and "CCEDelayScan" have int parameters but measurements of type "CCEAttenuationScan" have float parameters. So float are used all the time, but casting them to int if necessary. If the measurement is of type "CCEDelayScan" we need a different configuration file for each value of the delay. All these files are in "CCEDelayScanConfig" folder. How to run it: python ElectronicMonkeyCCEScan.py --s <sensor> --m <measurement> --fp <firstpar> --lp <lastpar> --sp <steppar> --z <z> --fx <firstx> --lx <lastx> --sx <stepx> --date <yyyymmdd> For example: python ElectronicMonkeyCCEScan.py --s Hans410 --m CCEBiasVoltageScan --fp 100 --lp 200 --sp 20 --z 176 --fx 0 --lx 50 --sx 2 --date 20150106 Arduino device ID: DEVICE ID 2341:0042 on Bus 001 Address 045, Communications Device (in hexadecimal) To get some information on the device: lsusb -v -d 2341:0042 ''' import argparse import subprocess import os import serial import time import numpy as np import sys sys.path.insert(0,'../Tools') from SendEmail import * parser = argparse.ArgumentParser(description='Define the parameters of the automated measurement for CCE scan.') parser.add_argument('--s',help='type of sensor') parser.add_argument('--m',help='type of measurement') # Meaurements of type "CCEBiasVoltageScan" and "CCEDelayScan" have int parameters but measurements of type "CCEAttenuationScan" have float parameters. So float are used all the time, but casting them to int if necessary. parser.add_argument('--fp',type=float,help='first value of the parameter identifying the measurement') parser.add_argument('--lp',type=float,help='last value of the parameter identifying the measurement') parser.add_argument('--sp',type=float,help='step size along the value of the parameter identifying the measurement') parser.add_argument('--z',type=int,help='z position') parser.add_argument('--fx',type=int,help='first x position') parser.add_argument('--lx',type=int,help='last x position') parser.add_argument('--sx',type=int,help='step size along x') parser.add_argument('--date',type=int,help='date according to the yyyymmdd format') args = parser.parse_args() # Parameters and configuration. sensor = args.s measurement = args.m firstpar = args.fp lastpar = args.lp steppar = args.sp z = args.z firstx = args.fx lastx = args.lx stepx = args.sx yyyymmdd = args.date nevents = 10000 folder = '/disk/groups/hep/flionett/TestStand/Data' filename = '' config = '/home/hep/flionett/TestStand/Repository/TestStandRepository/Software/AutomatedMeasurements' print 'Type of sensor: ', sensor print 'Type of measurement: ', measurement print 'First value of the parameter identifying the measurement: %.1f steps' % firstpar print 'Last value of the parameter identifying the measurement: %.1f steps' % lastpar print 'Step size along the value of the parameter identifying the measurement: %.1f steps' % steppar print 'z position: %i steps' % z print 'First x position: %i steps' % firstx print 'Last x position: %i steps' % lastx print 'Step size along x: %i steps' % stepx print 'Number of events per DAQ: %i' % nevents # Number of scanned values of the parameter identifying the measurement. stepspar = (int(lastpar)-int(firstpar))/int(steppar)+1 print 'Number of scanned values of the parameter identifying the measurement: %i' % stepspar # Number of scanned x positions. stepsx = (lastx-firstx)/stepx+1 print 'Number of scanned x positions: %i' % stepsx # Find Arduino. ser = serial.Serial('/dev/ttyACM0',9600) # Move the laser to the starting position along x and z. print 'Move the laser to the starting position along x and z.' # +10 if firstx is positive, +20 if firstx is negative, firstx times. for xcounter in range(abs(firstx)) : print 'Step along x %i of %i' % (xcounter,firstx) if (firstx > 0) : ser.write('+10') elif (firstx < 0) : ser.write('+20') time.sleep(1) # +01 if z is positive, +02 if z is negative, z times. for zcounter in range(abs(z)) : print 'Step along z %i of %i' % (zcounter,z) if (z > 0) : ser.write('+01') elif (z < 0) : ser.write('+02') time.sleep(1) # Take a pedestal run. if not os.path.exists(folder+"/"+sensor+"/"+measurement): os.makedirs(folder+"/"+sensor+"/"+measurement) filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-216-"+"ped.ali" configped = config+"/FocusingConfig"+sensor printcommand = "echo alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --pedestal "+configped command = "alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --pedestal "+configped print '***' subprocess.call(printcommand,shell=True) subprocess.call(command,shell=True) # Perform the measurement. daqx = 0. daqpar = 0. for pospar in np.linspace(firstpar,lastpar,(lastpar-firstpar)/steppar+1) : daqx = 0. daqpar = daqpar+1. # If the measurement is of type "CCEDelayScan" we need a different configuration file for each value of the delay. All these files are in "CCEDelayScanConfig" folder. if (measurement == "CCEDelayScan") : configlas = config+"/CCEDelayScanConfig/"+"CCEDelayScanConfig"+str(int(pospar))+"ns" else : configlas = configped for posx in range(firstx,lastx+stepx,stepx) : daqx = daqx+1. status = 100*((daqx-1)+(daqpar-1)*stepsx)/(stepsx*stepspar) print 'Value of the parameter identifying the measurement: %i steps' % pospar print 'Position along x: %i steps' % posx print 'Position along z: %i steps' % z print 'Status: %.2f %% completed' % status if (measurement == "CCEBiasVoltageScan") : filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+str(int(pospar))+"V"+"-216-"+str(posx)+"x-"+str(z)+"z-las.ali" elif (measurement == "CCEAttenuationScan") : filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+str(pospar)+"dB"+"-216-"+str(posx)+"x-"+str(z)+"z-las.ali" elif (measurement == "CCEDelayScan") : filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+str(int(pospar))+"ns"+"-216-"+str(posx)+"x-"+str(z)+"z-las.ali" else : filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-216-"+str(posx)+"x-"+str(z)+"z-las.ali" printcommand = "echo alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --laser "+configlas command = "alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --laser "+configlas print '***' subprocess.call(printcommand,shell=True) subprocess.call(command,shell=True) # Move the stepper motor along x. # Send +10 (forward step of 5 microns) stepx times. if (posx < lastx) : for counter in range(stepx) : print '+10 %i' % counter ser.write('+10') time.sleep(2) # Reset the position of the stepper motor along x, to make it ready for the DAQs at the following value of the parameter identifying the measurement. # Send +20 (backward step of 5 microns) stepx*len(range(firstx,lastx,stepx)) times. for counter in range(stepx*len(range(firstx,lastx,stepx))) : print '+20 %i' % counter ser.write('+20') time.sleep(2) print '***' # Move the laser to the starting position along x and z. print 'Move the laser to the starting position along x and z.' # +20 if firstx is positive, +10 if firstx is negative, firstx times. for xcounter in range(abs(firstx)) : print 'Step along x %i of %i' % (xcounter,firstx) if (firstx > 0) : ser.write('+20') elif (firstx < 0) : ser.write('+10') time.sleep(1) # +02 if z is positive, +01 if z is negative, z times. for zcounter in range(abs(z)) : print 'Step along z %i of %i' % (zcounter,z) if (z > 0) : ser.write('+02') elif (z < 0) : ser.write('+01') time.sleep(1) print 'End of the measurement!' # Send email. sender = 'federica.lionetto@cern.ch' receiver = 'federica.lionetto@cern.ch' # receiver = 'philipp.gloor@gmail.com' message = 'End of the measurement! Go to switch off the stepper motors ;)' subject = 'End of the measurement!' send_email(sender,receiver,message,subject)