Esempio n. 1
0
    def __init__(self, config_file='default.cfg'):
        """
        Reads in the param file and opens appropriate flat file.  Sets wavelength binning parameters.
        """
        # define the configuration file path
        self.frames = []
        self.config_file = config_file

        # check the configuration file path and read it in
        self._configCheck(0)
        self.config = ConfigParser()
        self.config.read(self.config_file)

        # check the configuration file format and load the parameters
        self._configCheck(1)
        self.wvlCalFile = ast.literal_eval(self.config['Data']['wvlCalFile'])
        self.flatPath = ast.literal_eval(self.config['Data']['flatPath'])
        self.intTime = ast.literal_eval(self.config['Data']['intTime'])
        self.expTime = ast.literal_eval(self.config['Data']['expTime'])
        self.deadtime = ast.literal_eval(self.config['Instrument']['deadtime'])
        self.energyBinWidth = ast.literal_eval(self.config['Instrument']['energyBinWidth'])
        self.wvlStart = ast.literal_eval(self.config['Instrument']['wvlStart'])
        self.wvlStop = ast.literal_eval(self.config['Instrument']['wvlStop'])
        self.countRateCutoff = ast.literal_eval(self.config['Calibration']['countRateCutoff'])
        self.fractionOfChunksToTrim = ast.literal_eval(self.config['Calibration']['fractionOfChunksToTrim'])
        self.verbose = ast.literal_eval(self.config['Output']['verbose'])
        self.calSolnPath = ast.literal_eval(self.config['Output']['calSolnPath'])
        self.save_plots = ast.literal_eval(self.config['Output']['save_plots'])
        if self.save_plots:
            answer = self._query("Save Plots flag set to 'yes', this will add ~30 min to the code.  "
                                 "Are you sure you want to save plots?", yes_or_no=True)
            if answer is False:
                self.save_plots = False
                print('Setting save_plots parameter to FALSE')
        self.timeSpacingCut = None

        # check the parameter formats
        self._configCheck(2)

        self.obsList = [ObsFile(self.flatPath)]
        self.flatCalFileName = self.calSolnPath + 'flatcalsoln.h5'
        self.out_directory = self.calSolnPath

        # get beammap from first obs
        self.beamImage = self.obsList[0].beamImage
        self.wvlFlags = self.obsList[0].beamFlagImage
        self.nxpix = self.obsList[0].nXPix
        self.nypix = self.obsList[0].nYPix
        self.wvlBinEdges = ObsFile.makeWvlBins(self.energyBinWidth, self.wvlStart, self.wvlStop)

        # wvlBinEdges includes both lower and upper limits, so number of bins is 1 less than number of edges
        self.nWvlBins = len(self.wvlBinEdges) - 1
        if self.verbose:
            print('Computing Factors for FlatCal')
            self.pbar = ProgressBar(widgets=[Percentage(), Bar(), '  (', Timer(), ') ', ETA(), ' '],
                                    max_value=4 * len(range(0, self.expTime, self.intTime))).start()
            self.pbar_iter = 0
Esempio n. 2
0
def populateFlatCals(runPath, lookupPath=None):
    if lookupPath is None:
        lookupPath = os.environ['MKID_CAL_LOOKUP']
    if not os.path.exists(path):
        writeNewCalLookupFile(path)

    lookup = CalLookupFile(path, mode='a')

    for root, dirs, files in os.walk(runPath):
        obsFilenames = fnmatch.filter(files, 'obs*.h5')
        for obsFilename in obsFilenames:
            obsPath = os.path.join(root, obsFilename)

            try:
                obs = ObsFile(obsPath)
                fn = FileName(obsFile=obsPath)
                params = {}
                params['obs_run'], params['obs_date'], params[
                    'obs_tstamp'] = fn.getComponents()
                params['flatSoln_run'] = params['obs_run']

                if params['obs_date'] in [
                        '20140923', '20140924', '20141020', '20141021',
                        '20141022'
                ]:
                    params['flatSoln_date'] = params['obs_date']
                else:
                    if params['obs_date'] == '20140925':
                        params['flatSoln_date'] = '20140924'
                print(params)
                lookup.updateObs(newParams=params)
            except:
                pass
Esempio n. 3
0
def getPixelPhotonList(filename, xCoord, yCoord, **kwargs):
    """
    Gets the list of photon arrival times from a H5 file
    
    INPUTS:
        filename - Name of H5 data file
        xCoord - 
        yCoord - 
        **kwargs - keywords for Obsfile getpixelphotonlist()
    OUTPUTS:
        ts - timestamps in us of photon arrival times
    """
    obs = ObsFile(filename)
    photonList = obs.getPixelPhotonList(xCoord, yCoord, **kwargs)
    times = photonList['Time']
    print("#photons: " + str(len(times)))
    del obs  #make sure to close files nicely
    return times
Esempio n. 4
0
def populateWaveCals(runPath, lookupPath=None):
    if lookupPath is None:
        lookupPath = os.environ['MKID_CAL_LOOKUP']
    if not os.path.exists(path):
        writeNewCalLookupFile(path)

    lookup = CalLookupFile(path, mode='a')
    for root, dirs, files in os.walk(runPath):
        obsFilenames = fnmatch.filter(files, 'obs*.h5')
        for obsFilename in obsFilenames:
            obsPath = os.path.join(root, obsFilename)

            try:
                obs = ObsFile(obsPath)
                fn = FileName(obsFile=obsPath)
                params = {}
                params['obs_run'], params['obs_date'], params[
                    'obs_tstamp'] = fn.getComponents()
                params['waveSoln_run'] = params['obs_run']

                obs.loadBestWvlCalFile()
                waveCalPath = obs.wvlCalFileName
                waveCalFilename = os.path.basename(waveCalPath)
                if waveCalFilename.startswith('master'):
                    params['waveSoln_isMasterCal'] = True
                    tstamp = waveCalFilename.split('_')[1].split('.')[0]
                    params['waveSoln_tstamp'] = tstamp
                    params['waveSoln_date'] = ''
                else:
                    params['waveSoln_isMasterCal'] = False
                    tstamp = waveCalFilename.split('_')[1].split('.')[0]
                    params['waveSoln_tstamp'] = tstamp
                    dirs = os.path.dirname(
                        os.path.normpath(waveCalPath)).split(os.sep)
                    params['waveSoln_date'] = dirs[-1]
                print(params)
                lookup.updateObs(newParams=params)
            except:
                pass
Esempio n. 5
0
    def loadDataFromH5(self, *args):
        #a = darkObsFile.ObsFile('/Users/clint/Documents/mazinlab/ScienceData/PAL2017b/20171004/1507175503.h5')
        if os.path.isfile(self.filename):
            try:
                self.a = ObsFile(self.filename)
            except:
                print('darkObsFile failed to load file. Check filename.\n',
                      self.filename)
            else:
                print('data loaded from .h5 file')
                self.h5_filename_label.setText(self.filename)
                self.initializeEmptyArrays(len(self.a.beamImage),
                                           len(self.a.beamImage[0]))
                self.beamFlagImage = np.transpose(self.a.beamFlagImage.read())
                self.beamFlagMask = self.beamFlagImage == 0  #make a mask. 0 for good beam map
                self.makeHotPixMask()
                self.radio_button_beamFlagImage.setChecked(True)
                self.callPlotMethod()
                #set the max integration time to the h5 exp time in the header
                self.expTime = self.a.getFromHeader('expTime')
                self.wvlBinStart = self.a.getFromHeader('wvlBinStart')
                self.wvlBinEnd = self.a.getFromHeader('wvlBinEnd')

                #set the max and min values for the lambda spinboxes
                #                self.spinbox_startLambda.setMinimum(self.wvlBinStart)
                self.spinbox_stopLambda.setMinimum(self.wvlBinStart)
                self.spinbox_startLambda.setMaximum(self.wvlBinEnd)
                self.spinbox_stopLambda.setMaximum(self.wvlBinEnd)
                self.spinbox_startLambda.setValue(self.wvlBinStart)
                self.spinbox_stopLambda.setValue(self.wvlBinEnd)

                #set the max value of the integration time spinbox
                self.spinbox_startTime.setMinimum(0)
                self.spinbox_startTime.setMaximum(self.expTime)
                self.spinbox_integrationTime.setMinimum(0)
                self.spinbox_integrationTime.setMaximum(self.expTime)
                self.spinbox_integrationTime.setValue(self.expTime)
Esempio n. 6
0
def populateTimeMasks(runPath, lookupPath=None):
    if lookupPath is None:
        lookupPath = os.environ['MKID_CAL_LOOKUP']
    if not os.path.exists(path):
        writeNewCalLookupFile(path)

    lookup = CalLookupFile(path, mode='a')
    for root, dirs, files in os.walk(runPath):
        obsFilenames = fnmatch.filter(files, 'obs*.h5')
        for obsFilename in obsFilenames:
            obsPath = os.path.join(root, obsFilename)

            try:
                obs = ObsFile(obsPath)
                fn = FileName(obsFile=obsPath)
                params = {}
                params['obs_run'], params['obs_date'], params[
                    'obs_tstamp'] = fn.getComponents()
                params['timeMask_run'], params['timeMask_date'], params[
                    'timeMask_tstamp'] = fn.getComponents()
                print(params)
                lookup.updateObs(newParams=params)
            except:
                pass
Esempio n. 7
0
    9459, 9460, 9461, 9462, 9463, 9464, 9465, 9466, 9467, 9468, 9469, 9470,
    9471, 9472, 9473, 9474, 9475, 9476, 9477, 9478, 9479, 9480, 9481, 9482,
    9483, 9484, 9485, 9486, 9487, 9488, 9489, 9490, 9491, 9492, 9493, 9494,
    9495, 9496, 9497, 9498, 9499, 9500, 9501, 9502, 9503, 9504, 9505
])

print('Warning: Only run this script once per file')
print(fns)
tmp = ''
while tmp not in ['Y', 'N']:
    tmp = input('Are you sure you want to run this script? (Y/N)')
    tmp = tmp.upper()
if tmp == 'Y':
    for fn in fns:
        print('Adjusting flags in: ' + fn)
        obs = ObsFile(fn, mode='w')
        resIDs = obs.beamImage[:, :]
        flags = obs.beamFlagImage[:, :]

        resID_noBeammap = resIDs[np.where(np.bitwise_and(flags, 1) > 0)]
        resID_beammap = resIDs[np.where(np.bitwise_and(flags, 1) == 0)]
        print('ResIDs with a DAC Tone that failed the beammap:')
        print(resID_withTone[np.where(np.isin(resID_withTone,
                                              resID_noBeammap))])
        print(
            'ResIDs without a DAC Tone that passed the beammaped (should be none):'
        )
        print(resID_beammap[np.where(
            np.isin(resID_beammap, resID_withTone, invert=True))])

        resID_wvlCal = resIDs[np.where(np.bitwise_and(flags, 2) == 0)]
Esempio n. 8
0
class mainWindow(QMainWindow):

    updateActivePix = pyqtSignal()

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent=parent)
        self.initializeEmptyArrays()
        self.setWindowTitle('quickLook.py')
        self.resize(
            600, 850
        )  #(600,850 works for clint's laptop screen. Units are pixels I think.)
        self.create_main_frame()
        self.create_status_bar()
        self.createMenu()
        self.plotNoise()

    def initializeEmptyArrays(self, nCol=10, nRow=10):
        self.nCol = nCol
        self.nRow = nRow
        self.IcMap = np.zeros(self.nRow * self.nCol).reshape(
            (self.nRow, self.nCol))
        self.IsMap = np.zeros(self.nRow * self.nCol).reshape(
            (self.nRow, self.nCol))
        self.IcIsMap = np.zeros(self.nRow * self.nCol).reshape(
            (self.nRow, self.nCol))
        self.rawCountsImage = np.zeros(self.nRow * self.nCol).reshape(
            (self.nRow, self.nCol))
        self.hotPixMask = np.zeros(self.nRow * self.nCol).reshape(
            (self.nRow, self.nCol))
        self.hotPixCut = 2300
        self.image = np.zeros(self.nRow * self.nCol).reshape(
            (self.nRow, self.nCol))
        self.activePixel = [0, 0]
        self.sWindowList = []

    def loadDataFromH5(self, *args):
        #a = darkObsFile.ObsFile('/Users/clint/Documents/mazinlab/ScienceData/PAL2017b/20171004/1507175503.h5')
        if os.path.isfile(self.filename):
            try:
                self.a = ObsFile(self.filename)
            except:
                print('darkObsFile failed to load file. Check filename.\n',
                      self.filename)
            else:
                print('data loaded from .h5 file')
                self.h5_filename_label.setText(self.filename)
                self.initializeEmptyArrays(len(self.a.beamImage),
                                           len(self.a.beamImage[0]))
                self.beamFlagImage = np.transpose(self.a.beamFlagImage.read())
                self.beamFlagMask = self.beamFlagImage == 0  #make a mask. 0 for good beam map
                self.makeHotPixMask()
                self.radio_button_beamFlagImage.setChecked(True)
                self.callPlotMethod()
                #set the max integration time to the h5 exp time in the header
                self.expTime = self.a.getFromHeader('expTime')
                self.wvlBinStart = self.a.getFromHeader('wvlBinStart')
                self.wvlBinEnd = self.a.getFromHeader('wvlBinEnd')

                #set the max and min values for the lambda spinboxes
                #                self.spinbox_startLambda.setMinimum(self.wvlBinStart)
                self.spinbox_stopLambda.setMinimum(self.wvlBinStart)
                self.spinbox_startLambda.setMaximum(self.wvlBinEnd)
                self.spinbox_stopLambda.setMaximum(self.wvlBinEnd)
                self.spinbox_startLambda.setValue(self.wvlBinStart)
                self.spinbox_stopLambda.setValue(self.wvlBinEnd)

                #set the max value of the integration time spinbox
                self.spinbox_startTime.setMinimum(0)
                self.spinbox_startTime.setMaximum(self.expTime)
                self.spinbox_integrationTime.setMinimum(0)
                self.spinbox_integrationTime.setMaximum(self.expTime)
                self.spinbox_integrationTime.setValue(self.expTime)

    def plotBeamImage(self):
        #check if obsfile object exists
        try:
            self.a
        except:
            print('\nNo obsfile object defined. Select H5 file to load.\n')
            return
        else:

            #clear the axes
            self.ax1.clear()

            self.image = self.beamFlagImage

            self.cbarLimits = np.array(
                [np.amin(self.image), np.amax(self.image)])

            self.ax1.imshow(self.image, interpolation='none')
            self.fig.cbar.set_clim(np.amin(self.image), np.amax(self.image))
            self.fig.cbar.draw_all()

            self.ax1.set_title('beam flag image')

            self.ax1.axis('off')

            self.cursor = Cursor(self.ax1,
                                 useblit=True,
                                 color='red',
                                 linewidth=2)

            self.draw()

    def plotImage(self, *args):
        #check if obsfile object exists
        try:
            self.a
        except:
            print('\nNo obsfile object defined. Select H5 file to load.\n')
            return
        else:

            #clear the axes
            self.ax1.clear()

            temp = self.a.getPixelCountImage(
                firstSec=self.spinbox_startTime.value(),
                integrationTime=self.spinbox_integrationTime.value(),
                applyWeight=False,
                flagToUse=0,
                wvlStart=self.spinbox_startLambda.value(),
                wvlStop=self.spinbox_stopLambda.value())
            self.rawCountsImage = np.transpose(temp['image'])

            self.image = self.rawCountsImage
            self.image[np.where(np.logical_not(np.isfinite(self.image)))] = 0
            #            self.image = self.rawCountsImage*self.beamFlagMask
            #self.image = self.rawCountsImage*self.beamFlagMask*self.hotPixMask
            self.image = 1.0 * self.image / self.spinbox_integrationTime.value(
            )

            self.cbarLimits = np.array(
                [np.amin(self.image), np.amax(self.image)])

            self.ax1.imshow(self.image,
                            interpolation='none',
                            vmin=self.cbarLimits[0],
                            vmax=self.cbarLimits[1])

            self.fig.cbar.set_clim(self.cbarLimits[0], self.cbarLimits[1])
            self.fig.cbar.draw_all()

            self.ax1.set_title('Raw counts')

            self.ax1.axis('off')

            self.cursor = Cursor(self.ax1,
                                 useblit=True,
                                 color='red',
                                 linewidth=2)

            #self.ax1.plot(np.arange(10),np.arange(10)**2)

            self.draw()

    def plotIcIs(self):
        #check if obsfile object exists
        try:
            self.a
        except:
            print('\nNo obsfile object defined. Select H5 file to load.\n')
            return
        else:
            self.ax1.clear()  #clear the axes

            for col in range(self.nCol):
                print(col, '/80')
                for row in range(self.nRow):
                    photonList = self.a.getPixelPhotonList(
                        col,
                        row,
                        firstSec=self.spinbox_startTime.value(),
                        integrationTime=self.spinbox_integrationTime.value(),
                        wvlStart=self.spinbox_startLambda.value(),
                        wvlStop=self.spinbox_stopLambda.value())

                    effExpTime = .00001  #10 ms/1000

                    lightCurveIntensityCounts, lightCurveIntensity, lightCurveTimes = binnedRE.getLightCurve(
                        photonList['Time'], self.spinbox_startTime.value(),
                        self.spinbox_startTime.value() +
                        self.spinbox_integrationTime.value(), effExpTime)

                    intensityHist, bins = binnedRE.histogramLC(
                        lightCurveIntensityCounts)
                    # [self.intensityHist] = counts

                    Nbins = max(30, len(bins))

                    if np.sum(lightCurveIntensityCounts) > 0:

                        Ic_final, Is_final, covMatrix = binnedRE.fitBlurredMR(
                            bins, intensityHist, effExpTime)

                        self.IcMap[row][col] = Ic_final
                        self.IsMap[row][col] = Is_final

            self.image = self.IsMap
            self.image[np.where(np.logical_not(np.isfinite(self.image)))] = 0
            #            self.image = self.rawCountsImage*self.beamFlagMask
            #self.image = self.rawCountsImage*self.beamFlagMask*self.hotPixMask
            #            self.image = 1.0*self.image/self.spinbox_integrationTime.value()

            self.cbarLimits = np.array(
                [np.amin(self.image), np.amax(self.image)])

            self.ax1.imshow(self.image,
                            interpolation='none',
                            vmin=self.cbarLimits[0],
                            vmax=self.cbarLimits[1])

            self.fig.cbar.set_clim(self.cbarLimits[0], self.cbarLimits[1])
            self.fig.cbar.draw_all()

            self.ax1.set_title('Raw counts')

            self.ax1.axis('off')

            self.cursor = Cursor(self.ax1,
                                 useblit=True,
                                 color='red',
                                 linewidth=2)

            self.draw()

    def plotNoise(self, *args):
        #clear the axes
        self.ax1.clear()

        #debugging- generate some noise to plot
        self.image = np.random.randn(self.nRow, self.nCol)

        self.foo = self.ax1.imshow(self.image, interpolation='none')
        self.cbarLimits = np.array([np.amin(self.image), np.amax(self.image)])
        self.fig.cbar.set_clim(self.cbarLimits[0], self.cbarLimits[1])
        self.fig.cbar.draw_all()

        self.ax1.set_title('some generated noise...')

        self.ax1.axis('off')

        self.cursor = Cursor(self.ax1, useblit=True, color='red', linewidth=2)

        self.draw()

    def callPlotMethod(self):
        if self.radio_button_img.isChecked() == True:
            self.plotNoise()
        elif self.radio_button_ic_is.isChecked() == True:
            self.plotIcIs()
        elif self.radio_button_beamFlagImage.isChecked() == True:
            self.plotBeamImage()
        elif self.radio_button_rawCounts.isChecked() == True:
            self.plotImage()
        else:
            self.plotNoise()

    def makeHotPixMask(self):
        #if self.hotPixMask[row][col] = 0, it's a hot pixel. If 1, it's good.
        temp = self.a.getPixelCountImage(firstSec=0,
                                         integrationTime=1,
                                         applyWeight=False,
                                         flagToUse=0)
        rawCountsImage = np.transpose(temp['image'])
        for col in range(self.nCol):
            for row in range(self.nRow):
                if rawCountsImage[row][col] < self.hotPixCut:
                    self.hotPixMask[row][col] = 1

    def create_main_frame(self):
        """
        Makes GUI elements on the window
        """
        #Define the plot window.
        self.main_frame = QWidget()
        self.dpi = 100
        self.fig = Figure(
            (5.0, 10.0), dpi=self.dpi,
            tight_layout=True)  #define the figure, set the size and resolution
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.main_frame)
        self.ax1 = self.fig.add_subplot(111)
        self.foo = self.ax1.imshow(self.image, interpolation='none')
        self.fig.cbar = self.fig.colorbar(self.foo)

        button_plot = QPushButton("Plot image")
        button_plot.setEnabled(True)
        button_plot.setToolTip('Click to update image.')
        button_plot.clicked.connect(self.callPlotMethod)

        button_quickLoad = QPushButton("Quick Load H5")
        button_quickLoad.setEnabled(True)
        button_quickLoad.setToolTip('Will change functionality later.')
        button_quickLoad.clicked.connect(self.quickLoadH5)

        #spinboxes for the start & stop times
        self.spinbox_startTime = QSpinBox()
        self.spinbox_integrationTime = QSpinBox()

        #labels for the start/stop time spinboxes
        label_startTime = QLabel('start time')
        label_integrationTime = QLabel('integration time')

        #spinboxes for the start & stop wavelengths
        self.spinbox_startLambda = QSpinBox()
        self.spinbox_stopLambda = QSpinBox()

        #labels for the start/stop time spinboxes
        label_startLambda = QLabel('start wavelength [nm]')
        label_stopLambda = QLabel('stop wavelength [nm]')

        #label for the filenames
        self.h5_filename_label = QLabel('no file loaded')

        #label for the active pixel
        self.activePixel_label = QLabel('Active Pixel ({},{}) {}'.format(
            self.activePixel[0], self.activePixel[1],
            self.image[self.activePixel[1], self.activePixel[0]]))

        #make the radio buttons
        #self.radio_button_noise = QRadioButton("Noise")
        self.radio_button_img = QRadioButton(".IMG")
        self.radio_button_ic_is = QRadioButton("Ic/Is")
        #self.radio_button_bin = QRadioButton(".bin")
        #self.radio_button_decorrelationTime = QRadioButton("Decorrelation Time")
        self.radio_button_beamFlagImage = QRadioButton("Beam Flag Image")
        self.radio_button_rawCounts = QRadioButton("Raw Counts")
        self.radio_button_img.setChecked(True)

        #create a vertical box for the plot to go in.
        vbox_plot = QVBoxLayout()
        vbox_plot.addWidget(self.canvas)

        #create a v box for the timespan spinboxes
        vbox_timespan = QVBoxLayout()
        vbox_timespan.addWidget(label_startTime)
        vbox_timespan.addWidget(self.spinbox_startTime)
        vbox_timespan.addWidget(label_integrationTime)
        vbox_timespan.addWidget(self.spinbox_integrationTime)

        #create a v box for the wavelength spinboxes
        vbox_lambda = QVBoxLayout()
        vbox_lambda.addWidget(label_startLambda)
        vbox_lambda.addWidget(self.spinbox_startLambda)
        vbox_lambda.addWidget(label_stopLambda)
        vbox_lambda.addWidget(self.spinbox_stopLambda)

        #create an h box for the buttons
        hbox_buttons = QHBoxLayout()
        hbox_buttons.addWidget(button_plot)
        hbox_buttons.addWidget(
            button_quickLoad
        )  #################################################

        #create an h box for the time and lambda v boxes
        hbox_time_lambda = QHBoxLayout()
        hbox_time_lambda.addLayout(vbox_timespan)
        hbox_time_lambda.addLayout(vbox_lambda)

        #create a v box combining spinboxes and buttons
        vbox_time_lambda_buttons = QVBoxLayout()
        vbox_time_lambda_buttons.addLayout(hbox_time_lambda)
        vbox_time_lambda_buttons.addLayout(hbox_buttons)

        #create a v box for the radio buttons
        vbox_radio_buttons = QVBoxLayout()
        #vbox_radio_buttons.addWidget(self.radio_button_noise)
        vbox_radio_buttons.addWidget(self.radio_button_img)
        vbox_radio_buttons.addWidget(self.radio_button_ic_is)
        #vbox_radio_buttons.addWidget(self.radio_button_bin)
        #vbox_radio_buttons.addWidget(self.radio_button_decorrelationTime)
        vbox_radio_buttons.addWidget(self.radio_button_beamFlagImage)
        vbox_radio_buttons.addWidget(self.radio_button_rawCounts)

        #create a h box combining the spinboxes, buttons, and radio buttons
        hbox_controls = QHBoxLayout()
        hbox_controls.addLayout(vbox_time_lambda_buttons)
        hbox_controls.addLayout(vbox_radio_buttons)

        #create a v box for showing the files that are loaded in memory
        vbox_filenames = QVBoxLayout()
        vbox_filenames.addWidget(self.h5_filename_label)
        vbox_filenames.addWidget(self.activePixel_label)

        #Now create another vbox, and add the plot vbox and the button's hbox to the new vbox.
        vbox_combined = QVBoxLayout()
        vbox_combined.addLayout(vbox_plot)
        vbox_combined.addLayout(hbox_controls)
        vbox_combined.addLayout(vbox_filenames)

        #Set the main_frame's layout to be vbox_combined
        self.main_frame.setLayout(vbox_combined)

        #Set the overall QWidget to have the layout of the main_frame.
        self.setCentralWidget(self.main_frame)

        #set up the pyqt5 events
        cid = self.fig.canvas.mpl_connect('motion_notify_event',
                                          self.hoverCanvas)
        cid2 = self.fig.canvas.mpl_connect('button_press_event',
                                           self.mousePressed)
        cid3 = self.fig.canvas.mpl_connect('scroll_event',
                                           self.scroll_ColorBar)

    def quickLoadH5(self):
        self.filename = '/Users/clint/Documents/mazinlab/ScienceData/PAL2017b/20171004/1507175503_old.h5'
        self.loadDataFromH5()

    def draw(self):
        #The plot window calls this function
        self.canvas.draw()
        self.canvas.flush_events()

    def hoverCanvas(self, event):
        if event.inaxes is self.ax1:
            col = int(round(event.xdata))
            row = int(round(event.ydata))
            if row < self.nRow and col < self.nCol:
                self.status_text.setText('({:d},{:d}) {}'.format(
                    col, row, self.image[row, col]))

    def scroll_ColorBar(self, event):
        if event.inaxes is self.fig.cbar.ax:
            stepSize = 0.1  #fractional change in the colorbar scale
            if event.button == 'up':
                self.cbarLimits[1] *= (1 + stepSize)  #increment by step size
                self.fig.cbar.set_clim(self.cbarLimits[0], self.cbarLimits[1])
                self.fig.cbar.draw_all()
                self.ax1.imshow(self.image,
                                interpolation='none',
                                vmin=self.cbarLimits[0],
                                vmax=self.cbarLimits[1])
            elif event.button == 'down':
                self.cbarLimits[1] *= (1 - stepSize)  #increment by step size
                self.fig.cbar.set_clim(self.cbarLimits[0], self.cbarLimits[1])
                self.fig.cbar.draw_all()
                self.ax1.imshow(self.image,
                                interpolation='none',
                                vmin=self.cbarLimits[0],
                                vmax=self.cbarLimits[1])

            else:
                pass

        self.draw()

    def mousePressed(self, event):
        #        print('\nclick event registered!\n')
        if event.inaxes is self.ax1:  #check if the mouse-click was within the axes.
            #print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %('double' if event.dblclick else 'single', event.button,event.x, event.y, event.xdata, event.ydata))

            if event.button == 1:
                #print('\nit was the left button that was pressed!\n')
                col = int(round(event.xdata))
                row = int(round(event.ydata))
                self.activePixel = [col, row]
                self.activePixel_label.setText(
                    'Active Pixel ({},{}) {}'.format(
                        self.activePixel[0], self.activePixel[1],
                        self.image[self.activePixel[1], self.activePixel[0]]))

                self.updateActivePix.emit(
                )  #emit a signal for other plots to update

            elif event.button == 3:
                print('\nit was the right button that was pressed!\n')

        elif event.inaxes is self.fig.cbar.ax:  #reset the scale bar
            if event.button == 1:
                self.cbarLimits = np.array(
                    [np.amin(self.image),
                     np.amax(self.image)])
                self.fig.cbar.set_clim(self.cbarLimits[0], self.cbarLimits[1])
                self.fig.cbar.draw_all()
                self.ax1.imshow(self.image,
                                interpolation='none',
                                vmin=self.cbarLimits[0],
                                vmax=self.cbarLimits[1])
                self.draw()
        else:
            pass

    def create_status_bar(self):
        #Using code from ARCONS-pipeline as an example:
        #ARCONS-pipeline/util/popup.py
        self.status_text = QLabel("")
        self.statusBar().addWidget(self.status_text, 1)

    def createMenu(self):
        #Using code from ARCONS-pipeline as an example:
        #ARCONS-pipeline/util/quicklook.py
        self.menubar = self.menuBar()
        self.fileMenu = self.menubar.addMenu("&File")

        openFileButton = QAction(QIcon('exit24.png'), 'Open H5 File', self)
        openFileButton.setShortcut('Ctrl+O')
        openFileButton.setStatusTip('Open an H5 File')
        openFileButton.triggered.connect(self.getFileNameFromUser)
        self.fileMenu.addAction(openFileButton)

        exitButton = QAction(QIcon('exit24.png'), 'Exit', self)
        exitButton.setShortcut('Ctrl+Q')
        exitButton.setStatusTip('Exit application')
        exitButton.triggered.connect(self.close)
        self.fileMenu.addAction(exitButton)

        #make a menu for plotting
        self.plotMenu = self.menubar.addMenu("&Plot")
        plotLightCurveButton = QAction('Light Curve', self)
        plotLightCurveButton.triggered.connect(self.makeTimestreamPlot)
        plotIntensityHistogramButton = QAction('Intensity Histogram', self)
        plotIntensityHistogramButton.triggered.connect(
            self.makeIntensityHistogramPlot)
        plotSpectrumButton = QAction('Spectrum', self)
        plotSpectrumButton.triggered.connect(self.makeSpectrumPlot)
        self.plotMenu.addAction(plotLightCurveButton)
        self.plotMenu.addAction(plotIntensityHistogramButton)
        self.plotMenu.addAction(plotSpectrumButton)

        self.menubar.setNativeMenuBar(False)  #This is for MAC OS

    def getFileNameFromUser(self):
        # look at this website for useful examples
        # https://pythonspot.com/pyqt5-file-dialog/
        try:
            def_loc = os.environ['MKID_DATA_DIR']
        except KeyError:
            def_loc = '.'
        filename, _ = QFileDialog.getOpenFileName(self,
                                                  'Select One File',
                                                  def_loc,
                                                  filter='*.h5')

        self.filename = filename
        self.loadDataFromH5(self.filename)

    def makeTimestreamPlot(self):
        sWindow = timeStream(self)
        sWindow.show()
        self.sWindowList.append(sWindow)

    def makeIntensityHistogramPlot(self):
        sWindow = intensityHistogram(self)
        sWindow.show()
        self.sWindowList.append(sWindow)

    def makeSpectrumPlot(self):
        sWindow = spectrum(self)
        sWindow.show()
        self.sWindowList.append(sWindow)