def main():

    #initialize board
    femb_config = CONFIG()
    femb_config.COLD = True
    femb_config.doSpiWrite = False

    print("\n")
    print("Running ADC synchronization process")
    print("Configuration parameters:")
    femb_config.printParameters()

    #check if register interface still working
    regVal = femb_config.femb.read_reg(femb_config.REG_FIRMWARE_VERSION)
    if regVal == None :
        print( "Register interface error, could not synchronize ASIC " )
        return

    #do sync
    asicStatus = [1,1,1,1]
    for asic in [0,1,2,3]:
        asicNum = int(asic)
        if (asicNum < 0) or (asicNum>3) :
            continue 
        femb_config.doAdcAsicConfig(asicNum)
        if femb_config.adcSyncStatus == False :
            femb_config.fixUnsync(asicNum)
        if femb_config.adcSyncStatus == False :
            print( "Could not synchronize ASIC ", asicNum )
            asicStatus[asicNum] = 0

    print("ASIC SYNC STATUS","\t",asicStatus)
def main(isCold=False):

    if (isCold != True) and (isCold != False):
        print(
            "Invalid input temperature parameter, will assume room temperature"
        )
        isCold = False

    #initialize board
    femb_config = CONFIG()
    femb_config.COLD = isCold
    #femb_config.COLD = True
    femb_config.enableTest = 1
    femb_config.isExternalClock = True
    femb_config.is1MHzSAMPLERATE = False  #COOL

    print("\n")
    print("Running test setup initialization process")
    print("Configuration parameters:")
    femb_config.printParameters()

    #initialize readout to known working state
    print("Initializing board")
    initStatus = femb_config.initBoard()
    if initStatus == False:
        #setup in bad state
        completeFailure()
        return
    asicStatus = [1, 1, 1, 1]
    for asic in [0, 1, 2, 3]:
        #for asic in [2]:
        asicNum = int(asic)
        if (asicNum < 0) or (asicNum > 3):
            continue
        print("\n")
        print("Try initializing ASIC ", asicNum)
        initStatus = femb_config.initAsic(asicNum)
        if initStatus == False:
            print("Could not initialize ASIC ", asicNum)
            asicStatus[asicNum] = 0

    #femb_config.printSyncRegister()

    #use external pulser
    femb_config.setFPGADac(0, 1, 0, 0)  # write regs 4 and 5

    #ideally check if function generator exists here...

    #initialize funciton generator
    funcgen = Keysight_33600A("/dev/usbtmc0", 1)  #hardcoded to usbtmc0
    xLow = 0.1
    xHigh = 1.3
    offsetV = (xLow + xHigh) * 0.5
    amplitudeV = (xHigh - xLow) * 0.5
    freq = 20173
    funcgen.startSin(freq, amplitudeV, offsetV)

    #setup is in good state
    totalVictory()
    print("ASIC STATUS", "\t", asicStatus)
Beispiel #3
0
class FEMB_TEST_SIMPLE(object):
    def __init__(self,
                 datadir="data",
                 outlabel="simpleMeasurement",
                 wib=0,
                 fembNum=0):
        #set internal variables
        self.datadir = datadir
        self.outlabel = outlabel + str("_femb_") + str(fembNum + 4 * wib)
        self.outpathlabel = os.path.join(self.datadir, self.outlabel)
        self.fembNum = int(fembNum)

        print("Test type\t" + str(self.outlabel))
        print("Data path\t" + str(datadir))
        print("FEMB #\t" + str(self.fembNum))

        #import femb_udp modules from femb_udp package
        self.femb_config = CONFIG()
        self.write_data = WRITE_DATA(datadir)
        #set appropriate packet size
        self.write_data.femb.MAX_PACKET_SIZE = 9014
        self.cppfr = CPP_FILE_RUNNER()

        #set status variables
        self.status_check_setup = 0
        self.status_record_data = 0
        self.status_do_analysis = 0
        self.status_archive_results = 0

        #json output, note module version number defined here
        self.jsondict = {'type': 'fembTest_simple'}
        self.jsondict['version'] = '1.0'
        self.jsondict['timestamp'] = str(self.write_data.date)

    def check_setup(self):
        #CHECK STATUS AND INITIALIZATION
        print("SIMPLE MEASUREMENT - CHECKING READOUT STATUS")
        self.status_check_setup = 0

        #make sure output directory exists
        self.write_data.assure_filedir()

        #check if register interface is working
        print("Checking register interface")
        regVal = self.femb_config.femb.read_reg(6)
        if (regVal == None):
            print(
                "Error running test - FEMB register interface is not working.")
            print(" Turn on or debug FEMB UDP readout.")
            return
        if (regVal < 0):
            print(
                "Error running test - FEMB register interface is not working.")
            print(" Turn on or debug FEMB UDP readout.")
            return
        print("Read register 6, value = " + str(hex(regVal)))

        #check that femb number is valid
        if (int(self.fembNum) < 0) or (int(self.fembNum) >=
                                       self.femb_config.NFEMBS):
            print("Error running doFembTest - Invalid FEMB # specified.")
            return

        #DO NOT CONFIGURE, except to enable streaming
        self.femb_config.wib_reg_enable()

        self.femb_config.femb.write_reg(20, 3)
        self.femb_config.femb.write_reg(20, 3)
        time.sleep(0.001)
        self.femb_config.femb.write_reg(20, 0)
        self.femb_config.femb.write_reg(20, 0)
        time.sleep(0.001)

        # start streaming data from ASIC 0 in initialization
        self.femb_config.femb.write_reg(7, 0x80000000)
        self.femb_config.femb.write_reg(7, 0x80000000)
        femb_asic = 0 & 0x0F
        wib_asic = (((self.fembNum << 16) & 0x000F0000) +
                    ((femb_asic << 8) & 0xFF00))
        self.femb_config.femb.write_reg(7, wib_asic | 0x80000000)
        self.femb_config.femb.write_reg(7, wib_asic | 0x80000000)
        self.femb_config.femb.write_reg(7, wib_asic)
        self.femb_config.femb.write_reg(7, wib_asic)

        self.femb_config.selectFemb(self.fembNum)

        #Enable Streaming
        self.femb_config.femb.write_reg(9, 9)
        self.femb_config.femb.write_reg(9, 9)
        time.sleep(0.1)

        #test firmware versions
        if self.femb_config.checkFirmwareVersion() == False:
            print(
                'Error running doFembTest - Invalid firmware and/or register read error'
            )
            return

        if self.femb_config.syncStatus != 0:
            print('Error running doFembTest - ADC SYNC failed')
            return

        if self.femb_config.spiStatus != 0:
            print('Error running doFembTest - ADC SPI failed')
            return

        #check if data streaming is working
        print("Checking data streaming")
        testData = self.write_data.femb.get_data_packets(1)
        if testData == None:
            print("Error running doFembTest - FEMB is not streaming data.")
            print(" Turn on and initialize FEMB UDP readout.")
            return
        if len(testData) == 0:
            print("Error running doFembTest - FEMB is not streaming data.")
            print(" Turn on and initialize FEMB UDP readout.")
            return

        print("Received data packet " + str(len(testData[0])) + " bytes long")

        #check for analysis executables
        if not self.cppfr.exists(
                'test_measurements/fembTest/code/parseBinaryFile'):
            print('parseBinaryFile not found, run setup.sh')
            return

        print("SIMPLE MEASUREMENT - READOUT STATUS OK" + "\n")
        self.status_check_setup = 1

    def record_data(self):
        if self.status_check_setup == 0:
            print("Please run check_setup method before trying to take data")
            return
        if self.status_record_data == 1:
            print(
                "Data already recorded. Reset/restat GUI to begin a new measurement"
            )
            return

        #MEASUREMENT SECTION
        print("SIMPLE MEASUREMENT - RECORDING DATA")

        #wait to make sure HS link is back on after check_setup
        sleep(5)

        self.femb_config.printParameters()

        #setup output file and record data
        self.write_data.filename = self.outlabel + ".bin"
        print("Recording " + self.write_data.filename)

        isOpen = self.write_data.open_file()
        if isOpen == 0:
            print(
                "Error running doFembTest - Could not open output data file for writing, ending test"
            )
        subrun = 0

        #record data
        self.write_data.numpacketsrecord = 100
        self.write_data.run = 0
        self.write_data.runtype = 0
        self.write_data.runversion = 0

        asicCh = 0
        for asic in range(0, 8, 1):
            self.femb_config.selectChannel(asic, asicCh)
            self.write_data.record_data(subrun, asic, asicCh)
        self.write_data.close_file()

        print("SIMPLE MEASUREMENT - DONE RECORDING DATA" + "\n")
        self.status_record_data = 1

    def do_analysis(self):
        if self.status_record_data == 0:
            print("Please record data before analysis")
            return
        if self.status_do_analysis == 1:
            print("Analysis already complete")
            return
        #ANALYSIS SECTION

        print("SIMPLE MEASUREMENT - ANALYZING AND SUMMARIZING DATA")

        #parse binary
        self.cppfr.run("test_measurements/fembTest/code/parseBinaryFile",
                       [self.write_data.data_file_path])

        #run analysis program
        parseBinaryFile = self.outpathlabel + "-parseBinaryFile.root"
        call(["mv", "output_parseBinaryFile.root", parseBinaryFile])
        self.cppfr.run(
            "test_measurements/fembTest/code/processNtuple_simpleMeasurement",
            [parseBinaryFile])

        processNtupleFile = self.outpathlabel + "-processNtupleFile.root"
        call([
            "mv", "output_processNtuple_simpleMeasurement.root",
            processNtupleFile
        ])

        summaryPlot = self.outpathlabel + "-summaryPlot.png"
        call(["mv", "summaryPlot_simpleMeasurement.png", summaryPlot])

        print("SIMPLE MEASUREMENT - DONE ANALYZING AND SUMMARIZING DATA" +
              "\n")
        self.status_do_analysis = 1

    def archive_results(self):
        #if self.status_check_setup == 0 :
        #     print("Check setup status is 0, not archiving data")
        #     return
        #if self.status_do_analysis == 0:
        #    print("Please analyze data before archiving results")
        #    return
        if self.status_archive_results == 1:
            print("Results already archived")
            return
        #ARCHIVE SECTION
        print("SIMPLE MEASUREMENT - ARCHIVE")

        #add summary variables to output
        self.jsondict['femb'] = self.fembNum
        self.jsondict['filedir'] = str(self.write_data.filedir)
        self.jsondict['status_check_setup'] = str(self.status_check_setup)
        self.jsondict['status_record_data'] = str(self.status_record_data)
        self.jsondict['status_do_analysis'] = str(self.status_do_analysis)
        self.jsondict['status_archive_results'] = str(1)
        self.jsondict['syncStatus'] = str(self.femb_config.syncStatus)

        #dump results into json
        jsonFile = self.outpathlabel + "-results.json"
        with open(jsonFile, 'w') as outfile:
            json.dump(self.jsondict, outfile, indent=4)

        print("SIMPLE MEASUREMENT - DONE ARCHIVING" + "\n")
        self.status_archive_results = 1
class FEMB_TEST_GAIN(object):

    def __init__(self, datadir="data", outlabel="gainMeasurement",fembNum=0):
        #set internal variables
        self.datadir = datadir
        self.outlabel = outlabel + str("_femb_") + str(fembNum)
        self.outpathlabel = os.path.join(self.datadir, self.outlabel)
        self.fembNum = int(fembNum)

        print( "FEMB # " + str(fembNum) )

        #import femb_udp modules from femb_udp package
        self.femb_config = CONFIG()
        self.write_data = WRITE_DATA(self.datadir)
        #set appropriate packet size
        self.write_data.femb.MAX_PACKET_SIZE = 8000
        self.cppfr = CPP_FILE_RUNNER()
	
        #set status variables
        self.status_check_setup = 0
        self.status_record_data = 0
        self.status_do_analysis = 0
        self.status_archive_results = 0

        #misc variables
        self.gain = 0
        self.shape = 0
        self.base = 0
        self.leakage = 0
        self.leakagex10 = 0
        self.buffer = 0
        self.acdc = 0
        self.useInternalPulser = False
        self.useExtAdcClock = False
        self.isRoomTemp = False

        #json output, note module version number defined here
        self.jsondict = {'type':'fembTest_gain'}
        self.jsondict['version'] = '1.0'
        self.jsondict['timestamp']  = str(self.write_data.date)

    def check_setup(self):
        #CHECK STATUS AND INITIALIZATION
        print("GAIN MEASUREMENT - CHECKING READOUT STATUS")
        self.status_check_setup = 0

        #make sure output directory exists
        self.write_data.assure_filedir()

        #check if register interface is working
        print("Checking register interface")
        regVal = self.femb_config.femb.read_reg(6)
        if (regVal == None):
            print("Error running doFembTest - FEMB register interface is not working.")
            print(" Turn on or debug FEMB UDP readout.")       
            return
        if ( regVal < 0 ):
            print("Error running doFembTest - FEMB register interface is not working.")
            print(" Turn on or debug FEMB UDP readout.")       
            return
        print("Read register 6, value = " + str( hex( regVal ) ) )

        #check that femb number is valid
        if ( int(self.fembNum) < 0 ) or ( int( self.fembNum) >= self.femb_config.NFEMBS ):
            print("Error running doFembTest - Invalid FEMB # specified.")
            return    

        #assign FEMB # to test 
        self.femb_config.selectFemb(self.fembNum)

        #initialize FEMB to known state
        print("Initializing board")
        self.femb_config.feasicGain = self.gain
        self.femb_config.feasicShape = self.shape
        self.femb_config.feasicBaseline = self.base
        self.femb_config.feasicLeakageVal = self.leakage
        self.femb_config.feasicLeakagex10Val = self.leakagex10
        self.femb_config.bufVal = self.buffer
        self.femb_config.acdcVal = self.acdc
        self.femb_config.feasicEnableTestInput = 0 #important
        self.femb_config.useExtAdcClock = self.useExtAdcClock
        self.femb_config.isRoomTemp = self.isRoomTemp
        #self.femb_config.printParameters()
        self.femb_config.initFemb()

        #test firmware versions
        if self.femb_config.checkFirmwareVersion() == False:
            print('Error running doFembTest - Invalid firmware and/or register read error')
            return

        #check if data streaming is working
        print("Checking data streaming")
        testData = self.write_data.femb.get_data_packets(1)
        if testData == None:
            print("Error running doFembTest - FEMB is not streaming data.")
            print(" Turn on and initialize FEMB UDP readout.")
            return
        if len(testData) == 0:
            print("Error running doFembTest - FEMB is not streaming data.")
            print(" Turn on and initialize FEMB UDP readout.")
            return

        print("Received data packet " + str(len(testData[0])) + " bytes long")

        #check for analysis executables
        if not self.cppfr.exists('test_measurements/fembTest/code/parseBinaryFile'):    
            print('parseBinaryFile not found, run setup.sh')
            return

        print("GAIN MEASUREMENT - READOUT STATUS OK" + "\n")
        self.status_check_setup = 1

    def record_data(self):
        if self.status_check_setup == 0:
            print("Please run check_setup method before trying to take data")
            return
        if self.status_record_data == 1:
            print("Data already recorded. Reset/restat GUI to begin a new measurement")
            return

        #MEASUREMENT SECTION
        print("GAIN MEASUREMENT - RECORDING DATA")

        #wait to make sure HS link is back on after check_setup
        sleep(5)

        #setup output file
        self.write_data.filename = self.outlabel+".bin"
        print("Recording " + self.write_data.filename )

        isOpen = self.write_data.open_file()
        if isOpen == 0 :
            print( "Error running doFembTest - Could not open output data file for writing, ending test" )
        subrun = 0

        #config FE ASICs
        print("FE ASIC Settings: Gain " + str(self.gain) + ", Shaping Time " + str(self.shape) + ", Baseline " + str(self.base) )
        print("FE ASIC Settings: Leakage Current " + str(self.leakage) + ", Leakage x10 " + str(self.leakagex10) )
        print("FE ASIC Settings: Output Buffer " + str(self.buffer) + ", AC/DC " + str(self.acdc) )
        self.femb_config.feasicGain = self.gain
        self.femb_config.feasicShape = self.shape
        self.femb_config.feasicBaseline = self.base
        self.femb_config.feasicLeakageVal = self.leakage
        self.femb_config.feasicLeakagex10Val = self.leakagex10
        self.femb_config.bufVal = self.buffer
        self.femb_config.acdcVal = self.acdc
        self.femb_config.feasicEnableTestInput = 0 #important
        self.femb_config.useExtAdcClock = self.useExtAdcClock
        self.femb_config.isRoomTemp = self.isRoomTemp
        self.femb_config.configFeAsic()

        #disable pulsers
        self.femb_config.setInternalPulser(0,0x0)
        self.femb_config.setFpgaPulser(0,0x0)

        self.femb_config.printParameters()

        #record data
        self.write_data.numpacketsrecord = 500
        self.write_data.run = 0
        self.write_data.runtype = 0
        self.write_data.runversion = 0

        #take initial noise data run
        subrun = 0
        asicCh = 0
        for asic in range(0,self.femb_config.NASICS,1):
          self.femb_config.selectChannel(asic,asicCh)
          self.write_data.record_data(subrun, asic, asicCh)

        #turn ASIC test input on, start pulser section
        self.femb_config.feasicEnableTestInput = 1
        self.femb_config.configFeAsic()
        if self.useInternalPulser == False :
            self.femb_config.setFpgaPulser(1,0)
        else:
            self.femb_config.setInternalPulser(1,0)
        subrun = 1

        #loop over pulser configurations, each configuration is it's own subrun
        for p in range(0,10,1):
            pVal = int(p)
            if self.useInternalPulser == False :
                self.femb_config.setFpgaPulser(1,pVal)
            else:
                self.femb_config.setInternalPulser(1,pVal)
            print("Pulse amplitude " + str(pVal) )

            #loop over channels
            for asic in range(0,8,1):
                self.femb_config.selectChannel(asic,asicCh)
                self.write_data.record_data(subrun, asic, asicCh)

            #increment subrun, important
            subrun = subrun + 1

        #close file
        self.write_data.close_file()

        #turn off FEMB
        self.femb_config.powerOffFemb(self.fembNum)

        print("GAIN MEASUREMENT - DONE RECORDING DATA" + "\n")
        self.status_record_data = 1

    def do_analysis(self):
        if self.status_record_data == 0:
            print("Please record data before analysis")
            return
        if self.status_do_analysis == 1:
            print("Analysis already complete")
            return
        #ANALYSIS SECTION
        print("GAIN MEASUREMENT - ANALYZING AND SUMMARIZING DATA")

        #parse binary
        self.cppfr.run("test_measurements/fembTest/code/parseBinaryFile", [self.write_data.data_file_path])

        #run analysis program
        parseBinaryFile = self.outpathlabel + "-parseBinaryFile.root"
        call(["mv", "output_parseBinaryFile.root" , parseBinaryFile])
        if self.useInternalPulser == False : 
            self.cppfr.run("test_measurements/fembTest/code/processNtuple_gainMeasurement",  [parseBinaryFile])
        else :
            self.cppfr.run("test_measurements/fembTest/code/processNtuple_gainMeasurement",  [parseBinaryFile,"1"])

        processNtupleFile = self.outpathlabel + "-processNtupleFile.root"
        call(["mv", "output_processNtuple_gainMeasurement.root" , processNtupleFile])

        summaryPlot = self.outpathlabel + "-summaryPlot.png"
        call(["mv", "summaryPlot_gainMeasurement.png" , summaryPlot])

        resultsFile = self.outpathlabel + "-results.list"
        call(["mv", "output_processNtuple_gainMeasurement.list" , resultsFile])

        print("GAIN MEASUREMENT - DONE ANALYZING AND SUMMARIZING DATA" + "\n")
        self.status_do_analysis = 1

    def archive_results(self):
        #if self.status_check_setup == 0 :
        #     print("Check setup status is 0, not archiving data")
        #     return
        #if self.status_do_analysis == 0:
        #    print("Please analyze data before archiving results")
        #    return
        if self.status_archive_results == 1:
            print("Results already archived")
            return
        #ARCHIVE SECTION
        print("GAIN MEASUREMENT - ARCHIVE")

        #add summary variables to output
        self.jsondict['status_check_setup'] = str(self.status_check_setup)
        self.jsondict['status_record_data'] = str(self.status_record_data)
        self.jsondict['status_do_analysis'] = str(self.status_do_analysis)
        self.jsondict['status_archive_results'] = str(1)
        self.jsondict['filedir'] = str(self.write_data.filedir )
        self.jsondict['config_gain'] = str(self.gain)
        self.jsondict['config_shape'] = str(self.shape)
        self.jsondict['config_base'] = str(self.base)
        self.jsondict['useInternalPulser'] = str(self.useInternalPulser)
        self.jsondict['syncStatus'] = str(self.femb_config.syncStatus)

        if self.status_do_analysis == 1:
          #parse the output results, kind of messy
          listFile = self.outpathlabel + "-results.list"

          lines = []
          with open( listFile ) as infile:
            for line in infile:
                line = line.strip('\n')
                line = line.split(',') #measurements separated by commas
                parseline = {}
                for n in range(0,len(line),1):
                    word = line[n].split(' ')
                    if( len(word) != 2 ):
                        continue
                    parseline[ str(word[0]) ] = str(word[1])
                lines.append(parseline)
            self.jsondict['results'] = lines

        #dump results into json
        jsonFile = self.outpathlabel + "-results.json"
        with open( jsonFile , 'w') as outfile:
            json.dump( self.jsondict, outfile, indent=4)

        print("GAIN MEASUREMENT - DONE STORING RESULTS IN DATABASE" + "\n")
        self.status_archive_results = 1
class QUADADC_TEST_FUNCGEN(object):
    def __init__(self,
                 datadir="data",
                 outlabel="funcgenMeasurement",
                 asicnum=0,
                 doReconfig=True,
                 isExternalClock=True,
                 is1MHzSAMPLERATE=True,
                 isCold=False):
        #set internal variables
        self.datadir = datadir
        self.outlabel = outlabel + str("_asic_") + str(asicnum)
        self.outpathlabel = os.path.join(self.datadir, self.outlabel)
        self.asicnum = int(asicnum)

        print("Test type\t" + str(self.outlabel))
        print("Data path\t" + str(datadir))
        print("ASIC socket #\t" + str(self.asicnum))

        #import femb_udp modules from femb_udp package
        self.femb_config = CONFIG()
        self.write_data = WRITE_DATA(datadir)
        self.cppfr = CPP_FILE_RUNNER()
        self.funcgen = Keysight_33600A("/dev/usbtmc0",
                                       1)  #hardcoded to usbtmc0

        #set appropriate UDP packet size
        self.write_data.femb.MAX_PACKET_SIZE = 8000  #should be larger than largest expected packet size

        #set test module status variables
        self.status_check_setup = 0
        self.status_record_data = 0
        self.status_do_analysis = 0
        self.status_archive_results = 0

        #assign input to test and config module internal variables
        self.doReconfig = doReconfig
        self.isExternalClock = isExternalClock
        self.is1MHzSAMPLERATE = is1MHzSAMPLERATE
        self.isCold = isCold
        self.femb_config.isExternalClock = self.isExternalClock  #False = internal monostable, True = external
        self.femb_config.is1MHzSAMPLERATE = self.is1MHzSAMPLERATE  #False = 1MHz, True = 2MHz
        self.femb_config.COLD = self.isCold

        #define json output
        self.jsondict = {'type': 'quadAdcTest_funcgen'}
        #self.jsondict['version'] = '1.0'
        self.jsondict['timestamp'] = str(self.write_data.date)
        self.jsondict['asicnum'] = str(self.asicnum)
        self.jsondict['doreconfig'] = str(self.doReconfig)
        self.jsondict['extclock'] = str(self.isExternalClock)
        self.jsondict['is1MHz'] = str(self.is1MHzSAMPLERATE)
        self.jsondict['iscold'] = str(self.isCold)

    def check_setup(self):
        #CHECK STATUS AND INITIALIZATION
        print("FUNCTION GENERATOR MEASUREMENT - CHECKING READOUT STATUS")
        self.status_check_setup = 0

        #make sure output directory exists (should catch permissions issues etc)
        isDir = self.write_data.assure_filedir()
        if isDir == None:
            print("Error running test - Output data directory note created.")
            return

        #check if register interface is working
        print("Checking register interface")
        regVal = self.femb_config.femb.read_reg(
            self.femb_config.REG_FIRMWARE_VERSION)
        if (regVal == None):
            print("Error running test - register interface is not working.")
            print(" Turn on or debug UDP readout.")
            return
        if (regVal < 0):
            print("Error running test - register interface is not working.")
            print(" Turn on or debug UDP readout.")
            return
        print("Read register 6, value = " + str(hex(regVal)))

        #check for any problems in input variables
        #check that input ASIC # is correct
        if self.asicnum == None:
            print(
                "Error running test - Invalid ASIC socket # specified, ending test"
            )
            return
        if (self.asicnum < 0) or (self.asicnum > self.femb_config.NASICS):
            print(
                "Error running test - Invalid ASIC socket # specified, ending test"
            )
            return

        #initialize readout to known working state
        #initialization may identify problem that cancels test
        if self.doReconfig == True:
            print("Initializing board")
            initStatus = self.femb_config.initBoard()
            if initStatus == False:
                print(
                    "Error running test - Could not initialize board, ending test"
                )
                return
            initStatus = self.femb_config.initAsic(self.asicnum)
            if initStatus == False:
                print(
                    "Error running test - Could not initialize ASIC, ending test"
                )
                return

        #firmware version check should be done in initialize, otherwise do here
        #if self.femb_config.checkFirmwareVersion() == False:
        #    print('Error running doFembTest - Invalid firmware and/or register read error')
        #    return

        #check if data streaming is working, assume it's ON after board + ASIC initialize
        print("Checking data streaming")
        testData = self.write_data.femb.get_data_packets(1)
        if testData == None:
            print("Error running test - board is not streaming data.")
            print(" Turn on and initialize FEMB UDP readout.")
            return
        if len(testData) == 0:
            print("Error running test - board is not streaming data.")
            print(" Turn on and initialize FEMB UDP readout.")
            return

        print("Received data packet " + str(len(testData[0])) + " bytes long")

        #check for analysis executables
        if not self.cppfr.exists(
                'test_measurements/quadAdcTester/code/parseBinaryFile'):
            print(
                'Error running test - parseBinaryFile executable not found, run setup.sh'
            )
            return
        #if not self.cppfr.exists('test_measurements/quadAdcTester/code/processNtuple_funcgenMeasurement'):
        #    print('Error running test - processNtuple_funcgenMeasurement executable not found, run setup.sh')
        #    return

        #Setup is ok
        print("FUNCTION GENERATOR MEASUREMENT - READOUT STATUS OK" + "\n")
        self.status_check_setup = 1

    def record_data(self):
        if self.status_check_setup == 0:
            print(
                "Error running test - Please run check_setup method before trying to take data"
            )
            return
        if self.status_record_data == 1:
            print(
                "Error running test - Data already recorded. Reset/restat GUI to begin a new measurement"
            )
            return

        #MEASUREMENT SECTION
        print("FUNCTION GENERATOR MEASUREMENT - RECORDING DATA")

        #wait to make sure HS link is back on after check_setup function
        sleep(1.)

        #enable external signal input
        self.femb_config.setFPGADac(0, 1, 0, 0)  # write regs 4 and 5

        #print config parameters just before data taking
        self.femb_config.printParameters()

        #data recording parameters
        self.write_data.run = 0
        self.write_data.runtype = 0
        self.write_data.runversion = 0

        #setup output file and record data
        self.write_data.filename = self.outlabel + ".bin"
        print("Recording " + self.write_data.filename)
        isOpen = self.write_data.open_file()
        if isOpen == 0:
            print(
                "Error running test - Could not open output data file for writing, ending test"
            )

        #speicify ASIC
        asic = self.asicnum
        asicCh = 0
        self.femb_config.selectAsic(asic)

        #initialize function generator parameters
        xLow = -0.3
        xHigh = 1.7
        offsetV = (xLow + xHigh) * 0.5
        amplitudeV = (xHigh - xLow) * 0.5
        settlingTime = 0.1

        #take a bunch of function generator data in sequence and stick it all in the same output file

        #long ramp
        subrun = 0
        freq = 4
        self.funcgen.startRamp(freq, xLow, xHigh)
        sleep(settlingTime)
        self.write_data.numpacketsrecord = 20000  #long
        self.write_data.record_data(subrun, asic, asicCh)

        #short ramp
        subrun = subrun + 1
        freq = 734
        self.funcgen.startRamp(freq, xLow, xHigh)
        sleep(settlingTime)
        self.write_data.numpacketsrecord = 1600
        self.write_data.record_data(subrun, asic, asicCh)

        #DC [0.2,0.5,1.,1.6]
        for dc in [0.2, 0.5, 1., 1.6]:
            subrun = subrun + 1
            self.funcgen.startDC(dc)
            sleep(settlingTime)
            self.write_data.numpacketsrecord = 160
            self.write_data.record_data(subrun, asic, asicCh)

        #SINE [6.2365e4,4.83587e5,9.515125e5]
        for freq in [6.2365e4, 4.83587e5, 9.515125e5]:
            subrun = subrun + 1
            self.funcgen.startSin(freq, amplitudeV, offsetV)
            sleep(settlingTime)
            self.write_data.numpacketsrecord = 1600
            self.write_data.record_data(subrun, asic, asicCh)

        #done taking data
        self.write_data.close_file()

        #Power off ASIC
        #self.femb_config.turnOffAsics()

        #disable external signal input
        self.femb_config.setFPGADac(0, 0, 0, 0)  # write regs 4 and 5

        #turn off function generator
        sleep(1)
        self.funcgen.stop()
        sleep(1)

        print("FUNCTION GENERATOR MEASUREMENT - DONE RECORDING DATA" + "\n")
        self.status_record_data = 1

    def do_analysis(self):
        if self.status_record_data == 0:
            print("Error running test - Please record data before analysis")
            return
        if self.status_do_analysis == 1:
            print("Error running test - Analysis already complete")
            return

        #ANALYSIS SECTION
        print(
            "FUNCTION GENERATOR MEASUREMENT - ANALYZING AND SUMMARIZING DATA")

        #parse binary
        self.cppfr.run("test_measurements/quadAdcTester/code/parseBinaryFile",
                       [self.write_data.data_file_path])

        #check for parsed file here
        if os.path.isfile("output_parseBinaryFile.root") == False:
            print("Error running test - parsed data file not found.")
            return

        #run analysis program
        parseBinaryFile = "output_parseBinaryFile.root"
        #self.cppfr.run("test_measurements/quadAdcTester/code/processNtuple_funcgenMeasurement",  [parseBinaryFile])

        #check for online analysis result files here
        #if os.path.isfile( "output_processNtuple_funcgenMeasurement.root" ) == False:
        #    print("Error running test - parsed data file not found.")
        #    return

        #update output file names
        parseBinaryFile = self.outpathlabel + "-parseBinaryFile.root"
        call(["mv", "output_parseBinaryFile.root", parseBinaryFile])

        #processNtupleFile = self.outpathlabel + "-processNtupleFile.root"
        #call(["mv", "output_processNtuple_funcgenMeasurement.root" , processNtupleFile])

        #summaryPlot = self.outpathlabel + "-summaryPlot.png"
        #call(["mv", "summaryPlot_funcgenMeasurement.png" , summaryPlot])

        print(
            "FUNCTION GENERATOR MEASUREMENT - DONE ANALYZING AND SUMMARIZING DATA"
            + "\n")
        self.status_do_analysis = 1

    def archive_results(self):
        #NOTE: GENERALLY ALLOW ARCHIVE PROCESS TO RUN EVEN IF OTHER STEPS FAIL
        #if self.status_check_setup == 0 :
        #     print("Check setup status is 0, not archiving data")
        #     return
        #if self.status_do_analysis == 0:
        #    print("Please analyze data before archiving results")
        #    return
        if self.status_archive_results == 1:
            print("Error running test - Results already archived")
            return
        #ARCHIVE SECTION
        print("FUNCTION GENERATOR MEASUREMENT - ARCHIVE")

        #add summary variables to output
        self.jsondict['filedir'] = str(self.write_data.filedir)
        self.jsondict['status_check_setup'] = str(self.status_check_setup)
        self.jsondict['status_record_data'] = str(self.status_record_data)
        self.jsondict['status_do_analysis'] = str(self.status_do_analysis)
        self.jsondict['status_archive_results'] = str(1)

        #dump results into json
        jsonFile = self.outpathlabel + "-results.json"
        with open(jsonFile, 'w') as outfile:
            json.dump(self.jsondict, outfile, indent=4)

        print("FUNCTION GENERATOR MEASUREMENT - DONE ARCHIVING" + "\n")
        self.status_archive_results = 1