Exemple #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
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
Exemple #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
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
Exemple #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)
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
    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)]
Exemple #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)