'''

Author: Federica Lionetto
Date: January 5th, 2015

Description:
Automated measurement for focusing.
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;
- <par>, the parameter identifying the measurement;
- <firstx>, the first x position;
- <lastx>, the last x position;
- <stepx>, the step size along x;
- <firstz>, the first z position;
- <lastz>, the last z position;
- <stepz>, the step size along z;
- <yyyymmdd>, the date according to the yyyymmdd format.

Some more information about <par>.
If <measurement> = <CCEBiasVoltageScan>, <par> = 200 means that the measurement is taken at 200 V.
If <measurement> = <CCEAttenuationScan>, <par> = 23.0 means that the measurement is taken at 23.0 dB.
More functionalities can be implemented.

How to run it:
python ElectronicMonkeyFocusing.py --s <sensor> --m <measurement> --p <par> --fx <firstx> --lx <lastx> --sx <stepx> --fz <firstz> --lz <lastz> --sz <stepz> --date <yyyymmdd>

For example:
python ElectronicMonkeyFocusing.py --s Hans410 --m CCEBiasVoltageScan --p 200 --fx 0 --lx 50 --sx 2 --fz -400 --lz -200 --sz 20 --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 sys
sys.path.insert(0,'../Tools')
from SendEmail import *

parser = argparse.ArgumentParser(description='Define the parameters of the automated measurement for focusing.')

parser.add_argument('--s',help='type of sensor')
parser.add_argument('--m',help='type of measurement')
parser.add_argument('--p',help='parameter identifying the measurement')
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('--fz',type=int,help='first z position')
parser.add_argument('--lz',type=int,help='last z position')
parser.add_argument('--sz',type=int,help='step size along z')

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
par = args.p

firstx = args.fx
lastx = args.lx
stepx = args.sx

firstz = args.fz
lastz = args.lz
stepz = args.sz

yyyymmdd = args.date

nevents = 10000

folder = '/disk/groups/hep/flionett/TestStand/Data'
filename = ''
config = '/home/hep/flionett/TestStand/Repository/TestStandRepository/Software/AutomatedMeasurements/FocusingConfig'

print 'Type of sensor: ', sensor
print 'Type of measurement: ', measurement 

print 'First x position: %i steps' % firstx
print 'Last x position: %i steps' % lastx
print 'Step size along x: %i steps' % stepx

print 'First z position: %i steps' % firstz
print 'Last z position: %i steps' % lastz
print 'Step size along z: %i steps' % stepz

print 'Number of events per DAQ: %i' % nevents

# Number of scanned x positions.
stepsx = (lastx-firstx)/stepx+1
print 'Number of scanned x positions: %i' % stepsx
# Number of scanned z positions.
stepsz = (lastz-firstz)/stepz+1
print 'Number of scanned z positions: %i' % stepsz

# 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 firstz is positive, +02 if firstz is negative, firstz times.
for zcounter in range(abs(firstz)) :
    print 'Step along z %i of %i' % (zcounter,firstz)
    if (firstz > 0) :
        ser.write('+01')
    elif (firstz < 0) :
        ser.write('+02')
    time.sleep(1)

# Take a pedestal run.
if not os.path.exists(folder+"/"+sensor+"/"+measurement):
    os.makedirs(folder+"/"+sensor+"/"+measurement)
if (measurement == "CCEBiasVoltageScan") :
    filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+par+"V"+"-216-"+"ped.ali"
elif (measurement == "CCEAttenuationScan") :
    filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+par+"dB"+"-216-"+"ped.ali"
else :
    filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-216-"+"ped.ali"
printcommand = "echo alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --pedestal "+config
command = "alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --pedestal "+config
print '***'
subprocess.call(printcommand,shell=True)
subprocess.call(command,shell=True)

# Perform the measurement.
daqx = 0.
daqz = 0.
for posz in range(firstz,lastz+stepz,stepz) :
    daqx = 0.
    daqz = daqz+1.
    for posx in range(firstx,lastx+stepx,stepx) :
        daqx = daqx+1.
        status = 100.*((daqx-1)+(daqz-1)*stepsx)/(stepsx*stepsz)
        print 'Position along x: %i steps' % posx
        print 'Position along z: %i steps' % posz
        print 'Status: %.2f %% completed' % status

        if (measurement == "CCEBiasVoltageScan") :
            filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+par+"V"+"-216-"+str(posx)+"x-"+str(posz)+"z-las.ali"
        elif (measurement == "CCEAttenuationScan") :
            filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-"+par+"dB"+"-216-"+str(posx)+"x-"+str(posz)+"z-las.ali"
        else :
            filename = folder+"/"+sensor+"/"+measurement+"/"+str(yyyymmdd)+"-216-"+str(posx)+"x-"+str(posz)+"z-las.ali"

        printcommand = "echo alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --laser "+config
        command = "alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --laser "+config
        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 z position.
    # 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)
    # Move the stepper motor along z.
    # Send +01 (backward step of 5 microns) stepz times.
    if (posz < lastz) :
        for counter in range(stepz) :
            print '+01 %i' % counter
            ser.write('+01')
            time.sleep(2)
# Reset the position of the stepper motor along z, to make it ready for the following measurement.
# Send +02 (forward step of 5 microns) stepz*len(range(firstz,lastz,stepz)) times.
for counter in range(stepz*len(range(firstz,lastz,stepz))) :
    print '+02 %i' % counter
    ser.write('+02')
    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 firstz is positive, +01 if firstz is negative, firstz times.
for zcounter in range(abs(firstz)) :
    print 'Step along z %i of %i' % (zcounter,firstz)
    if (firstz > 0) :
        ser.write('+02')
    elif (firstz < 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)
