diff --git a/simuLines.py b/simuLines.py index c7cb44b..6925cb5 100755 --- a/simuLines.py +++ b/simuLines.py @@ -11,7 +11,7 @@ from gwpy.time import tconvert import datetime import configparser import numpy as np -from multiprocessing import Process, Queue, Manager +from multiprocessing import Process, Queue, Manager, Lock import cdsutils import h5py import logging @@ -42,6 +42,9 @@ logger.addHandler(file_handler) logger.addHandler(stdout_handler) ###/Python Logger boiler plate +# lock used to block processes from sending at the same time +awg_lock = Lock() + class ResultsObject(): ''' This object defines how data is collected within each swept sine measurement. @@ -481,19 +484,68 @@ def SignalInjection(resultobj, freqAmp): #Driving the excitations with ramp up, settle time and ramp down. logger.info('Drive, on ' + resultobj.scanName + ', at frequency: ' + str(freqAmp[0])+ ', is now running for '+str(fullDuration + rampUp + rampDown + settleTime + 1) + ' seconds.') - drive.start(ramptime=rampUp) #this is blocking, and starts on a GPS second. + + start_drive(drive, rampUp) #this is blocking, and starts on a GPS second. + time.sleep(np.ceil(settleTime)) #this will soak at least half of that +1 second buffer. Having at least that one second assures that the time windows are actually after sette time. #start of real data acquisition should also be exactly a GPS second #tconvert('now') gives the floor of the current GPS second. timeWindowStart = int(tconvert('now')) time.sleep(fullDuration) timeWindowEnd = int(tconvert('now')) - drive.stop(ramptime=rampDown)# you'd think 'wait = false' skips the sleep and saves time? No, it just fails to ramp down when a new start is called, since commands sent to a channel override previous commands. :( No beuno. + + stop_drive(drive,rampDown) + #write the start and stop times to the results object for later processing. logger.info('Drive, on ' + resultobj.scanName + ', at frequency: ' + str(freqAmp[0])+ ', is finished. GPS start and end time stamps: '+str(timeWindowStart)+', '+str(timeWindowEnd)) for iteration in range(len(resultobj.channelB)): #One TF is defined by each A and B pair. resultobj.saveTimeFlags(str(freqAmp[0]), timeWindowStart, timeWindowEnd, singleDuration, iteration) + +def start_drive(drive, rampUp): + """Safely start a drive, but without blocking + other commands from other processes for long.""" + + # set the gain to 0 before starting excitation, because + # we need to use the gain later to ramp up the excitatioin + awg_lock.acquire() + drive.set_gain(0.0, wait=False) + awg_lock.release() + + # sleep two epochs (1/8 sec) to make sure gain is set + time.sleep(1 / 8.0); + + awg_lock.acquire() + drive.start(ramptime=0, wait=False) + awg_lock.release() + + # sleep two epochs (1/8 sec)to make sure sine wave is started + time.sleep(1 / 8.0); + + # ramp up the drive using the gain + awg_lock.acquire() + drive.set_gain(1.0, ramptime=rampUp, wait=False) + awg_lock.release() + + # wait for the ramp up to finish + time.sleep(rampUp + 1 / 8.0) + + +def stop_drive(drive, rampDown): + + # start thre ramp down + awg_lock.acquire() + drive.set_gain(0, ramptime=rampDown, wait=False) + awg_lock.release() + + # wait for the ramp down to finish + time.sleep(rampDown + 1 / 8.0) + + awg_lock.acquire() + drive.stop() + awg_lock.release() + + def scanToFilenameMap(scan): if scan == 'DARM_OLGTF': return 'DARMOLG_SS'