示例#1
0
 def __init__(self):
     self.config = CONFIG
     self.functions = FEMB_CONFIG_BASE(self.config)
     self.low_level = self.functions.lower_functions
     self.analyze = Data_Analysis(self.config)
     
     #json output, note module version number defined here
     self.jsondict = {'type':'baseline_test'}
     self.jsondict['monitor_code_version'] = '1.1'
     self.jsondict['monitor_timestamp']  = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
示例#2
0
    def __init__(self):

        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        self.low_level = self.functions.lower_functions
        self.sync_functions = self.functions.sync
        self.plotting = self.functions.sync.plot

        #json output, note module version number defined here
        self.syncdict = {'type': 'sync_adcs'}
        self.syncdict['sync_code_version'] = '1.1'
        self.syncdict['sync_timestamp'] = datetime.datetime.today().strftime(
            '%Y%m%d%H%M%S')
示例#3
0
class MONITOR_TESTER(object):
    
    def __init__(self):
        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        self.low_level = self.functions.lower_functions
        self.analyze = Data_Analysis(self.config)
        
        #json output, note module version number defined here
        self.jsondict = {'type':'baseline_test'}
        self.jsondict['monitor_code_version'] = '1.1'
        self.jsondict['monitor_timestamp']  = datetime.datetime.today().strftime('%Y%m%d%H%M%S')

        
    def check_setup(self):
        print("MONITOR - SETUP")
        self.functions.initBoard(default_sync = False)
        if (self.params['using_power_supply'] == True):
            self.PowerSupply = Power_Supply(self.config)
            if (self.PowerSupply.interface == None):
                sys.exit("SYNCHRONIZATION --> Power Supply not found!")      

    def record_data(self):
        print("MONITOR - COLLECT DATA")
        #Read from TEST output ADCs
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_READOUT_OPTIONS"]), int(self.config["DEFINITIONS"]["READOUT_TEST_ADC"]))
        
        #Select the monitor readout to ADC
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_MUX_MODE"]), int(self.config["DEFINITIONS"]["MUX_ADC_GND"]))
        #Adds tracer bits on data coming in when the internal pulser has an edge
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_TAGGING"]), int(self.config["DEFINITIONS"]["TAGGING_ON"]))
        
        #Get the ASIC to send out pulses
        self.low_level.setInternalPulser(period = int(self.config["MONITOR_SETTINGS"]["MONITOR_FREQ"]), shift = int(self.config["MONITOR_SETTINGS"]["MONITOR_DLY"]), enable = True)
        self.low_level.setExternalPulser(enable = False)
        self.power_info_total = []
        for i in self.params['working_chips']:
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name, self.params["outlabel"])
            data_directory = os.path.join(chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
            os.makedirs(data_directory, exist_ok=True)
            
            for chn in range(int(self.config["DEFAULT"]["NASICCH_MIN"]), int(self.config["DEFAULT"]["NASICCH_MAX"]) + 1, 1):
                self.functions.configFeAsic(test_cap="on", base=self.config["SYNC_SETTINGS"]["SYNC_BASELINE"], gain=self.config["SYNC_SETTINGS"]["SYNC_GAIN"], shape=self.config["SYNC_SETTINGS"]["SYNC_PEAK"], 
                                    monitor_ch=None, buffer=self.config["SYNC_SETTINGS"]["SYNC_BUFFER"], leak = self.config["SYNC_SETTINGS"]["SYNC_LEAK"], monitor_param = None, s16=None, 
                                    acdc=self.config["SYNC_SETTINGS"]["SYNC_ACDC"], test_dac="test_int", dac_value=int(self.config["MONITOR_SETTINGS"]["MONITOR_AMPL"]))
                self.functions.FE_Regs.set_fe_chn(chip = i, chn = chn, smn = 1)
                self.functions.writeFE()
                
                monitor_file_notation = self.config["FILENAMES"]["MONITOR_NAMING"]
                filename = monitor_file_notation.format(chn)
                full_filename = os.path.join(data_directory,filename)            
                packets = int(self.config["MONITOR_SETTINGS"]["MONITOR_PACKETS"])
                data = self.low_level.get_data_chipXchnX_tagged(chip = i, chn = chn, packets = packets, data_format = "bin", header = False)
                buffer = len(data)
                bin_data = struct.pack(">%dH"%buffer, *data)
                
                with open(full_filename,"wb") as f:
                    f.write(bin_data) 
                    f.close()
                    
            power_info = self.functions.PCB_power_monitor(chips = i)
            self.power_info_total.append(power_info)
            
        if (self.params['using_power_supply'] == True):   
            pwr = self.config["POWER_SUPPLY"]
            self.heating_results = self.PowerSupply.measure_params(channel = int(pwr["PS_HEATING_CHN"]))
            self.quad_results = self.PowerSupply.measure_params(channel = int(pwr["PS_QUAD_CHN"]))
            self.fpga_results = self.PowerSupply.measure_params(channel = int(pwr["PS_FPGA_CHN"]))
                    
        #Bring things back to normal
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_READOUT_OPTIONS"]), int(self.config["DEFINITIONS"]["READOUT_NORMAL"]))
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_TAGGING"]), int(self.config["DEFINITIONS"]["TAGGING_OFF"]))
        self.low_level.setInternalPulser(period = int(self.config["SYNC_SETTINGS"]["SYNC_INTERNAL_PULSE_FREQ"]), shift = int(self.config["SYNC_SETTINGS"]["SYNC_INTERNAL_PULSE_DLY"]), enable = False)

    def do_analysis(self):
        print("MONITOR - ANALYZE")
        self.results = []
        self.peaks = []
        self.differences = []
        self.average_peak = []
        for i in self.params["working_chips"]:
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name, self.params["outlabel"])
            data_directory = os.path.join(chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
            #To grab baseline
            jsonFile = os.path.join(self.params["datadir"],chip_name,self.params["datasubdir"],self.config["FILENAMES"]["RESULTS"])
            with open(jsonFile,'r') as f:
                existing_json = json.load(f)
            baseline_outlabel = existing_json["baseline_outlabel"]
            jsonFile = os.path.join(self.params["datadir"],chip_name,self.params["datasubdir"],baseline_outlabel, self.config["FILENAMES"]["RESULTS"])
            
            result, peaks, differences, average_peak = self.analyze.monitor_directory(chip_outpathlabel, data_directory, chip_name, i, jsonFile)
            self.results.append(result)
            self.peaks.append(peaks)
            self.differences.append(differences)
            self.average_peak.append(average_peak)
        
    def archiveResults(self):
        print("MONITOR - ARCHIVE")
        
        self.jsondict['monitor_executable'] = self.params['executable']
        self.jsondict['monitor_datasubdir'] = self.params['datasubdir']
        self.jsondict['monitor_outlabel'] = self.params['outlabel']
        
        if (self.params['using_power_supply'] == True):  
            self.jsondict['PS_heating_voltage'] = self.heating_results[0]
            self.jsondict['PS_heating_current'] = self.heating_results[1]
            self.jsondict['PS_quad_voltage'] = self.quad_results[0]
            self.jsondict['PS_quad_current'] = self.quad_results[1]
            self.jsondict['PS_fpga_voltage'] = self.fpga_results[0]
            self.jsondict['PS_fpga_current'] = self.fpga_results[1]

        for num, i in enumerate(self.params['working_chips']):
            chip_name = self.params['chip_list'][i][1]
            jsonFile = os.path.join(self.params["datadir"],chip_name,self.params["datasubdir"],self.params["outlabel"], self.config["FILENAMES"]["RESULTS"])
            if (self.results[num] == True):
                self.jsondict['monitor_result'] = "PASS"
            elif (self.results[num] == False):
                self.jsondict['monitor_result'] = "FAIL"
            else:
                self.jsondict['monitor_result'] = "N/A"
                
            self.jsondict['monitor_average_peak'] = self.average_peak[num]
            self.jsondict['vdda_shunt_voltage'] = self.power_info_total[num][0][0]
            self.jsondict['vdda_bus_voltage'] = self.power_info_total[num][0][1]
            self.jsondict['vdda_current'] = self.power_info_total[num][0][2]
            self.jsondict['vddp_shunt_voltage'] = self.power_info_total[num][1][0]
            self.jsondict['vddp_bus_voltage'] = self.power_info_total[num][1][1]
            self.jsondict['vddp_current'] = self.power_info_total[num][1][2]
            
            for chn in range(int(self.config["DEFAULT"]["NASICCH_MIN"]), int(self.config["DEFAULT"]["NASICCH_MAX"]) + 1, 1):
                jsname = "monitor_peak{}".format(chn)
                self.jsondict[jsname] = self.peaks[num][chn][1]
                jsname = "monitor_difference{}".format(chn)
                self.jsondict[jsname] = self.differences[num][chn]
                
            with open(jsonFile,'a') as outfile:
                json.dump(self.jsondict, outfile, indent=4)        
                
            jsonFile = os.path.join(self.params["datadir"],chip_name,self.params["datasubdir"],self.config["FILENAMES"]["RESULTS"])
            with open(jsonFile,'r') as f:
                existing_json = json.load(f)
            
            existing_json['monitor_outlabel'] = self.params['outlabel']
            with open(jsonFile,'w') as outfile:
                json.dump(existing_json, outfile, indent=4)
示例#4
0
    def __init__(self, master=None):

        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        #Gets the low level module to do UDP packets
        self.femb = self.functions.lower_functions
        self.master = master

        self.functions.configFeAsic(
            test_cap="on",
            base=self.config["SYNC_SETTINGS"]["SYNC_BASELINE"],
            gain=self.config["SYNC_SETTINGS"]["SYNC_GAIN"],
            shape=self.config["SYNC_SETTINGS"]["SYNC_PEAK"],
            monitor_ch=None,
            buffer=self.config["SYNC_SETTINGS"]["SYNC_BUFFER"],
            leak=self.config["SYNC_SETTINGS"]["SYNC_LEAK"],
            monitor_param=None,
            s16=None,
            acdc=self.config["SYNC_SETTINGS"]["SYNC_ACDC"],
            test_dac="test_int",
            dac_value=int(
                self.config["SYNC_SETTINGS"]["SYNC_DAC_PEAK_HEIGHT"]))
        self.functions.writeFE()
        #Creates Tkinter object
        Tk.Frame.__init__(self, master)  # hack to make work in python2
        self.pack()
        #Creates Matplotlib object
        self.figure = Figure(figsize=(20, 7), dpi=100, facecolor='white')
        self.canvas = FigureCanvas(self.figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        #Create toolbar for bottom
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.update()

        self.pauseButton = Tk.Button(self, text="Pause", command=self.pause)
        self.pauseButton.pack(side=Tk.LEFT)

        self.playButton = Tk.Button(self,
                                    text="Play",
                                    command=self.play,
                                    state=Tk.DISABLED)
        self.playButton.pack(side=Tk.LEFT)

        pulse_options = ["None", "Internal Pulse", "External Pulse"]
        self.pulse_entry_choices = Tk.StringVar(self.master,
                                                name="pulse_entry")
        self.pulse_entry_choices.set(pulse_options[0])  # initial value
        self.pulse_entry_choices.trace("w", self.gui_callback)

        self.pulse_entry = Tk.OptionMenu(self, self.pulse_entry_choices,
                                         *pulse_options)
        self.pulse_entry.pack(side=Tk.LEFT)

        self.chip = 0
        chip_options = []
        for i in range(int(self.config["DEFAULT"]["NASICS"])):
            chip_options.append("Chip {}".format(i))

        self.chip_entry_choices = Tk.StringVar(self.master, name="chip_entry")
        self.chip_entry_choices.set(chip_options[0])  # initial value
        self.chip_entry_choices.trace("w", self.gui_callback)

        self.chip_entry = Tk.OptionMenu(self, self.chip_entry_choices,
                                        *chip_options)
        self.chip_entry.pack(side=Tk.LEFT)

        self.packets = 2
        self.packet_label = Tk.Label(self, text="Packet Length:", width=11)
        self.packet_label.pack(side=Tk.LEFT)
        self.packet_entry = Tk.Spinbox(self,
                                       width=5,
                                       from_=1,
                                       to=100,
                                       name="patcket_entry",
                                       command=self.packet_change)
        self.packet_entry.delete(0, "end")
        self.packet_entry.insert(0, self.packets)
        self.packet_entry.pack(side=Tk.LEFT)

        self.manualSyncButton = Tk.Button(self,
                                          text="Manual Sync",
                                          command=self.manualSync)
        self.manualSyncButton.pack(side=Tk.LEFT)

        self.reset()
示例#5
0
class TRACE_VIEWER(Tk.Frame):
    """
  This window displays a live ADC readout
  """
    def __init__(self, master=None):

        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        #Gets the low level module to do UDP packets
        self.femb = self.functions.lower_functions
        self.master = master

        self.functions.configFeAsic(
            test_cap="on",
            base=self.config["SYNC_SETTINGS"]["SYNC_BASELINE"],
            gain=self.config["SYNC_SETTINGS"]["SYNC_GAIN"],
            shape=self.config["SYNC_SETTINGS"]["SYNC_PEAK"],
            monitor_ch=None,
            buffer=self.config["SYNC_SETTINGS"]["SYNC_BUFFER"],
            leak=self.config["SYNC_SETTINGS"]["SYNC_LEAK"],
            monitor_param=None,
            s16=None,
            acdc=self.config["SYNC_SETTINGS"]["SYNC_ACDC"],
            test_dac="test_int",
            dac_value=int(
                self.config["SYNC_SETTINGS"]["SYNC_DAC_PEAK_HEIGHT"]))
        self.functions.writeFE()
        #Creates Tkinter object
        Tk.Frame.__init__(self, master)  # hack to make work in python2
        self.pack()
        #Creates Matplotlib object
        self.figure = Figure(figsize=(20, 7), dpi=100, facecolor='white')
        self.canvas = FigureCanvas(self.figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        #Create toolbar for bottom
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.update()

        self.pauseButton = Tk.Button(self, text="Pause", command=self.pause)
        self.pauseButton.pack(side=Tk.LEFT)

        self.playButton = Tk.Button(self,
                                    text="Play",
                                    command=self.play,
                                    state=Tk.DISABLED)
        self.playButton.pack(side=Tk.LEFT)

        pulse_options = ["None", "Internal Pulse", "External Pulse"]
        self.pulse_entry_choices = Tk.StringVar(self.master,
                                                name="pulse_entry")
        self.pulse_entry_choices.set(pulse_options[0])  # initial value
        self.pulse_entry_choices.trace("w", self.gui_callback)

        self.pulse_entry = Tk.OptionMenu(self, self.pulse_entry_choices,
                                         *pulse_options)
        self.pulse_entry.pack(side=Tk.LEFT)

        self.chip = 0
        chip_options = []
        for i in range(int(self.config["DEFAULT"]["NASICS"])):
            chip_options.append("Chip {}".format(i))

        self.chip_entry_choices = Tk.StringVar(self.master, name="chip_entry")
        self.chip_entry_choices.set(chip_options[0])  # initial value
        self.chip_entry_choices.trace("w", self.gui_callback)

        self.chip_entry = Tk.OptionMenu(self, self.chip_entry_choices,
                                        *chip_options)
        self.chip_entry.pack(side=Tk.LEFT)

        self.packets = 2
        self.packet_label = Tk.Label(self, text="Packet Length:", width=11)
        self.packet_label.pack(side=Tk.LEFT)
        self.packet_entry = Tk.Spinbox(self,
                                       width=5,
                                       from_=1,
                                       to=100,
                                       name="patcket_entry",
                                       command=self.packet_change)
        self.packet_entry.delete(0, "end")
        self.packet_entry.insert(0, self.packets)
        self.packet_entry.pack(side=Tk.LEFT)

        self.manualSyncButton = Tk.Button(self,
                                          text="Manual Sync",
                                          command=self.manualSync)
        self.manualSyncButton.pack(side=Tk.LEFT)

        self.reset()

    def reset(self):
        self.figure.clf()
        self.subgs = [None] * 16
        self.ax = [None] * 16
        self.plot = [None] * 16

        self.figure.text(0.5,
                         0.02,
                         'Time [us]',
                         ha='center',
                         color='black',
                         fontsize='25.0',
                         weight='bold')
        self.figure.text(0.08,
                         0.625,
                         'ADC counts',
                         ha='center',
                         rotation=90,
                         color='black',
                         fontsize='25.0',
                         weight='bold')

        # 4x4 grid, one cell per channel
        self.gs = gridspec.GridSpec(4, 4)
        self.gs.update(wspace=0.2, hspace=0.2)
        # 1 plots per channel, create axes objects
        for row in range(4):
            for col in range(4):
                ch = col + 4 * row
                self.subgs[ch] = gridspec.GridSpecFromSubplotSpec(
                    1, 1, subplot_spec=self.gs[ch], hspace=0.0)
                self.ax[ch] = self.figure.add_subplot(self.subgs[ch][0])
                self.ax[ch].tick_params(axis='x',
                                        colors='black',
                                        labelsize='medium')
                self.ax[ch].tick_params(axis='y',
                                        colors='black',
                                        labelsize='smaller')

        #Continually updates by calling self.plotData
        self.ani = animation.FuncAnimation(self.figure,
                                           self.plotData,
                                           interval=1000,
                                           blit=True)
        self.canvas.draw()

    def packet_change(self):
        self.packets = int(self.packet_entry.get())

    def gui_callback(self, *args, **kwargs):
        if (args[0] == "pulse_entry"):
            if (self.pulse_entry_choices.get() == "None"):
                self.femb.femb_udp.write_reg(
                    int(self.config["REGISTERS"]["REG_MUX_MODE"]),
                    int(self.config["DEFINITIONS"]["MUX_GND_GND"]))
            elif (self.pulse_entry_choices.get() == "Internal Pulse"):
                self.femb.femb_udp.write_reg(
                    int(self.config["REGISTERS"]["REG_MUX_MODE"]),
                    int(self.config["DEFINITIONS"]["MUX_GND_GND_INTPULSE"]))
            elif (self.pulse_entry_choices.get() == "External Pulse"):
                self.femb.femb_udp.write_reg(
                    int(self.config["REGISTERS"]["REG_MUX_MODE"]),
                    int(self.config["DEFINITIONS"]["MUX_GND_DACPULSE"]))

        elif (args[0] == "chip_entry"):
            self.chip = int(
                re.findall(r'\d+', self.chip_entry_choices.get())[0])

    def pause(self):
        self.ani.event_source.stop()
        self.pauseButton['state'] = Tk.DISABLED
        self.playButton['state'] = Tk.NORMAL

    def play(self):
        self.ani.event_source.start()
        self.pauseButton['state'] = Tk.NORMAL
        self.playButton['state'] = Tk.DISABLED

    def plotData(self, iFrame):
        for a in self.ax:
            #Clears all previous traces
            a.cla()
            #Limits the number of traces on each subplot
            a.locator_params(tight=True, nbins=3)

        #In case no data, return an empty plot


#    self.plot[0] = self.ax[0].plot()
        t, adc, thistimestamp = self.getData()
        for r in range(4):
            for c in range(4):
                ch = c + 4 * r
                if not (t is None) and not (adc is None):
                    self.plot[ch] = self.ax[ch].plot(t, adc[ch])
                    if ch < 12: self.ax[ch].set_xticklabels([])
                    self.ax[ch].title.set_text("Channel {}".format(ch))

        if not (thistimestamp is None):
            self.figure.suptitle(
                thistimestamp.replace(microsecond=0).isoformat(" "))
        self.canvas.draw()
        return self.plot[0]

    def closeSync(self):
        self.syncWindow.destroy()
        self.syncWindow.quit()
        self.syncWindow = None

    def manualSync(self):
        self.syncWindow = Tk.Toplevel(self.master)
        self.app = manSync(self.syncWindow, config=self.config, femb=self.femb)
        self.syncWindow.title("Manual Synchronization")

    def getData(self):
        """
    Gets trace from FEMB and returns 4 1D arrays:
        times, ADC counts
    """

        data = self.femb.get_data_chipX(chip=self.chip,
                                        packets=self.packets,
                                        data_format="counts",
                                        tagged=False,
                                        header=False)
        #    data = [[1,2,3,4,5,6,7,8,9,10]]*16
        timestamp = datetime.datetime.now()

        if data == None:
            return None, None, None
        if len(data) == 0:
            return None, None, None

        xpoint = []
        for num, samp in enumerate(data[0]):
            xpoint.append(num * float(self.config["DEFAULT"]["SAMPLE_PERIOD"]))

        return xpoint, data, timestamp
 def configAdcAsic(self,
                   enableOffsetCurrent=None,
                   offsetCurrent=None,
                   testInput=None,
                   freqInternal=None,
                   sleep=None,
                   pdsr=None,
                   pcsr=None,
                   clockMonostable=None,
                   clockExternal=None,
                   clockFromFIFO=None,
                   sLSB=None,
                   f0=0,
                   f1=0,
                   f2=0,
                   f3=None,
                   f4=None,
                   f5=None):
     """
     Configure ADCs
       enableOffsetCurrent: 0 disable offset current, 1 enable offset current
       offsetCurrent: 0-15, amount of current to draw from sample and hold
       testInput: 0 digitize normal input, 1 digitize test input
       freqInternal: internal clock frequency: 0 1MHz, 1 2MHz
       sleep: 0 disable sleep mode, 1 enable sleep mode
       pdsr: if pcsr=0: 0 PD is low, 1 PD is high
       pcsr: 0 power down controlled by pdsr, 1 power down controlled externally
       Only one of these can be enabled:
         clockMonostable: True ADC uses monostable clock
         clockExternal: True ADC uses external clock
         clockFromFIFO: True ADC uses digital generator FIFO clock
       sLSB: LSB current steering mode. 0 for full, 1 for partial (ADC7 P1)
       f0, f1, f2, f3, f4, f5: version specific
     """
     FEMB_CONFIG_BASE.configAdcAsic(self,
                                    clockMonostable=clockMonostable,
                                    clockExternal=clockExternal,
                                    clockFromFIFO=clockFromFIFO)
     if enableOffsetCurrent is None:
         enableOffsetCurrent = 0
     if offsetCurrent is None:
         offsetCurrent = 0
     else:
         offsetCurrent = int(
             "{:04b}".format(offsetCurrent)[::-1],
             2)  # need to reverse bits, use string/list tricks
     if testInput is None:
         testInput = 1
     if freqInternal is None:
         freqInternal = 1
     if sleep is None:
         sleep = 0
     if pdsr is None:
         pdsr = 1
     if pcsr is None:
         pcsr = 1
     if not (clockMonostable or clockExternal or clockFromFIFO):
         clockFromFIFO = True
     clk0 = 0
     clk1 = 0
     if clockExternal:
         clk0 = 1
         clk1 = 0
     elif clockFromFIFO:
         clk0 = 0
         clk1 = 1
     self.adc_reg.set_sbnd_board(en_gr=enableOffsetCurrent,
                                 d=offsetCurrent,
                                 tstin=testInput,
                                 frqc=freqInternal,
                                 slp=sleep,
                                 pdsr=pdsr,
                                 pcsr=pcsr,
                                 clk0=clk0,
                                 clk1=clk1,
                                 f1=f1,
                                 f2=f2,
                                 res2=0,
                                 res1=1,
                                 res0=1)
     self.configAdcAsic_regs(self.adc_reg.REGS)
示例#7
0
class ALIVE_TESTER(object):
    
    def __init__(self):
        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        self.low_level = self.functions.lower_functions
        self.analyze = Data_Analysis(self.config)
        
        #json output, note module version number defined here
        self.jsondict = {'type':'baseline_test'}
        self.jsondict['alive_code_version'] = '1.1'
        self.jsondict['alive_timestamp']  = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
        
    def check_setup(self):
        print("ALIVE - SETUP")
        self.functions.initBoard(default_sync = False)
        if (self.params['using_power_supply'] == True):
            self.PowerSupply = Power_Supply(self.config)
            if (self.PowerSupply.interface == None):
                sys.exit("SYNCHRONIZATION --> Power Supply not found!")    
        
    def record_data(self):
        
        print("ALIVE - COLLECT DATA")
        #Read from regular ADCs
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_READOUT_OPTIONS"]), int(self.config["DEFINITIONS"]["READOUT_NORMAL"]))
        
        #Adds tracer bits on data coming in when the internal pulser has an edge
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_TAGGING"]), int(self.config["DEFINITIONS"]["TAGGING_ON"]))
        
        #Make sure no unwanted pulses
        self.low_level.setInternalPulser(enable = False)
        
        
        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_MUX_MODE"]), int(self.config["DEFINITIONS"]["MUX_GND_DACPULSE"]))
        self.low_level.setExternalPulser(period = int(self.config["MONITOR_SETTINGS"]["MONITOR_FREQ"]), shift = int(self.config["MONITOR_SETTINGS"]["MONITOR_DLY"]), enable = True)
        self.power_info_total = []
        for i in self.params['working_chips']:
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name, self.params["outlabel"])
            data_directory = os.path.join(chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
            os.makedirs(data_directory, exist_ok=True)
            
            for test in ["test_off", "test_ext"]:
                self.functions.configFeAsic(test_cap="on", base=self.config["ALIVE_SETTINGS"]["ALIVE_BASELINE"], gain=self.config["ALIVE_SETTINGS"]["ALIVE_GAIN"], shape=self.config["ALIVE_SETTINGS"]["ALIVE_PEAK"], 
                                    monitor_ch=None, buffer="on", leak = self.config["ALIVE_SETTINGS"]["ALIVE_LEAK"], monitor_param = None, s16=None, 
                                    acdc=self.config["ALIVE_SETTINGS"]["ALIVE_ACDC"], test_dac=test, dac_value=0)
                self.functions.writeFE()
                
                if (test == "test_off"):
                    self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_MUX_MODE"]), int(self.config["DEFINITIONS"]["MUX_GND_DACPULSE"]))
                    self.low_level.setExternalPulser(val = int(self.config["ALIVE_SETTINGS"]["ALIVE_DAC_IN"]), 
                                                    period = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_PERIOD"]), shift = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_SHIFT"]), enable = True)
                elif (test == "test_ext"):
                    self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_MUX_MODE"]), int(self.config["DEFINITIONS"]["MUX_DACPULSE_GND"]))
                    self.low_level.setExternalPulser(val = int(self.config["ALIVE_SETTINGS"]["ALIVE_DAC_MON"]), 
                                                    period = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_PERIOD"]), shift = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_SHIFT"]), enable = True)
                
                packets = int(self.config["ALIVE_SETTINGS"]["ALIVE_PACKETS"])
                data = self.low_level.get_data_chipX(chip = i, tagged = True, packets = packets, header = False)
                for chn in range(int(self.config["DEFAULT"]["NASICCH_MIN"]), int(self.config["DEFAULT"]["NASICCH_MAX"]) + 1, 1):
                    alive_file_notation = self.config["FILENAMES"]["ALIVE_NAMING"]
                    filename = alive_file_notation.format(chn,self.config["ALIVE_SETTINGS"]["ALIVE_LEAK"],test)
                    full_filename = os.path.join(data_directory,filename)
                    chn_data = data[chn]
                    buffer = len(chn_data)
                    bin_data = struct.pack(">%dH"%buffer, *chn_data)
                    
                    with open(full_filename,"wb") as f:
                        f.write(bin_data) 
                        f.close()
                        
            power_info = self.functions.PCB_power_monitor(chips = i)
            self.power_info_total.append(power_info)
            
        if (self.params['using_power_supply'] == True):   
            pwr = self.config["POWER_SUPPLY"]
            self.heating_results = self.PowerSupply.measure_params(channel = int(pwr["PS_HEATING_CHN"]))
            self.quad_results = self.PowerSupply.measure_params(channel = int(pwr["PS_QUAD_CHN"]))
            self.fpga_results = self.PowerSupply.measure_params(channel = int(pwr["PS_FPGA_CHN"]))
        
        self.power_cycle_PCB_power = []
        self.power_cycle_heating_results = []
        self.power_cycle_quad_results = []
        self.power_cycle_fpga_results = []

        temp = self.params['temperature']
        
        if (temp == "LN"):
            
            total_cycles = int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_1"]) + int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_2"])
            
            print("Test--> Testing {} power cycles ({} seconds in between for the first {}, {} seconds in between for the next {})".format(total_cycles, self.config["ALIVE_SETTINGS"]["ALIVE_TIME_OFF_1"],
                                                                                                  self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_1"], self.config["ALIVE_SETTINGS"]["ALIVE_TIME_OFF_2"],
                                                                                                    self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_2"]))
            for cycle in range(total_cycles):
                self.power_cycle_PCB_power.append([])
                print("Test--> Cycle {}".format(cycle))
                
                self.functions.turnOffAsics()
                if (cycle < int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_1"])):
                    time.sleep(float(self.config["ALIVE_SETTINGS"]["ALIVE_TIME_OFF_1"]))
                else:
                    time.sleep(float(self.config["ALIVE_SETTINGS"]["ALIVE_TIME_OFF_2"]))
                self.functions.turnOnAsics()
                
                for test in ["test_off", "test_ext"]:
                    self.functions.configFeAsic(test_cap="on", base=self.config["ALIVE_SETTINGS"]["ALIVE_BASELINE"], gain=self.config["ALIVE_SETTINGS"]["ALIVE_GAIN"], shape=self.config["ALIVE_SETTINGS"]["ALIVE_PEAK"], 
                                        monitor_ch=None, buffer="on", leak = self.config["ALIVE_SETTINGS"]["ALIVE_LEAK"], monitor_param = None, s16=None, 
                                        acdc=self.config["ALIVE_SETTINGS"]["ALIVE_ACDC"], test_dac=test, dac_value=0)
                    self.functions.writeFE()
                    
                    if (test == "test_off"):
                        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_MUX_MODE"]), int(self.config["DEFINITIONS"]["MUX_GND_DACPULSE"]))
                        self.low_level.setExternalPulser(val = int(self.config["ALIVE_SETTINGS"]["ALIVE_DAC_IN"]), 
                                                        period = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_PERIOD"]), shift = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_SHIFT"]), enable = True)
                    elif (test == "test_ext"):
                        self.low_level.femb_udp.write_reg(int(self.config["REGISTERS"]["REG_MUX_MODE"]), int(self.config["DEFINITIONS"]["MUX_DACPULSE_GND"]))
                        self.low_level.setExternalPulser(val = int(self.config["ALIVE_SETTINGS"]["ALIVE_DAC_MON"]), 
                                                        period = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_PERIOD"]), shift = int(self.config["ALIVE_SETTINGS"]["ALIVE_TP_SHIFT"]), enable = True)
                    
                    packets = int(self.config["BASELINE_SETTINGS"]["BASELINE_PACKETS"])
                    for i in self.params['working_chips']:
                        chip_name = self.params['chip_list'][i][1]
                        chip_outpathlabel = os.path.join(self.params["datadir"], chip_name, self.params["outlabel"])
                        data_directory = os.path.join(chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
                        os.makedirs(data_directory, exist_ok=True)
                        data = self.low_level.get_data_chipXchnX_tagged(chn = 1, chip = i, packets = packets, header = False)
                        
                        cycle_file_notation = self.config["FILENAMES"]["ALIVE_NAMING2"]
                        filename = cycle_file_notation.format(self.config["ALIVE_SETTINGS"]["ALIVE_LEAK"],test,cycle)
                        full_filename = os.path.join(data_directory,filename)
                        buffer = len(data)
                        bin_data = struct.pack(">%dH"%buffer, *data)
                        
                        with open(full_filename,"wb") as f:
                            f.write(bin_data) 
                            f.close()
                            
                        power_info = self.functions.PCB_power_monitor(chips = i)
                        self.power_cycle_PCB_power[cycle].append(power_info)
                
                if (self.params['using_power_supply'] == True):   
                    pwr = self.config["POWER_SUPPLY"]
                    self.power_cycle_heating_results.append(self.PowerSupply.measure_params(channel = int(pwr["PS_HEATING_CHN"])))
                    self.power_cycle_quad_results.append(self.PowerSupply.measure_params(channel = int(pwr["PS_QUAD_CHN"])))
                    self.power_cycle_fpga_results.append(self.PowerSupply.measure_params(channel = int(pwr["PS_FPGA_CHN"])))
                        
        print ("Test--> Input Alive data completed")
        
    def do_analysis(self):
        print("ALIVE - ANALYZE")
        self.results = []
        for i in self.params["working_chips"]:
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name, self.params["outlabel"])
            data_directory = os.path.join(chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
            
            result = self.analyze.alive_directory(chip_outpathlabel, chip_name, data_directory, ["test_off", "test_ext"], self.config["ALIVE_SETTINGS"]["ALIVE_LEAK"], self.params['temperature'])
            self.results.append(result)
            
    def archiveResults(self):
        print("ALIVE - ARCHIVE")
        
        self.jsondict['alive_executable'] = self.params['executable']
        self.jsondict['alive_datasubdir'] = self.params['datasubdir']
        self.jsondict['alive_outlabel'] = self.params['outlabel']
        self.jsondict['alive_gain'] = self.config["ALIVE_SETTINGS"]["ALIVE_GAIN"]
        self.jsondict['alive_peak'] = self.config["ALIVE_SETTINGS"]["ALIVE_PEAK"]
        self.jsondict['alive_leak'] = self.config["ALIVE_SETTINGS"]["ALIVE_LEAK"]
        self.jsondict['alive_acdc'] = self.config["ALIVE_SETTINGS"]["ALIVE_ACDC"]
        self.jsondict['alive_baseline'] = self.config["ALIVE_SETTINGS"]["ALIVE_BASELINE"]
        
        if (self.params['using_power_supply'] == True):  
            self.jsondict['PS_heating_voltage'] = self.heating_results[0]
            self.jsondict['PS_heating_current'] = self.heating_results[1]
            self.jsondict['PS_quad_voltage'] = self.quad_results[0]
            self.jsondict['PS_quad_current'] = self.quad_results[1]
            self.jsondict['PS_fpga_voltage'] = self.fpga_results[0]
            self.jsondict['PS_fpga_current'] = self.fpga_results[1]
        
        if ((self.params['temperature'] == "LN") and (self.params['using_power_supply'] == True)):
            total_cycles = int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_1"]) + int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_2"])
            for cycle in range(total_cycles):
                self.jsondict['PS_heating_voltage_cycle{}'.format(cycle)] = self.power_cycle_heating_results[cycle][0]
                self.jsondict['PS_heating_current_cycle{}'.format(cycle)] = self.power_cycle_heating_results[cycle][1]
                self.jsondict['PS_quad_voltage_cycle{}'.format(cycle)] = self.power_cycle_quad_results[cycle][0]
                self.jsondict['PS_quad_current_cycle{}'.format(cycle)] = self.power_cycle_quad_results[cycle][1]
                self.jsondict['PS_fpga_voltage_cycle{}'.format(cycle)] = self.power_cycle_fpga_results[cycle][0]
                self.jsondict['PS_fpga_current_cycle{}'.format(cycle)] = self.power_cycle_fpga_results[cycle][1]

        for num, i in enumerate(self.params['working_chips']):
            chip_name = self.params['chip_list'][i][1]
            jsonFile = os.path.join(self.params["datadir"],chip_name,self.params["datasubdir"],self.params["outlabel"], self.config["FILENAMES"]["RESULTS"])
            if (self.results[num] == True):
                self.jsondict['alive_result'] = "PASS"
            elif (self.results[num] == False):
                self.jsondict['alive_result'] = "FAIL"
            else:
                self.jsondict['alive_result'] = "N/A"
                
            #TODO add which channels, cycles, tests, failed
                
            self.jsondict['vdda_shunt_voltage'] = self.power_info_total[num][0][0]
            self.jsondict['vdda_bus_voltage'] = self.power_info_total[num][0][1]
            self.jsondict['vdda_current'] = self.power_info_total[num][0][2]
            self.jsondict['vddp_shunt_voltage'] = self.power_info_total[num][1][0]
            self.jsondict['vddp_bus_voltage'] = self.power_info_total[num][1][1]
            self.jsondict['vddp_current'] = self.power_info_total[num][1][2]
                
            if (self.params['temperature'] == "LN"):
                total_cycles = int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_1"]) + int(self.config["ALIVE_SETTINGS"]["ALIVE_POWER_CYCLES_2"])
                for cycle in range(total_cycles):
                    self.jsondict['vdda_shunt_voltage_cycle{}'.format(cycle)] = self.power_cycle_PCB_power[cycle][num][0][0]
                    self.jsondict['vdda_bus_voltage_cycle{}'.format(cycle)] = self.power_cycle_PCB_power[cycle][num][0][1]
                    self.jsondict['vdda_current_cycle{}'.format(cycle)] = self.power_cycle_PCB_power[cycle][num][0][2]
                    self.jsondict['vddp_shunt_voltage_cycle{}'.format(cycle)] = self.power_cycle_PCB_power[cycle][num][1][0]
                    self.jsondict['vddp_bus_voltage_cycle{}'.format(cycle)] = self.power_cycle_PCB_power[cycle][num][1][1]
                    self.jsondict['vddp_current_cycle{}'.format(cycle)] = self.power_cycle_PCB_power[cycle][num][1][2]
                
            with open(jsonFile,'a') as outfile:
                json.dump(self.jsondict, outfile, indent=4)
                
            jsonFile = os.path.join(self.params["datadir"],chip_name,self.params["datasubdir"],self.config["FILENAMES"]["RESULTS"])
            with open(jsonFile,'r') as f:
                existing_json = json.load(f)
            
            existing_json['alive_outlabel'] = self.params['outlabel']
            with open(jsonFile,'w') as outfile:
                json.dump(existing_json, outfile, indent=4)
    def configAdcAsic(self,
                      enableOffsetCurrent=None,
                      offsetCurrent=None,
                      testInput=None,
                      freqInternal=None,
                      sleep=None,
                      pdsr=None,
                      pcsr=None,
                      clockMonostable=None,
                      clockExternal=None,
                      clockFromFIFO=None,
                      sLSB=None,
                      f0=None,
                      f1=None,
                      f2=None,
                      f3=None,
                      f4=None,
                      f5=None):
        """
        Configure ADCs
          enableOffsetCurrent: 0 disable offset current, 1 enable offset current
          offsetCurrent: 0-15, amount of current to draw from sample and hold
          testInput: 0 digitize normal input, 1 digitize test input
          freqInternal: internal clock frequency: 0 1MHz, 1 2MHz
          sleep: 0 disable sleep mode, 1 enable sleep mode
          pdsr: if pcsr=0: 0 PD is low, 1 PD is high
          pcsr: 0 power down controlled by pdsr, 1 power down controlled externally
          Only one of these can be enabled:
            clockMonostable: True ADC uses monostable clock
            clockExternal: True ADC uses external clock
            clockFromFIFO: True ADC uses digital generator FIFO clock
          sLSB: LSB current steering mode. 0 for full, 1 for partial (ADC7 P1)
          f0, f1, f2, f3, f4, f5: version specific
        """
        FEMB_CONFIG_BASE.configAdcAsic(self,
                                       clockMonostable=clockMonostable,
                                       clockExternal=clockExternal,
                                       clockFromFIFO=clockFromFIFO)
        if enableOffsetCurrent is None:
            enableOffsetCurrent = 0
        if offsetCurrent is None:
            offsetCurrent = 0
        else:
            offsetCurrent = int(
                "{:04b}".format(offsetCurrent)[::-1],
                2)  # need to reverse bits, use string/list tricks
        if testInput is None:
            testInput = 1
        if freqInternal is None:
            freqInternal = 1
        if sleep is None:
            sleep = 0
        if pdsr is None:
            pdsr = 0
        if pcsr is None:
            pcsr = 0
        if sLSB is None:
            sLSB = 0
        if f1 is None:
            f1 = 0
        if f2 is None:
            f2 = 0
        if f3 is None:
            f3 = 0
        if f4 is None:
            f4 = 1
        if f5 is None:
            f5 = 0
        if not (clockMonostable or clockExternal or clockFromFIFO):
            clockExternal = True
        # a bunch of things depend on the clock choice
        clk0 = 0
        clk1 = 0
        if clockExternal:
            clk0 = 1
            clk1 = 0
        elif clockFromFIFO:
            clk0 = 0
            clk1 = 1
        if f0 is None:
            if clockExternal:
                f0 = 1
            else:
                f0 = 0
        if clockExternal:
            self.extClock(enable=True)
        else:
            self.extClock(enable=False)

        regsListOfLists = []
        for chipRegConfig in self.adc_regs:
            chipRegConfig.set_chip(en_gr=enableOffsetCurrent,
                                   d=offsetCurrent,
                                   tstin=testInput,
                                   frqc=freqInternal,
                                   slp=sleep,
                                   pdsr=pdsr,
                                   pcsr=pcsr,
                                   clk0=clk0,
                                   clk1=clk1,
                                   f0=f0,
                                   f1=f1,
                                   f2=f2,
                                   f3=f3,
                                   f4=f4,
                                   f5=f5,
                                   slsb=sLSB)
            regsListOfLists.append(chipRegConfig.REGS)
        self.configAdcAsic_regs(regsListOfLists)
示例#9
0
class SYNC_ADCS(object):
    def __init__(self):

        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        self.low_level = self.functions.lower_functions
        self.sync_functions = self.functions.sync
        self.plotting = self.functions.sync.plot

        #json output, note module version number defined here
        self.syncdict = {'type': 'sync_adcs'}
        self.syncdict['sync_code_version'] = '1.1'
        self.syncdict['sync_timestamp'] = datetime.datetime.today().strftime(
            '%Y%m%d%H%M%S')

    def check_setup(self):
        print("SYNCHRONIZATION - SETUP")
        self.functions.initBoard(default_sync=False)
        if (self.params['using_power_supply'] == True):
            self.PowerSupply = Power_Supply(self.config)
            if (self.PowerSupply.interface == None):
                sys.exit("SYNCHRONIZATION --> Power Supply not found!")

    def sync(self):
        print("SYNCHRONIZATION - COLLECT DATA")
        self.return_results = self.sync_functions.syncADC(**self.params)

        self.low_level.femb_udp.write_reg(
            int(self.config["REGISTERS"]["REG_TAGGING"]),
            int(self.config["DEFINITIONS"]["TAGGING_ON"]))
        self.low_level.setExternalPulser(
            val=int(
                self.config["INITIAL_SETTINGS"]["DEFAULT_EXTERNAL_DAC_VAL"],
                16),
            period=int(self.config["INITIAL_SETTINGS"]
                       ["DEFAULT_EXTERNAL_DAC_TP_PERIOD"]),
            shift=int(self.config["INITIAL_SETTINGS"]
                      ["DEFAULT_EXTERNAL_DAC_TP_SHIFT"]),
            enable=True)

        self.functions.configFeAsic(
            test_cap="on",
            base=self.config["SYNC_SETTINGS"]["SYNC_BASELINE"],
            gain=self.config["SYNC_SETTINGS"]["SYNC_GAIN"],
            shape=self.config["SYNC_SETTINGS"]["SYNC_PEAK"],
            monitor_ch=None,
            buffer=self.config["SYNC_SETTINGS"]["SYNC_BUFFER"],
            leak=self.config["SYNC_SETTINGS"]["SYNC_LEAK"],
            monitor_param=None,
            s16=None,
            acdc=self.config["SYNC_SETTINGS"]["SYNC_ACDC"],
            test_dac="test_int",
            dac_value=int(
                self.config["SYNC_SETTINGS"]["SYNC_DAC_PEAK_HEIGHT"]))
        self.functions.writeFE()
        self.low_level.femb_udp.write_reg(
            int(self.config["REGISTERS"]["REG_MUX_MODE"]),
            int(self.config["DEFINITIONS"]["MUX_GND_GND_INTPULSE"]))
        self.power_info_total = []
        for i in self.params['working_chips']:
            chip_index = self.params['chip_list'][i][0]
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name,
                                             self.params["outlabel"])
            data = self.low_level.get_data_chipX(
                chip=chip_index,
                packets=int(self.config["SYNC_SETTINGS"]["SYNC_PACKETS"]),
                tagged=True)
            print(
                "quad_sync_adcs--> Printing internal synchronization plot for Chip {}"
                .format(chip_name))
            sync_int_text = self.config["FILENAMES"]["SYNC_FILE_INT"].format(
                chip_name)
            savefig = os.path.join(chip_outpathlabel, sync_int_text)
            power_info = self.functions.PCB_power_monitor(chips=i)
            self.power_info_total.append(power_info)
            self.plotting.plot_chip(
                data=data,
                plot_name=savefig,
                title_name=
                "Chip {} Internal Sync: Gain = {}/fC, Peaking Time = {}".
                format(chip_name, self.config["SYNC_SETTINGS"]["SYNC_GAIN"],
                       self.config["SYNC_SETTINGS"]["SYNC_PEAK"]),
                power=power_info,
                length=1000)
        if (self.params['using_power_supply'] == True):
            pwr = self.config["POWER_SUPPLY"]
            self.heating_results = self.PowerSupply.measure_params(
                channel=int(pwr["PS_HEATING_CHN"]))
            self.quad_results = self.PowerSupply.measure_params(
                channel=int(pwr["PS_QUAD_CHN"]))
            self.fpga_results = self.PowerSupply.measure_params(
                channel=int(pwr["PS_FPGA_CHN"]))
        self.low_level.femb_udp.write_reg(
            int(self.config["REGISTERS"]["REG_MUX_MODE"]),
            int(self.config["DEFINITIONS"]["MUX_GND_DACPULSE"]))

        for i in self.params['working_chips']:
            chip_index = self.params['chip_list'][i][0]
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name,
                                             self.params["outlabel"])
            data = self.low_level.get_data_chipX(
                chip=chip_index,
                packets=int(self.config["SYNC_SETTINGS"]["SYNC_PACKETS"]),
                tagged=True)
            print(
                "quad_sync_adcs--> Printing external synchronization plot for Chip {}"
                .format(chip_name))
            sync_ext_text = self.config["FILENAMES"]["SYNC_FILE_EXT"].format(
                chip_name)
            savefig = os.path.join(chip_outpathlabel, sync_ext_text)
            power_info = self.functions.PCB_power_monitor(chips=i)
            self.plotting.plot_chip(
                data=data,
                plot_name=savefig,
                title_name=
                "Chip {} External Sync: Gain = {}/fC, Peaking Time = {}".
                format(chip_name, self.config["SYNC_SETTINGS"]["SYNC_GAIN"],
                       self.config["SYNC_SETTINGS"]["SYNC_PEAK"]),
                power=power_info,
                length=1000)

        self.low_level.setExternalPulser(enable=False)
        self.low_level.femb_udp.write_reg(
            int(self.config["REGISTERS"]["REG_MUX_MODE"]),
            int(self.config["DEFINITIONS"]["MUX_GND_GND"]))
        self.low_level.femb_udp.write_reg(
            int(self.config["REGISTERS"]["REG_TAGGING"]),
            int(self.config["DEFINITIONS"]["TAGGING_OFF"]))

    def do_analysis(self, ):
        print("SYNCHRONIZATION - ANALYZE")
        self.results = self.params["chip_list"]
        for num, i in enumerate(range(len(self.results))):
            if (self.return_results[num] == True):
                self.results[i].append("PASS")
            elif (self.return_results[num] == False):
                self.results[i].append("FAIL")
            else:
                self.results[i].append("NOT TESTED (SPI ERROR)")

    def archiveResults(self):
        print("SYNCHRONIZATION - ARCHIVE")

        self.jsondict = {'boardID': self.params['boardid']}
        self.jsondict['fw_ver'] = self.params['fw_ver']
        self.jsondict['test_category'] = self.params['test_category']
        self.jsondict['test_stand'] = self.params['test_stand']
        self.jsondict['chipver'] = self.params['chipver']
        self.jsondict['sw_version'] = self.params['sw_version']
        self.jsondict['fpgamezz'] = self.params['fpgamezz']
        self.jsondict['femb_config'] = self.params['femb_config']
        self.jsondict['paramfile'] = self.params['paramfile']
        self.jsondict['sync_outlabel'] = self.params['outlabel']
        for i in self.params['working_chips']:
            chip_index = self.params['chip_list'][i][0]
            chip_name = self.params['chip_list'][i][1]
            jsonFile = os.path.join(self.params["datadir"], chip_name,
                                    self.params["datasubdir"],
                                    self.config["FILENAMES"]["RESULTS"])
            self.jsondict['chip_index'] = chip_index
            self.jsondict['chip_name'] = chip_name
            self.jsondict['socket'] = self.params["socket{}id".format(
                chip_index)]
            with open(jsonFile, 'a') as outfile:
                json.dump(self.jsondict, outfile, indent=4)

        self.syncdict['sync_baseline'] = self.config["SYNC_SETTINGS"][
            "SYNC_BASELINE"]
        self.syncdict['sync_buffer'] = self.config["SYNC_SETTINGS"][
            "SYNC_BUFFER"]
        self.syncdict['sync_gain'] = self.config["SYNC_SETTINGS"]["SYNC_GAIN"]
        self.syncdict['sync_peak'] = self.config["SYNC_SETTINGS"]["SYNC_PEAK"]
        self.syncdict['sync_acdc'] = self.config["SYNC_SETTINGS"]["SYNC_ACDC"]
        self.syncdict['sync_leak'] = self.config["SYNC_SETTINGS"]["SYNC_LEAK"]
        self.syncdict['sync_executable'] = self.params['executable']
        self.syncdict['sync_datasubdir'] = self.params['datasubdir']

        if (self.params['using_power_supply'] == True):
            self.syncdict['PS_heating_voltage'] = self.heating_results[0]
            self.syncdict['PS_heating_current'] = self.heating_results[1]
            self.syncdict['PS_quad_voltage'] = self.quad_results[0]
            self.syncdict['PS_quad_current'] = self.quad_results[1]
            self.syncdict['PS_fpga_voltage'] = self.fpga_results[0]
            self.syncdict['PS_fpga_current'] = self.fpga_results[1]

        for num, i in enumerate(self.params['working_chips']):
            chip_index = self.params['chip_list'][i][0]
            chip_name = self.params['chip_list'][i][1]
            jsonFile = os.path.join(self.params["datadir"], chip_name,
                                    self.params["datasubdir"],
                                    self.params["outlabel"],
                                    self.config["FILENAMES"]["RESULTS"])
            self.syncdict['sync_result'] = self.results[chip_index][2]
            self.syncdict['vdda_shunt_voltage'] = self.power_info_total[num][
                0][0]
            self.syncdict['vdda_bus_voltage'] = self.power_info_total[num][0][
                1]
            self.syncdict['vdda_current'] = self.power_info_total[num][0][2]
            self.syncdict['vddp_shunt_voltage'] = self.power_info_total[num][
                1][0]
            self.syncdict['vddp_bus_voltage'] = self.power_info_total[num][1][
                1]
            self.syncdict['vddp_current'] = self.power_info_total[num][1][2]
            with open(jsonFile, 'a') as outfile:
                json.dump(self.syncdict, outfile, indent=4)
示例#10
0
    def __init__(self, master=None, forceQuick=False, forceLong=False):
        self.use_sumatra = True

        #Useful to have if we ever want to look back and see what version of femb_python we were using
        try:
            repo = git.Repo(__file__, search_parent_directories=True)
            self.sw_version = repo.head.object.hexsha
        except:
            self.sw_version = "Not Found"

        #It's calling the constructor of the parent tkinter object, the pack method of the class, which is now a tkinter object
        tk.Frame.__init__(self, master)
        self.pack()
        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)

        self.master.title("Quad FE ASIC Test GUI")
        self.master.protocol("WM_DELETE_WINDOW",
                             lambda arg=self.master: self.on_closing(arg))
        self.WF_GUI = None
        self.analysis = "basic"
        try:
            self.PowerSupply = Power_Supply(self.config)
        except BrokenPipeError:
            self.PowerSupply = None
        #Variables that I want to save in the JSON but aren't included in the generic runner
        self.params = dict(test_category="feasic_quad_cold",
                           sw_version=self.sw_version,
                           use_sumatra=self.use_sumatra)

        #Look in the root folder for the test name and see if there was a JSON file created with the previous settings
        #This is used to pre-fill in the fields, much more preferable than putting in the sockets and all that from scratch
        self.root_dir = getDefaultDirectory()
        file_name = os.path.join(
            self.root_dir, self.config["FILENAMES"]["DEFAULT_GUI_FILE_NAME"])
        if os.path.isfile(file_name):
            self.default_settings = dict()
            with open(file_name, 'r') as f:
                jsondata = json.load(f)
                for i in jsondata:
                    self.default_settings[i] = jsondata[i]
        else:
            self.default_settings = dict(operator_name="",
                                         test_stand="",
                                         test_stand_other="",
                                         boardid="",
                                         boardid_other="",
                                         chipver="",
                                         chipver_other="",
                                         fpgamezz="",
                                         fpgamezz_other="",
                                         asic0id="",
                                         asic1id="",
                                         asic2id="",
                                         asic3id="",
                                         socket0id="",
                                         socket1id="",
                                         socket2id="",
                                         socket3id="")

        #Define general commands column
        self.define_test_details_column()

        #Define general commands column
        self.define_general_commands_column()
        return
示例#11
0
class GUI_WINDOW(tk.Frame):

    #GUI window defined entirely in init function
    def __init__(self, master=None, forceQuick=False, forceLong=False):
        self.use_sumatra = True

        #Useful to have if we ever want to look back and see what version of femb_python we were using
        try:
            repo = git.Repo(__file__, search_parent_directories=True)
            self.sw_version = repo.head.object.hexsha
        except:
            self.sw_version = "Not Found"

        #It's calling the constructor of the parent tkinter object, the pack method of the class, which is now a tkinter object
        tk.Frame.__init__(self, master)
        self.pack()
        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)

        self.master.title("Quad FE ASIC Test GUI")
        self.master.protocol("WM_DELETE_WINDOW",
                             lambda arg=self.master: self.on_closing(arg))
        self.WF_GUI = None
        self.analysis = "basic"
        try:
            self.PowerSupply = Power_Supply(self.config)
        except BrokenPipeError:
            self.PowerSupply = None
        #Variables that I want to save in the JSON but aren't included in the generic runner
        self.params = dict(test_category="feasic_quad_cold",
                           sw_version=self.sw_version,
                           use_sumatra=self.use_sumatra)

        #Look in the root folder for the test name and see if there was a JSON file created with the previous settings
        #This is used to pre-fill in the fields, much more preferable than putting in the sockets and all that from scratch
        self.root_dir = getDefaultDirectory()
        file_name = os.path.join(
            self.root_dir, self.config["FILENAMES"]["DEFAULT_GUI_FILE_NAME"])
        if os.path.isfile(file_name):
            self.default_settings = dict()
            with open(file_name, 'r') as f:
                jsondata = json.load(f)
                for i in jsondata:
                    self.default_settings[i] = jsondata[i]
        else:
            self.default_settings = dict(operator_name="",
                                         test_stand="",
                                         test_stand_other="",
                                         boardid="",
                                         boardid_other="",
                                         chipver="",
                                         chipver_other="",
                                         fpgamezz="",
                                         fpgamezz_other="",
                                         asic0id="",
                                         asic1id="",
                                         asic2id="",
                                         asic3id="",
                                         socket0id="",
                                         socket1id="",
                                         socket2id="",
                                         socket3id="")

        #Define general commands column
        self.define_test_details_column()

        #Define general commands column
        self.define_general_commands_column()
        return

    #For GUI options where there are predefined but have the option for "other" (in case we're testing a new version of something)
    #Every time a change is made to those fields, this is called to see if "other" was chosen.  If it was, it creates a text field to manually write the value
    #If it's not, it hides that text field
    def gui_callback(self, *args, **kwargs):
        #TODO use dictionary map to get this quicker
        if (args[0] == "test_stand_GUI_variable"):
            index = 0
        elif (args[0] == "boardid_GUI_variable"):
            index = 1
        elif (args[0] == "chipver_GUI_variable"):
            index = 2
        elif (args[0] == "fpgamezz_GUI_variable"):
            index = 3

        if (self.selections[index].get() == "Other"):
            self.other_entries[index].grid(sticky=tk.W,
                                           row=index + 2,
                                           column=3)
            self.others[index] = True
        else:
            self.other_entries[index].grid_forget()
            self.others[index] = False

    #For fields with predefined values, it gets those values from the config files
    #There's also a variable to tell if "other" was chosen, so it knows to look at the manual entry field for the value
    def define_test_details_column(self):
        columnbase = 1
        entry_width = 9
        options_width = 5
        spinner_width = 8
        label_width = 15

        self.details_label = tk.Label(self, text="Tests Details")
        self.details_label.grid(row=0, column=columnbase, columnspan=3)

        # Adding operator name label and read entry box
        label = tk.Label(self, text="Operator Name:", width=label_width)
        label.grid(sticky=tk.W, row=1, column=columnbase + 0)

        self.operator_entry = tk.Entry(self, width=entry_width)
        self.operator_entry.insert(tk.END,
                                   self.default_settings["operator_name"])
        self.operator_entry.grid(sticky=tk.W, row=1, column=columnbase + 1)

        test_stand = [
            "Test Stand #:", "test_stand_GUI_variable", "test_stand",
            'KNOWN_TEST_STANDS', self.default_settings["test_stand_other"]
        ]
        board_id = [
            "Test Board ID:", "boardid_GUI_variable", "boardid",
            'KNOWN_QUAD_BOARDS', self.default_settings["boardid_other"]
        ]
        chip_ver = [
            "Chip Version:", "chipver_GUI_variable", "chipver",
            'KNOWN_CHIP_VERSIONS', self.default_settings["chipver_other"]
        ]
        fpgamezz = [
            "FPGA Board:", "fpgamezz_GUI_variable", "fpgamezz",
            'KNOWN_FPGA_MEZZANINES', self.default_settings["fpgamezz_other"]
        ]

        self.option_rows = [test_stand, board_id, chip_ver, fpgamezz]
        self.selections = []
        self.entries = []
        self.other_entries = []
        self.others = []

        for num, i in enumerate(self.option_rows):

            # Adding test stand ID and read entry box
            label = tk.Label(self, text=i[0], width=label_width)
            label.grid(sticky=tk.W, row=2 + num, column=columnbase + 0)

            selection = tk.StringVar(self.master, name=i[1])
            selection.set(self.default_settings[i[2]])  # initial value
            selection.trace("w", self.gui_callback)
            self.selections.append(selection)

            options = list(self.config._sections[i[3]].keys())
            possible_options = []
            for j in range(len(options)):
                possible_options.append(self.config[i[3]][options[j]])

            entry = tk.OptionMenu(self, selection, *possible_options)
            entry.config(width=options_width)
            self.entries.append(entry)
            entry.grid(sticky=tk.W, row=2 + num, column=columnbase + 1)

            entry_other = tk.Entry(self, width=entry_width)
            self.other_entries.append(entry_other)
            if (selection.get() == "Other"):
                entry_other.insert(tk.END, i[4])
                entry_other.grid(sticky=tk.W, row=2 + num, column=3)
                other = True
            else:
                entry_other.grid_forget()
                other = False
            self.others.append(other)

        label = tk.Label(self, text="Chip ID:", width=entry_width)
        label.grid(sticky=tk.W, row=7, column=columnbase + 1)

        label = tk.Label(self, text="Socket ID:", width=entry_width)
        label.grid(sticky=tk.W, row=7, column=columnbase + 2)

        self.asic_entries = []
        self.socket_entries = []
        self.asic_enables = []
        for i, chip in enumerate(
                range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                      int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1)):
            var = tk.BooleanVar(value=True)
            self.asic_enables.append(var)
            button = tk.Checkbutton(self, variable=var)
            button.grid(row=8 + i, column=columnbase - 1)

            label = tk.Label(self,
                             text="ASIC {}".format(chip),
                             width=label_width)
            label.grid(sticky=tk.W, row=8 + i, column=columnbase + 0)

            spinbox = tk.Spinbox(self,
                                 width=spinner_width,
                                 from_=self.config['GUI_SETTINGS']['CHIP_MIN'],
                                 to=self.config['GUI_SETTINGS']['CHIP_MAX'])
            self.asic_entries.append(spinbox)
            spinbox.insert(tk.END,
                           self.default_settings["asic{}id".format(chip)])
            spinbox.delete(0)
            spinbox.grid(sticky=tk.W, row=8 + i, column=columnbase + 1)

            spinbox = tk.Spinbox(
                self,
                width=spinner_width,
                from_=self.config['GUI_SETTINGS']['SOCKET_MIN'],
                to=self.config['GUI_SETTINGS']['SOCKET_MAX'])
            self.socket_entries.append(spinbox)
            spinbox.insert(tk.END,
                           self.default_settings["socket{}id".format(chip)])
            spinbox.delete(0)
            spinbox.grid(sticky=tk.W, row=8 + i, column=columnbase + 2)

    def define_general_commands_column(self):
        self.midcolumnbase = 4

        self.status_label = tk.Label(self, text="FE ASIC TESTS", width=20)
        self.status_label.grid(row=0, column=self.midcolumnbase, columnspan=50)

        #Set up buttons
        power_on = ["Power On", self.power_on, "green"]
        power_off = ["Power Off", self.power_off, "red"]
        test_connection = ["Test Connection", self.test_connection]
        debug = ["Debug Waveform", self.debug]
        start = ["Start Cold Tests", self.start_cold_measurements]
        start_warm = ["Start Warm Tests", self.start_warm_measurements]

        buttons = [
            power_on, power_off, test_connection, debug, start, start_warm
        ]

        for num, i in enumerate(buttons):
            try:
                button_i = tk.Button(self,
                                     text=i[0],
                                     bg=i[2],
                                     command=i[1],
                                     width=10)
            except IndexError:
                button_i = tk.Button(self, text=i[0], command=i[1], width=10)
            button_i.grid(row=1 + num, column=self.midcolumnbase)

        advanced = tk.Button(self,
                             text="Advanced",
                             command=self.change_analysis_level)
        advanced.grid(row=3, column=self.midcolumnbase + 1)

        #Name as appears on GUI, basic or advanced, executible, and name of folder
        sync_test = ["Sync", "basic", "feasic_quad_sync", "Sync"]
        baseline_test = [
            "Baseline", "basic", "feasic_quad_baseline", "Baseline"
        ]
        monitor_test = ["Monitor", "basic", "feasic_quad_monitor", "Monitor"]
        alive_test = ["Alive", "basic", "feasic_quad_alive", "Alive"]
        dac_test = ["DAC", "advanced", "feasic_quad_dac", "Internal DAC"]
        gain_test = ["Pulse", "advanced", "feasic_quad_pulse", "Pulse"]
        ledge_test = ["Ledge", "advanced", "feasic_quad_ledge", "Ledge"]
        final_test = ["Final", "basic"]
        self.all_tests = [
            sync_test, baseline_test, monitor_test, alive_test, dac_test,
            gain_test, ledge_test, final_test
        ]
        for num, i in enumerate(self.all_tests):
            label = tk.Label(self, text=i[0], width=10)
            i.append(label)

            var = tk.BooleanVar(value=True)
            i.append(var)
            button = tk.Checkbutton(self, variable=var)
            i.append(button)
            if (i[1] == "basic"):
                label.grid(sticky=tk.W,
                           row=7,
                           column=self.midcolumnbase + num + 1)
                if (i[0] != "Final" and i[0] != "Sync"):
                    button.grid(row=6, column=self.midcolumnbase + num + 1)

        self.connected_power_supply = ["Connected Power Supply"]
        self.temperature_cold = ["Cold Test"]
        self.online_analysis = ["Concurrent Analysis"]
        self.advanced_options = [
            self.connected_power_supply, self.temperature_cold,
            self.online_analysis
        ]
        self.advanced_variables = []
        for i in self.advanced_options:
            label = tk.Label(self, text=i[0], width=20, anchor="w")
            i.append(label)
            var = tk.BooleanVar(value=True)
            self.advanced_variables.append(var)
            button = tk.Checkbutton(self, variable=var)
            i.append(button)

        self.results_array = []
        for num, i in enumerate(self.all_tests):
            test_specific = []
            for chips in range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                               int(self.config["DEFAULT"]["NASIC_MAX"]) + 1,
                               1):
                label = tk.Label(self, text="----", width=10)
                if (i[1] == "basic"):
                    label.grid(stick=tk.W,
                               row=8 + chips,
                               column=self.midcolumnbase + num + 1)
                test_specific.append(label)

            self.results_array.append(test_specific)

        #Set up static labels
        for num, chips in enumerate(
                range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                      int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1)):
            label = tk.Label(self,
                             text="ASIC {} Results:".format(chips),
                             width=15)
            label.grid(sticky=tk.W, row=8 + num, column=self.midcolumnbase + 0)

    def write_default_file(self):
        self.params['operator_name'] = self.operator_entry.get()
        for num, i in enumerate(self.option_rows):
            using_other = self.others[num]
            if (using_other == True):
                self.params[i[2]] = self.other_entries[num].get()
            else:
                self.params[i[2]] = self.selections[num].get()

        #Create that default file
        self.defaultjson = dict(operator_name=self.operator_entry.get(),
                                test_stand=self.selections[0].get(),
                                test_stand_other=self.other_entries[0].get(),
                                boardid=self.selections[1].get(),
                                boardid_other=self.other_entries[1].get(),
                                chipver=self.selections[2].get(),
                                chipver_other=self.other_entries[2].get(),
                                fpgamezz=self.selections[3].get(),
                                fpgamezz_other=self.other_entries[3].get())

        for i, chip in enumerate(
                range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                      int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1)):
            self.params['asic{}id'.format(chip)] = self.asic_entries[i].get()
            self.params['socket{}id'.format(
                chip)] = self.socket_entries[i].get()
            self.defaultjson['asic{}id'.format(
                chip)] = self.asic_entries[i].get()
            self.defaultjson['socket{}id'.format(
                chip)] = self.socket_entries[i].get()

        jsonFile = os.path.join(
            self.root_dir, self.config["FILENAMES"]["DEFAULT_GUI_FILE_NAME"])
        with open(jsonFile, 'w') as outfile:
            json.dump(self.defaultjson, outfile, indent=4)

    def start_warm_measurements(self):
        self.advanced_variables[1].set(value=False)
        self.start_measurements()

    def start_cold_measurements(self):
        self.advanced_variables[1].set(value=True)
        self.start_measurements()

    def start_measurements(self):
        self.write_default_file()
        self.clear_labels()
        #Make sure everything was entered ok, that nothing was screwed up
        gui_check = self.config["GUI_SETTINGS"]
        asic_tup = []
        sock_tup = []

        for i, chip in enumerate(
                range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                      int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1)):
            asic_tup.append("asic{}id".format(chip))
            sock_tup.append("socket{}id".format(chip))

        for i in asic_tup:
            j = self.params[i]
            if ((int(j) < int(gui_check['CHIP_MIN']))
                    or (int(j) > int(gui_check['CHIP_MAX']))):
                print("{}({}) is out of range ({} to {})!".format(
                    i, j, int(gui_check['CHIP_MIN']),
                    int(gui_check['CHIP_MAX'])))
                self.status_label["text"] = "ENTER REQUIRED INFO"
                self.update_idletasks()
                return

        for i in sock_tup:
            j = self.params[i]
            if ((int(j) < int(gui_check['SOCKET_MIN']))
                    or (int(j) > int(gui_check['SOCKET_MAX']))):
                print("{}({}) is out of range ({} to {})!".format(
                    i, j, int(gui_check['SOCKET_MIN']),
                    int(gui_check['SOCKET_MAX'])))
                self.status_label["text"] = "ENTER REQUIRED INFO"
                self.update_idletasks()
                return

        if not (self.params['operator_name'] and self.params['test_stand']
                and self.params['boardid'] and self.params['fpgamezz']
                and self.params['chipver']):
            print("ENTER REQUIRED INFO")
            self.status_label["text"] = "ENTER REQUIRED INFO"
            self.update_idletasks()
            return

        if (self.advanced_variables[0].get() == True):
            self.params['using_power_supply'] = True
            self.get_power_supply()
            if (self.PowerSupply.interface == None):
                return
            else:
                self.power_on()

        else:
            self.params['using_power_supply'] = False

        if (self.advanced_variables[1].get() == True):
            self.params['temperature'] = "LN"
            self.get_power_supply()

            if (self.PowerSupply.interface != None):
                self.power_on()

        else:
            self.params['temperature'] = "RT"

        fw_ver = self.functions.get_fw_version()
        self.params['fw_ver'] = hex(fw_ver)

        if (fw_ver < int(self.config["DEFAULT"]["LATEST_FW"], 16)):
            messagebox.showinfo(
                "Warning!",
                "The FPGA is running firmware version {} when the latest firmware is version {}.  Please let an expert know!"
                .format(hex(fw_ver),
                        hex(int(self.config["DEFAULT"]["LATEST_FW"], 16))))

        print("got here")
        self.functions.turnOnAsics()
        self.functions.resetBoard()

        responding_chips = self.functions.initBoard()
        self.chiplist = []
        working_chips = []
        for i, chip in enumerate(
                range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                      int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1)):
            tup = [i, self.params["asic{}id".format(chip)]]
            self.chiplist.append(tup)
            if (self.asic_enables[i].get() == True):
                if chip in (responding_chips):
                    working_chips.append(chip)

        self.params['working_chips'] = working_chips

        tests_to_do = []
        if (self.params['temperature'] == "LN"):
            for i in self.all_tests:
                if (i[0] != "Final"):
                    if ((i[1] == "basic") and (i[5].get() == True)):
                        tests_to_do.append([i[2], i[3]])

                    elif (self.analysis == "advanced" and i[1] == "advanced"
                          and i[5].get() == True):
                        tests_to_do.append([i[2], i[3]])

        else:
            sync = self.all_tests[0]
            tests_to_do.append([sync[2], sync[3]])
            alive = self.all_tests[3]
            tests_to_do.append([alive[2], alive[3]])

        self.params['tests_to_do'] = tests_to_do

        start_time = time.time()
        self.now = time.strftime("%Y%m%dT%H%M%S", time.localtime(time.time()))

        print("BEGIN TESTS")
        self.params.update(chip_list=self.chiplist)
        self.update_idletasks()
        params = None
        #Calls the new generic tester/runner.  Note that this is done in a for loop and the generic tester passes values back by using "Yield"
        #This is the only way I figured out how to get feedback back to the GUI mid-test without changing too much
        for i in (maintest(**self.params)):
            self.postResults(i)
            self.update_idletasks()
            params = i

        for i in self.working_chips:
            chip_name = self.chip_list[i][1]
            results_file = os.path.join(self.datadir, chip_name,
                                        "results.json")
            with open(results_file, 'r') as f:
                results = json.load(f)

            ver = {'verified': False}

            with open(results_file, 'w') as outfile:
                results.update(ver)
                json.dump(results, outfile, indent=4)

        self.postResults(params)

        end_time = time.time()
        self.status_label = "DONE"
        self.update_idletasks()
        response = CustomDialog(self,
                                power_supply=self.advanced_variables[0].get(),
                                PS=self.PowerSupply).show()

        for i in self.working_chips:
            chip_name = self.chip_list[i][1]
            results_file = os.path.join(self.datadir, chip_name,
                                        "results.json")
            with open(results_file, 'r') as f:
                results = json.load(f)

            ver = {'verified': str(response[i])}

            with open(results_file, 'w') as outfile:
                results.update(ver)
                json.dump(results, outfile, indent=4)

        run_time = end_time - start_time
        print("Total run time: {}".format(int(run_time)))
        self.functions.turnOffAsics()
        print(self.GetTimeString(int(run_time)))

        if (self.params['using_power_supply'] == True):
            self.power_off(channels=[2, 3])

    def change_analysis_level(self):
        if (self.analysis == "basic"):
            self.analysis = "advanced"
            for num, i in enumerate(self.all_tests):
                if (i[1] == "advanced"):
                    label = i[4]
                    label.grid(sticky=tk.W,
                               row=7,
                               column=self.midcolumnbase + num + 1)
                    button = i[6]
                    button.grid(row=6, column=self.midcolumnbase + num + 1)

                    for chips in range(
                            int(self.config["DEFAULT"]["NASIC_MIN"]),
                            int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1):
                        label = self.results_array[num][chips]
                        label.grid(stick=tk.W,
                                   row=8 + chips,
                                   column=self.midcolumnbase + num + 1)

            for num, i in enumerate(self.advanced_options):
                button = i[2]
                button.grid(row=1 + num, column=self.midcolumnbase + 2)
                label = i[1]
                label.grid(row=1 + num,
                           column=self.midcolumnbase + 3,
                           columnspan=3)

        elif (self.analysis == "advanced"):
            self.analysis = "basic"
            for num, i in enumerate(self.all_tests):
                if (i[1] == "advanced"):
                    label = i[4]
                    label.grid_forget()
                    button = i[6]
                    button.grid_forget()

                    for chips in range(
                            int(self.config["DEFAULT"]["NASIC_MIN"]),
                            int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1):
                        label = self.results_array[num][chips]
                        label.grid_forget()

                for num, i in enumerate(self.advanced_options):
                    button = i[2]
                    button.grid_forget()
                    label = i[1]
                    label.grid_forget()
        else:
            print(
                "GUI_ERROR --> Analysis level should only ever be 'basic' or 'advanced', it was {}"
                .format(self.analysis))

    def power_on(self):
        self.on_child_closing()
        self.PowerSupply = self.get_power_supply()
        if (self.PowerSupply != None):
            pwr = self.config["POWER_SUPPLY"]
            self.PowerSupply.on(channels=[
                int(pwr["PS_HEATING_CHN"]),
                int(pwr["PS_QUAD_CHN"]),
                int(pwr["PS_FPGA_CHN"])
            ])
        self.update_idletasks()
#        self.power_button["bg"]="green"

    def power_off(self, channels=[1, 2, 3]):
        self.on_child_closing()
        self.PowerSupply = self.get_power_supply()
        if (self.PowerSupply.interface != None):
            self.PowerSupply.off(channels=channels)
        self.update_idletasks()


#        self.power_button["bg"]="green"

    def test_connection(self):
        #TODO if not on already, turn on and wait
        self.on_child_closing()
        self.write_default_file()
        self.power_on()
        fw_ver = self.functions.get_fw_version()
        self.params['fw_ver'] = hex(fw_ver)

        if (fw_ver < int(self.config["DEFAULT"]["LATEST_FW"], 16)):
            messagebox.showinfo(
                "Warning!",
                "The FPGA is running firmware version {} when the latest firmware is version {}.  Please let an expert know!"
                .format(hex(fw_ver),
                        hex(int(self.config["DEFAULT"]["LATEST_FW"], 16))))

        self.functions.turnOnAsics()
        self.functions.resetBoard()
        SPI_response = self.functions.initBoard()

        temp_sync_folder = os.path.join(self.root_dir, "temp_sync_files")
        if not os.path.exists(temp_sync_folder):
            os.makedirs(temp_sync_folder)

        for thing in os.listdir(temp_sync_folder):
            file_path = os.path.join(temp_sync_folder, thing)
            try:
                if (os.path.isfile(file_path)):
                    os.unlink(file_path)
                if (os.path.isdir(file_path)):
                    shutil.rmtree(file_path)
            except Exception as e:
                print(e)

        chiplist = []
        for i, chip in enumerate(
                range(int(self.config["DEFAULT"]["NASIC_MIN"]),
                      int(self.config["DEFAULT"]["NASIC_MAX"]) + 1, 1)):
            tup = [i, self.params["asic{}id".format(chip)]]
            chiplist.append(tup)

        self.functions.syncADC(datadir=temp_sync_folder,
                               working_chips=SPI_response,
                               chip_list=chiplist,
                               to_print=True)

        self.WF_GUI = tk.Tk()
        self.WF_GUI.protocol("WM_DELETE_WINDOW", self.on_child_closing)
        startWF(self.WF_GUI)

    def debug(self):
        self.WF_GUI = tk.Tk()
        self.WF_GUI.protocol("WM_DELETE_WINDOW", self.on_child_closing)
        startWF(self.WF_GUI)

    def postResults(self, params):
        self.datadir = params['datadir']
        self.working_chips = params['working_chips']
        self.chip_list = params['chip_list']

        #just gets the first "results.json" from the first working chip, just to get the main test paramfile json location
        chip_name = self.chip_list[self.working_chips[0]][1]
        results_path = os.path.join(self.datadir, chip_name)
        jsonFile_chip = os.path.join(results_path,
                                     self.config["FILENAMES"]["RESULTS"])

        with open(jsonFile_chip, 'r') as f:
            test_list = json.load(f)

        paramfile = test_list["paramfile"]
        with open(paramfile, 'r') as f:
            param_json = json.load(f)
        #Now we have the json and can add to it during the loop

        for i in self.working_chips:
            chip_name = self.chip_list[i][1]
            results_path = os.path.join(self.datadir, chip_name)
            jsonFile_chip = os.path.join(results_path,
                                         self.config["FILENAMES"]["RESULTS"])
            #Now that we know what the timestamped directory is, we can have a button on the GUI open it directly
            self.details_label.bind(
                "<Button-1>",
                lambda event, arg=self.datadir: self.open_directory(arg))

            with open(jsonFile_chip, 'r') as f:
                test_list = json.load(f)

            overall_result = True

            if "sync_outlabel" in test_list:
                outlabel = test_list["sync_outlabel"]
                jsonFile = os.path.join(results_path, outlabel,
                                        self.config["FILENAMES"]["RESULTS"])
                with open(jsonFile, 'r') as f:
                    results = json.load(f)
                label = self.results_array[0][i]
                result = results['sync_result']
                test_list["sync_result"] = result
                if (result == "FAIL"):
                    bool_result = False
                else:
                    bool_result = True
                overall_result = overall_result and bool_result
                param_json["sync_result_{}".format(i)] = result
                self.update_label(label, result)
                linked_folder = os.path.join(results_path, outlabel)
                linked_file1 = self.config["FILENAMES"]["SYNC_LINK"].format(
                    chip_name)
                linked_file2 = self.config["FILENAMES"][
                    "SYNC_LINK_MONITOR"].format(chip_name)
                linked_file_path1 = os.path.join(linked_folder, linked_file1)
                linked_file_path2 = os.path.join(linked_folder, linked_file2)
                label.bind(
                    "<Button-1>",
                    lambda event, arg=linked_file_path1: self.link_label(arg))
                label.bind(
                    "<Button-3>",
                    lambda event, arg=linked_file_path2: self.link_label(arg))
            if "baseline_outlabel" in test_list:
                outlabel = test_list["baseline_outlabel"]
                jsonFile = os.path.join(results_path, outlabel,
                                        self.config["FILENAMES"]["RESULTS"])
                with open(jsonFile, 'r') as f:
                    results = json.load(f)
                label = self.results_array[1][i]
                result = results['baseline_result']
                test_list["baseline_result"] = result
                if (result == "FAIL"):
                    bool_result = False
                else:
                    bool_result = True
                overall_result = overall_result and bool_result
                param_json["baseline_result_{}".format(i)] = result
                self.update_label(label, result)
                linked_folder = os.path.join(results_path, outlabel)
                linked_file = self.config["FILENAMES"]["BASELINE_LINK"].format(
                    chip_name)
                linked_file_path = os.path.join(linked_folder, linked_file)
                label.bind(
                    "<Button-1>",
                    lambda event, arg=linked_file_path: self.link_label(arg))
            if "monitor_outlabel" in test_list:
                outlabel = test_list["monitor_outlabel"]
                jsonFile = os.path.join(results_path, outlabel,
                                        self.config["FILENAMES"]["RESULTS"])
                with open(jsonFile, 'r') as f:
                    results = json.load(f)
                label = self.results_array[2][i]
                result = results['monitor_result']
                test_list["monitor_result"] = result
                if (result == "FAIL"):
                    bool_result = False
                else:
                    bool_result = True
                overall_result = overall_result and bool_result
                param_json["monitor_result_{}".format(i)] = result
                self.update_label(label, result)
                linked_folder = os.path.join(results_path, outlabel)
                linked_file = self.config["FILENAMES"]["MONITOR_LINK"].format(
                    chip_name)
                linked_file_path = os.path.join(linked_folder, linked_file)
                label.bind(
                    "<Button-1>",
                    lambda event, arg=linked_file_path: self.link_label(arg))
            if "alive_outlabel" in test_list:
                outlabel = test_list["alive_outlabel"]
                jsonFile = os.path.join(results_path, outlabel,
                                        self.config["FILENAMES"]["RESULTS"])
                with open(jsonFile, 'r') as f:
                    results = json.load(f)
                label = self.results_array[3][i]
                result = results['alive_result']
                test_list["alive_result"] = result
                if (result == "FAIL"):
                    bool_result = False
                else:
                    bool_result = True
                overall_result = overall_result and bool_result
                param_json["alive_result_{}".format(i)] = result
                self.update_label(label, result)
                linked_folder = os.path.join(results_path, outlabel)
                linked_file = self.config["FILENAMES"]["ALIVE_LINK"].format(
                    chip_name)
                linked_file_path = os.path.join(linked_folder, linked_file)
                label.bind(
                    "<Button-1>",
                    lambda event, arg=linked_file_path: self.link_label(arg))
            if "verified" in test_list:
                if (overall_result):
                    overall_result_string = "PASS"
                else:
                    overall_result_string = "FAIL"
                param_json["overall_result_{}".format(
                    i)] = overall_result_string
                label = self.results_array[7][i]
                self.update_label(label, overall_result_string)

            with open(jsonFile_chip, 'w') as outfile:
                json.dump(test_list, outfile, indent=4)

        with open(paramfile, 'w') as outfile:
            json.dump(param_json, outfile, indent=4)

    def clear_labels(self):
        for i in range(8):
            for j in range(4):
                label = self.results_array[i][j]
                label["text"] = "----"
                label["fg"] = "black"

    def update_label(self, label, result):
        if (result == "PASS"):
            label["text"] = "Pass"
            label["fg"] = "green"
        elif (result == "FAIL"):
            label["text"] = "Fail"
            label["fg"] = "red"
        else:
            print(
                "Top_Level_GUI--> Incorrect result, must 'PASS' or 'FAIL', was {}"
                .format(result))

    def link_label(self, file):
        #eog is so it opens in the superior Image Viewer without all the junk in Image Magick
        subprocess.check_call(["eog", file])

    def open_directory(self, directory):
        #xdg-open is so it opens the directory as is
        subprocess.check_call(["xdg-open", directory])

    # Can add additional testing sequences like as above with a method name
    # like "do_<semantic_label>".
    def GetTimeString(self, t):
        sec = timedelta(seconds=t)
        d = datetime(1, 1, 1) + sec
        time_str = "{}:{}:{}".format(d.hour, d.minute, d.second)
        return time_str

    def on_closing(self, window):
        self.on_child_closing()
        window.destroy()
        window.quit()

    def on_child_closing(self):
        if (self.WF_GUI != None):
            self.WF_GUI.destroy()
            #self.WF_GUI.quit()
            self.WF_GUI = None

    def get_power_supply(self):

        if (self.advanced_variables[0].get() == True):
            if (self.PowerSupply.interface != None):
                self.set_supply_params()
                return (self.PowerSupply)
            else:
                self.PowerSupply = Power_Supply(self.config)
                if (self.PowerSupply.interface == None):
                    messagebox.showinfo(
                        "Warning!",
                        "No power supply device was detected!  Plug in the power supply and try again!  "
                        +
                        "If you want to run the test without the power supply connected, uncheck the box in 'Advanced Options', make sure to turn the power "
                        +
                        "on when testing at room temperature, off while cooling down, and on again when doing the cold test."
                    )
                    return (self.PowerSupply)

                else:
                    self.set_supply_params()
                    return (self.PowerSupply)
        else:
            print("Top Level GUI --> Not using Power Supply")

    def set_supply_params(self):
        pwr = self.config["POWER_SUPPLY"]
        self.PowerSupply.set_channel(channel=int(pwr["PS_HEATING_CHN"]),
                                     voltage=float(pwr["PS_HEATING_V"]),
                                     v_limit=float(pwr["PS_HEATING_V_LIMIT"]),
                                     c_limit=float(pwr["PS_HEATING_I_LIMIT"]),
                                     vp=pwr["PS_HEATING_V_PROTECTION"],
                                     cp=pwr["PS_HEATING_I_PROTECTION"])
        self.PowerSupply.set_channel(channel=int(pwr["PS_QUAD_CHN"]),
                                     voltage=float(pwr["PS_QUAD_V"]),
                                     v_limit=float(pwr["PS_QUAD_V_LIMIT"]),
                                     c_limit=float(pwr["PS_QUAD_I_LIMIT"]),
                                     vp=pwr["PS_QUAD_V_PROTECTION"],
                                     cp=pwr["PS_QUAD_I_PROTECTION"])
        self.PowerSupply.set_channel(channel=int(pwr["PS_FPGA_CHN"]),
                                     voltage=float(pwr["PS_FPGA_V"]),
                                     v_limit=float(pwr["PS_FPGA_V_LIMIT"]),
                                     c_limit=float(pwr["PS_FPGA_I_LIMIT"]),
                                     vp=pwr["PS_FPGA_V_PROTECTION"],
                                     cp=pwr["PS_FPGA_I_PROTECTION"])
        self.PowerSupply.on(channels=[
            int(pwr["PS_HEATING_CHN"]),
            int(pwr["PS_QUAD_CHN"]),
            int(pwr["PS_FPGA_CHN"])
        ])
示例#12
0
class BASELINE_TESTER(object):
    def __init__(self):
        self.config = CONFIG
        self.functions = FEMB_CONFIG_BASE(self.config)
        self.low_level = self.functions.lower_functions
        self.analyze = Data_Analysis(self.config)

        #json output, note module version number defined here
        self.jsondict = {'type': 'baseline_test'}
        self.jsondict['baseline_code_version'] = '1.1'
        self.jsondict['baseline_timestamp'] = datetime.datetime.today(
        ).strftime('%Y%m%d%H%M%S')

    def check_setup(self):
        print("BASELINE - SETUP")
        self.functions.initBoard(default_sync=False)
        if (self.params['using_power_supply'] == True):
            self.PowerSupply = Power_Supply(self.config)
            if (self.PowerSupply.interface == None):
                sys.exit("SYNCHRONIZATION --> Power Supply not found!")

    def record_data(self):
        print("BASELINE - COLLECT DATA")
        self.power_info_total = []
        for i in self.params['working_chips']:
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name,
                                             self.params["outlabel"])
            data_directory = os.path.join(
                chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
            os.makedirs(data_directory, exist_ok=True)
            self.low_level.femb_udp.write_reg(
                int(self.config["REGISTERS"]["REG_MUX_MODE"]),
                int(self.config["DEFINITIONS"]["MUX_GND_GND"]))

            self.gain = self.config["BASELINE_SETTINGS"]["BASELINE_GAIN"]
            self.shape = self.config["BASELINE_SETTINGS"]["BASELINE_PEAK"]
            self.leak = self.config["BASELINE_SETTINGS"]["BASELINE_LEAK"]
            self.buff = self.config["BASELINE_SETTINGS"]["BASELINE_BUFFER"]

            if (self.buff == "on"):
                self.low_level.femb_udp.write_reg(
                    int(self.config["REGISTERS"]["REG_SAMPLESPEED"]),
                    int(self.config["INITIAL_SETTINGS"]
                        ["DEFAULT_SAMPLE_SPEED"]))
            elif (self.buff == "off"):
                self.low_level.femb_udp.write_reg(
                    int(self.config["REGISTERS"]["REG_SAMPLESPEED"]),
                    int(self.config["INITIAL_SETTINGS"]
                        ["UNBUFFERED_SAMPLE_SPEED"]))
            else:
                print(
                    "FE_baseline_test --> buffer is not defined.  Should be 'on' or 'off', but is {}"
                    .format(self.buff))

            for base in ["200mV", "900mV"]:
                self.functions.configFeAsic(test_cap="off",
                                            base=base,
                                            gain=self.gain,
                                            shape=self.shape,
                                            monitor_ch=None,
                                            buffer=self.buff,
                                            leak=self.leak,
                                            monitor_param=None,
                                            s16=None,
                                            acdc="dc",
                                            test_dac="test_off",
                                            dac_value=0)

                self.functions.writeFE()

                for chn in range(
                        int(self.config["DEFAULT"]["NASICCH_MIN"]),
                        int(self.config["DEFAULT"]["NASICCH_MAX"]) + 1, 1):
                    self.low_level.selectChipChannel(chip=i, chn=chn)
                    baseline_file_notation = self.config["FILENAMES"][
                        "BASELINE_NAMING"]
                    filename = baseline_file_notation.format(
                        chn, self.gain, self.shape, self.leak, base, self.buff)
                    full_filename = os.path.join(data_directory, filename)
                    packets = int(
                        self.config["BASELINE_SETTINGS"]["BASELINE_PACKETS"])
                    rawdata = self.low_level.get_data_chipXchnX(
                        chip=i,
                        chn=chn,
                        packets=packets,
                        data_format="bin",
                        header=False)

                    with open(full_filename, "wb") as f:
                        f.write(rawdata)
                        f.close()

            power_info = self.functions.PCB_power_monitor(chips=i)
            self.power_info_total.append(power_info)

        if (self.params['using_power_supply'] == True):
            pwr = self.config["POWER_SUPPLY"]
            self.heating_results = self.PowerSupply.measure_params(
                channel=int(pwr["PS_HEATING_CHN"]))
            self.quad_results = self.PowerSupply.measure_params(
                channel=int(pwr["PS_QUAD_CHN"]))
            self.fpga_results = self.PowerSupply.measure_params(
                channel=int(pwr["PS_FPGA_CHN"]))

        self.low_level.femb_udp.write_reg(
            int(self.config["REGISTERS"]["REG_SAMPLESPEED"]),
            int(self.config["INITIAL_SETTINGS"]["DEFAULT_SAMPLE_SPEED"]))

    def do_analysis(self):
        print("BASELINE - ANALYZE")
        analysis = ["mean"]
        self.results = []
        self.average_baseline_200 = []
        self.average_baseline_900 = []
        self.baseline_200 = []
        self.baseline_900 = []
        for i in self.params["working_chips"]:
            chip_name = self.params['chip_list'][i][1]
            chip_outpathlabel = os.path.join(self.params["datadir"], chip_name,
                                             self.params["outlabel"])
            data_directory = os.path.join(
                chip_outpathlabel, self.config["FILENAMES"]["DATA_NAME"])
            result, average_200, average_900, baselines_200, baselines_900 = self.analyze.baseline_directory(
                chip_outpathlabel, data_directory, chip_name, i, analysis)
            self.results.append(result)
            self.average_baseline_200.append(average_200)
            self.average_baseline_900.append(average_900)
            self.baseline_200.append(baselines_200)
            self.baseline_900.append(baselines_900)

    def archiveResults(self):
        print("BASELINE - ARCHIVE")

        self.jsondict['baseline_executable'] = self.params['executable']
        self.jsondict['baseline_datasubdir'] = self.params['datasubdir']
        self.jsondict['baseline_outlabel'] = self.params['outlabel']
        self.jsondict['baseline_gain'] = self.config["BASELINE_SETTINGS"][
            "BASELINE_GAIN"]
        self.jsondict['baseline_peak'] = self.config["BASELINE_SETTINGS"][
            "BASELINE_PEAK"]
        self.jsondict['baseline_leak'] = self.config["BASELINE_SETTINGS"][
            "BASELINE_LEAK"]
        self.jsondict['baseline_buffer'] = self.config["BASELINE_SETTINGS"][
            "BASELINE_BUFFER"]

        if (self.params['using_power_supply'] == True):
            self.jsondict['PS_heating_voltage'] = self.heating_results[0]
            self.jsondict['PS_heating_current'] = self.heating_results[1]
            self.jsondict['PS_quad_voltage'] = self.quad_results[0]
            self.jsondict['PS_quad_current'] = self.quad_results[1]
            self.jsondict['PS_fpga_voltage'] = self.fpga_results[0]
            self.jsondict['PS_fpga_current'] = self.fpga_results[1]

        for num, i in enumerate(self.params['working_chips']):
            chip_name = self.params['chip_list'][i][1]
            jsonFile = os.path.join(self.params["datadir"], chip_name,
                                    self.params["datasubdir"],
                                    self.params["outlabel"],
                                    self.config["FILENAMES"]["RESULTS"])
            if (self.results[num] == True):
                self.jsondict['baseline_result'] = "PASS"
            elif (self.results[num] == False):
                self.jsondict['baseline_result'] = "FAIL"
            else:
                self.jsondict['baseline_result'] = "N/A"

            self.jsondict['baseline_200_average'] = self.average_baseline_200[
                num]
            self.jsondict['baseline_900_average'] = self.average_baseline_900[
                num]
            self.jsondict['vdda_shunt_voltage'] = self.power_info_total[num][
                0][0]
            self.jsondict['vdda_bus_voltage'] = self.power_info_total[num][0][
                1]
            self.jsondict['vdda_current'] = self.power_info_total[num][0][2]
            self.jsondict['vddp_shunt_voltage'] = self.power_info_total[num][
                1][0]
            self.jsondict['vddp_bus_voltage'] = self.power_info_total[num][1][
                1]
            self.jsondict['vddp_current'] = self.power_info_total[num][1][2]

            for chn in range(int(self.config["DEFAULT"]["NASICCH_MIN"]),
                             int(self.config["DEFAULT"]["NASICCH_MAX"]) + 1,
                             1):
                jsname = "baseline_200_channel{}".format(chn)
                self.jsondict[jsname] = self.baseline_200[num][chn]
                jsname = "baseline_900_channel{}".format(chn)
                self.jsondict[jsname] = self.baseline_900[num][chn]

            with open(jsonFile, 'a') as outfile:
                json.dump(self.jsondict, outfile, indent=4)

            jsonFile = os.path.join(self.params["datadir"], chip_name,
                                    self.params["datasubdir"],
                                    self.config["FILENAMES"]["RESULTS"])
            with open(jsonFile, 'r') as f:
                existing_json = json.load(f)

            existing_json['baseline_outlabel'] = self.params['outlabel']
            with open(jsonFile, 'w') as outfile:
                json.dump(existing_json, outfile, indent=4)