Skip to content
Snippets Groups Projects
Commit 7c52f5ca authored by Mario Gonzalez Carpintero's avatar Mario Gonzalez Carpintero
Browse files

Merge branch 'devel_iviscan' into 'devel'

devel iviscan

See merge request !5
parents 9c738379 95159b02
Branches
Tags
1 merge request!5devel iviscan
Pipeline #2590325 passed
......@@ -5,10 +5,10 @@
{
"name": "HV",
"initial_voltage": 0,
"final_voltage": -150,
"final_voltage": -200,
"step_size": -5,
"measurements_per_step": 3,
"sleeping_time_per_step_s": 10,
"measurements_per_step": 10,
"sleeping_time_per_step_s": 2,
"current_protection": 0.0001
},
"passive_channels":
......@@ -34,4 +34,4 @@
[
]
}
}
\ No newline at end of file
}
......@@ -6,6 +6,7 @@ import numpy as np
import time
import getpass
from influxdb import InfluxDBClient, exceptions
import logging, coloredlogs, verboselogs
# LR stuff
LABREMOTE = 1
......@@ -18,31 +19,14 @@ except:
LABREMOTE = 0
def sigint_handler(sig, frame):
print('[ info ][ ivi ] Received SIGINT. Exiting!')
logger.info('Received SIGINT. Exiting!')
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
def meas_voltage(hw, ps, args):
return ps.measureVoltage()
def power_on(hw, ps, args):
if args.voltage_level and args.current_protect:
ps.setVoltageLevel(args.voltage_level)
ps.setCurrentProtect(args.current_protect)
ps.turnOn()
return 0
def power_off(hw, ps, args):
ps.turnOff()
return 0
def powerPassiveChannels(config, key, what):
if what == "turnOn":
......@@ -51,8 +35,7 @@ def powerPassiveChannels(config, key, what):
ps = hw.getPowerSupplyChannel(elem["name"])
print()
print("setting I to %2g A and V to %2g V on channel %s" % (elem["current"], elem["voltage"], elem["name"]))
logger.info("setting I to %2g A and V to %2g V on channel %s" % (elem["current"], elem["voltage"], elem["name"]))
ps.setVoltageLevel(elem["voltage"])
ps.setCurrentLevel(elem["current"])
......@@ -65,6 +48,70 @@ def powerPassiveChannels(config, key, what):
ps.turnOn()
def ramp(varName, pschannel, target, step = None, tsleep = None):
if varName == "voltage":
xVarName = "voltage" ; xUnit = "V"
yVarName = "current" ; yUnit = "A"
measXvar = pschannel.measureVoltage
setXvar = pschannel.setVoltageLevel
measYvar = pschannel.measureCurrent
tolerance = 1 # V
if step is None: step = 5 # V
if tsleep is None: tsleep = 1 # s
elif varName == "current":
xVarName = "current" ; xUnit = "A"
yVarName = "voltage" ; yUnit = "V"
measXvar = pschannel.measureCurrent
setXvar = pschannel.setCurrentLevel
measYvar = pschannel.measureVoltage
tolerance = 0.02 # A
if step is None: step = 0.1 # A
if tsleep is None: tsleep = 0.5 # s
else:
logger.error("'varName' can only be 'voltage' or 'current'")
# Get current values of V and I
xmeas = measXvar()
ymeas = measYvar()
#isOn = pschannel.getPowerSupply().isOn(pschannel.getChannel())
isOn = (measXvar() != 0 or measYvar() != 0)
diff = target - xmeas
logging.debug(varName + " difference (target - meas): " + str(diff) + " " + xUnit)
# Decide whether ramping is finished or not
if abs(diff) <= tolerance / 2:
logger.info("ramping finished")
return xmeas
# determine direction of ramp
if diff < 0 and step > 0 or diff > 0 and step < 0 :
step = -step
logger.info("ramping from %.2g %s to %.2g %s in steps of %.2g %s" % (xmeas, xUnit, target, xUnit, step, xUnit))
while abs(xmeas) >= abs(target)+abs(step) or abs(xmeas) <= abs(target)-abs(step):
setXvar(xmeas+step)
time.sleep(tsleep)
xmeas = measXvar()
ymeas = measYvar()
logger.debug("PSU is on? " + str(isOn) + "; " + xVarName + ": " + str(xmeas) + " " + xUnit + "; " + yVarName + ": " + str(ymeas) + " " + yUnit)
diff = target - xmeas
if abs(diff) < abs(step):
logging.debug("--------------------")
logger.info("[%s, %s] = [%.2g %s, %.2g %s] " % (xVarName, yVarName, xmeas, xUnit, ymeas, yUnit))
ramp(xVarName, pschannel, target, step/5.)
def doivi(config, w, dbSink=""):
if w == "iv":
......@@ -83,7 +130,7 @@ def doivi(config, w, dbSink=""):
ch = config[key]["target_channel"]
ps = hw.getPowerSupplyChannel(ch["name"])
if ps == None:
print("[ error ][ ivi ] change the config and try again!")
logger.error("change the config and try again!")
exit(1)
if w == "iv":
......@@ -97,7 +144,7 @@ def doivi(config, w, dbSink=""):
measYvar = ps.measureVoltage
print("Starting the %s scan..." % w)
logger.info("Starting the %s scan..." % w)
if w == "iv":
ps.setCurrentProtect(ch["current_protection"])
......@@ -127,30 +174,34 @@ def doivi(config, w, dbSink=""):
data[yKeyOutUnit+"_Compliance"] = config[key]["target_channel"][yVarName+"_protection"]
data[outputKey] = []
# < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <
# Output to the terminal
# > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
colWidths = "{0:8}{1:17}{2:20}{3:20}{4:20}{5:20}"
print(colWidths.format("# time", xVarName + "_Level", xVarName + "_SenseMean", xVarName + "_SenseStd", yVarName + "_SenseMean", yVarName + "_SenseStd"))
# < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <
xVar = ch["initial_" + xVarName]
step = ch["step_size"]
startX = measXvar()
#wasOn = ps.isOn()
wasOn = (measXvar() != 0 or measYvar() != 0)
# Go to the starting point
steps = np.linspace(startX, xVar, 10)
for e in steps:
setXvar(e)
time.sleep(1)
# Ramp to the starting point if PSU is already on
if wasOn:
ramp(xVarName, ps, xVar)#, 5, 1)
else:
setXvar(xVar)
ps.turnOn()
# Output to the terminal
# > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
colWidths = "{0:8}{1:17}{2:20}{3:20}{4:20}{5:20}"
print(colWidths.format("# time", xVarName + "_Level", xVarName + "_SenseMean", xVarName + "_SenseStd", yVarName + "_SenseMean", yVarName + "_SenseStd"))
# < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <
while (xVar - ch["final_" + xVarName])* step/abs(step) <= 0:
setXvar(xVar)
ps.turnOn()
if w == "vi":
ps.turnOn()
time.sleep(ch["sleeping_time_per_step_s"])
......@@ -166,7 +217,7 @@ def doivi(config, w, dbSink=""):
yVarPerStep.append(measY)
if measY > ch[yVarName + "_protection"]:
print("Reached " + yVarName + " protection value")
logger.warning("Reached " + yVarName + " protection value")
break
else:
......@@ -208,22 +259,25 @@ def doivi(config, w, dbSink=""):
xVar += step
# turn everything off (power-cycle the PS)
#ps.turnOff()
if w == "vi":
ps.turnOff()
continue
break
# Go back to the point before the scans
steps = np.linspace(measXvar(), startX, 10)
for e in steps:
setXvar(e)
time.sleep(1)
with open(args.outfile+"_"+w+".json", "w") as f:
json.dump(data, f, indent=4)
if w == "iv":
# ramp HV outside of IV curve according to module testing document
# 2V/s for 3D, 5V/s for planar
ramp(xVarName, ps, startX)#, 5, 1)
if not wasOn:
ps.turnOff()
powerPassiveChannels(config, key, "turnOff")
with open("output_"+w+".json", "w") as f:
json.dump(data, f, indent=4)
......@@ -255,14 +309,14 @@ def toInfluxDB(points, dbSink, host='localhost', port=8086):
# If auth is enabled, ask the user for his/her password
if "authorization failed" in str(e):
print("[ warn ] Input the password for user \"{}\" in InfluxDB.\n"
logger.warning("Input the password for user \"{}\" in InfluxDB.\n"
" If you don\'t want to input the password in the future until\n"
" you close your current bash session use \n"
" \"export INFLUXDBPWD=yourPassword\".".format(usr))
try:
pwd = getpass.getpass()
except:
print()
except Exception as e:
logger.error(e)
sys.exit(1)
# And connect again.
......@@ -279,8 +333,8 @@ def toInfluxDB(points, dbSink, host='localhost', port=8086):
except exceptions.InfluxDBClientError as e:
# If not, let the user know what's happening and exit.
print("[ error ] Received error from InfluxDB: {}".format(e))
print("[ info ] Please specify the db connectivity parameters "
logger.error("Received error from InfluxDB: {}".format(e))
logger.info("Please specify the db connectivity parameters "
"\"database\", and also \"username\", "
"\"host\" and \"port\" in the .\"influxdb_cfg\" section in"
"the provided DCS config file. Make sure the provided username and password are correct.\n")
......@@ -290,11 +344,15 @@ def toInfluxDB(points, dbSink, host='localhost', port=8086):
try:
client.write_points(points)
except exceptions.InfluxDBClientError as e:
print("[ error ] Received error from InfluxDB: {}".format(e))
logger.error("Received error from InfluxDB: {}".format(e))
sys.exit(1)
if __name__ == "__main__":
coloredlogs.install(level="INFO") ### controls availability of colored logs
logger = verboselogs.VerboseLogger('ivi')
parser = argparse.ArgumentParser()
parser.add_argument(
......@@ -306,8 +364,9 @@ if __name__ == "__main__":
parser.add_argument(
"-j",
"--json",
required=True,
help="path to iviscan.json",
required=False,
default="configs/lr_iviscan.json",
help="path to iviscan.json. Default is \"configs/lr_iviscan.json\"",
)
parser.add_argument(
"-e",
......@@ -315,8 +374,23 @@ if __name__ == "__main__":
required=True,
help="powersupply.json Configuration file with the power supply definition",
)
parser.add_argument(
"-o",
"--outfile",
required=False,
default="output",
help="output file name without file extension. Will be saved in .json format. Default is \"output\"",
)
parser.add_argument(
"-u",
"--upload",
required=False,
action="store_true",
help="If set will upload data to influxDB. \"influxdb_cfg\" required in powersupply.json",
)
args = parser.parse_args()
logger.debug(args)
# - - - - - - - - - -
with open(args.json) as f:
......@@ -339,20 +413,16 @@ if __name__ == "__main__":
try:
import _labRemote as labRemote
except:
print("Couldn't find the labRemote Python libraries. Make sure to add them to your $PYTHONPATH first by either doing")
print()
print(" export PYTHONPATH=/path/to/labRemote/build/lib:$PYTHONPATH")
print()
print(" or writing \"/path/to/labRemote/build/lib\" in \"" + args.equip + "\"")
print()
print("And make sure also that you have previously built labRemote enabling the Python bindings (cmake3 -DUSE_PYTHON=on)")
logger.error("Couldn't find the labRemote Python libraries")
logger.info("Make sure to add them to your $PYTHONPATH first by either doing")
logger.info(" export PYTHONPATH=/path/to/labRemote/build/lib:$PYTHONPATH")
logger.info(" or writing \"/path/to/labRemote/build/lib\" in \"" + args.equip + "\"")
logger.info("Also make sure labRemote is built with Python bindings (cmake3 -DUSE_PYTHON=on)")
exit(1)
uploadToInflux = False
if uploadToInflux:
#dbSink = psConfig["influxdb_cfg"]
if args.upload:
dbSink = psConfig["influxdb_cfg"]
pass
else:
dbSink = ""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment