コード例 #1
0
    def __init__(self, path, runName, voltStart, voltEnd, numPoints,
                 exposure_Seconds):
        self.path = path
        self.runName = runName
        self.voltStart = voltStart
        self.numPoints = numPoints
        self.voltArr = np.linspace(voltStart, voltEnd, numPoints)
        self.exposure_MilliSeconds = exposure_Seconds * 1000

        self.MKSFullScale = 500.0  #full scale of N2, sccm
        self.scaleFact = 1.4  #scael factor for He
        self.flowRate = 50.0
        self.binning = 1  #don't use binnig for absorption

        self.nozzleWaitTime_Seconds = 5  #time to wait for turning on or off the nozzle
        self.waitTimeToFlow_Seconds = self.nozzleWaitTime_Seconds - exposure_Seconds
        if self.waitTimeToFlow_Seconds < 0.0:
            self.waitTimeToFlow_Seconds = 0.0
        self.waitTimeToStopFlow_Seconds = self.nozzleWaitTime_Seconds

        self.camera = Camera('FAR',
                             self.exposure_MilliSeconds,
                             bin=self.binning)
        self.galvoOut = DAQPin(gv.galvoOutPin)
        self.shutterOut = DAQPin(gv.shutterPin)  #open the shutter contorl pin
        self.darkImageList = []
        self.noFlowImageList = []
        self.flowImageList = []
        self.absorptionSignalImageList = []
    def run(self):
        self.save_Settings()
        self.galvoOut = DAQPin(gv.galvoOutPin)
        self.shutterOut = DAQPin(gv.shutterPin)

        self.galvoOut.write(float(self.voltStartBox.get()))
        x1 = int(self.x1Box.get())
        y1 = int(self.y1Box.get())
        x2 = int(self.x2Box.get())
        y2 = int(self.y2Box.get())
        imageParams = [x1, x2, y1, y2]
        binSize = int(self.binSizeBox.get())
        self.camera = Camera(self.cameraVar.get(),
                             float(self.expTimeBox.get()),
                             imageParams=imageParams,
                             bin=binSize)

        self.voltArr = np.linspace(float(self.voltStartBox.get()),
                                   float(self.voltStopBox.get()),
                                   num=int(self.numImagesBox.get()))
        if os.path.isdir(self.folderPath.get()) == False:
            print('-----ERROR-----------')
            print('YOU HAVE ENTERED AN INVALID FOLDERPATH')
        if os.path.isfile(self.folderPath.get() + '\\' + self.fileName.get() +
                          '.png') == True:
            print('--------------ERROR-------')
            print('THERE IS ALREADY A FILE WITH THAT NAME IN THAT FOLDER')
            gv.error_Sound()
            sys.exit()

        plt.close('all')
        if self.ratioVar.get() == True:
            self.sweep_Ratio()
        else:
            self.sweep_Single()
 def cool_Camera(self):
     if self.cameraVar.get() == "NEAR":
         print("YOU CAN'T COOL THE NEAR FIELD CAMERA")
         gv.warning_Sound()
     else:
         tempCamera = Camera(self.cameraVar.get(),
                             1000)  #the camera will cool down
         tempCamera.close()  #now close it. It will stay cool though
コード例 #4
0
ファイル: TwitterClass.py プロジェクト: epi-k/PiZeroPlant
 def __init__(self, ckey, csecret, atoken, asecret, plant=False):
     self.auth = OAuthHandler(ckey, csecret)
     self.auth.set_access_token(atoken, asecret)
     self.api = tweepy.API(self.auth)
     self.twitterStream = Stream(self.auth, self.listener(self))
     self.twitterStream.filter(track=['@literally_plant'], is_async=True)
     self.plant = plant
     self.camera = Camera()
    def initialize_Camera(self):
        x1 = int(self.x1Box.get())  #image region values
        y1 = int(self.y1Box.get())  #image region values
        x2 = int(self.x2Box.get())  #image region values
        y2 = int(self.y2Box.get())  #image region values
        imageParams = [x1, x2, y1, y2]
        binSize = int(self.binSizeBox.get())  #binning value

        #initialize camera object. can be near or far field camera
        expTime = int(self.expTimeBox.get())  #exposure time, ms
        whichCam = self.cameraVar.get()  #which camera to use, 'FAR' or 'NEAR'
        self.camera = Camera(whichCam,
                             expTime,
                             imageParams=imageParams,
                             bin=binSize)
コード例 #6
0
    def _initialize_Cameras(self):
        binNearX = self.binSizeNear
        binNearY = self.binSizeNear
        binFarX = self.binSizeFarX
        binFarY = self.binSizeFarY
        if binFarX <= 0 and binFarY <= 0:
            raise Exception('Both bin values cannot be zero')
        elif binFarX == 0:
            binFarX = binFarY
        elif binFarY == 0:
            binFarY = binFarX

        if binNearX <= 0 and binNearY <= 0:
            raise Exception('Both bin values cannot be zero')
        elif binNearX == 0:
            binNearX = binNearY
        elif binNearY == 0:
            binNearY = binNearX

        if self.GUI.cameraVarData.get() == 'BOTH':
            self.cameraFar = Camera('FAR',
                                    self.expTimeFar,
                                    self.imageParamFar,
                                    binx=binFarX,
                                    biny=binFarY)
            self.cameraNear = Camera('NEAR',
                                     self.expTimeNear,
                                     self.imageParamNear,
                                     binx=binNearX,
                                     biny=binNearY)
        elif self.GUI.cameraVarData.get() == 'NEAR':
            self.cameraNear = Camera('NEAR',
                                     self.expTimeNear,
                                     self.imageParamNear,
                                     binx=binNearX,
                                     biny=binNearY)
        elif self.GUI.cameraVarData.get() == 'FAR':
            self.cameraFar = Camera('FAR',
                                    self.expTimeFar,
                                    self.imageParamFar,
                                    binx=binFarX,
                                    biny=binFarY)
        else:
            gv.error_Sound()
            raise Exception('NO VALID CAMERA NAME PROVIDED')
class GUI:
    def __init__(self):
        self.settingsList = []
        self.x1Box = None
        self.x2Box = None
        self.y1Box = None
        self.y2 = None
        self.voltArr = None  #array to to hold voltage value sto scan over
        self.camera = None  #to hold the camera opject
        self.galvoOut = None
        self.shutterOut = None  #shutter control
        self.window = tk.Tk()
        self.window.title("Simple Scan")
        self.window.geometry('800x600')

        lbl1 = tk.Label(self.window, text='Scan Range (V)')
        lbl1.grid(column=0, row=0)

        self.voltStartBox = tk.Entry(self.window)
        self.voltStartBox.config(width=5)
        self.voltStartBox.grid(column=1, row=0, sticky='W')
        self.settingsList.append(self.voltStartBox)

        lbl2 = tk.Label(self.window, text='to')
        lbl2.grid(column=2, row=0)

        self.voltStopBox = tk.Entry(self.window)
        self.voltStopBox.config(width=5)
        self.voltStopBox.grid(column=3, row=0, sticky='W')
        self.settingsList.append(self.voltStopBox)

        lbl3 = tk.Label(self.window, text='Num images')
        lbl3.grid(column=0, row=1)

        self.numImagesBox = tk.Entry(self.window)
        self.numImagesBox.config(width=5)
        self.numImagesBox.grid(column=1, row=1, sticky='W')
        self.settingsList.append(self.numImagesBox)

        lbl31 = tk.Label(self.window, text='Exp time (ms)')
        lbl31.grid(column=2, row=1)

        self.expTimeBox = tk.Entry(self.window)
        self.expTimeBox.config(width=5)
        self.expTimeBox.grid(column=3, row=1, sticky='W')
        self.settingsList.append(self.expTimeBox)

        lbl32 = tk.Label(self.window, text='bin size')
        lbl32.grid(column=4, row=1)

        self.binSizeBox = tk.Entry(self.window)
        self.binSizeBox.config(width=5)
        self.binSizeBox.grid(column=5, row=1, sticky='W')
        self.settingsList.append(self.binSizeBox)

        lbl4 = tk.Label(self.window, text='Camera')
        lbl4.grid(column=0, row=4)

        self.cameraVar = tk.StringVar(self.window)
        self.cameraVar.set("FAR")
        cameraChoice = ["NEAR", "FAR"]
        CAMERA_MENU = tk.OptionMenu(self.window, self.cameraVar, *cameraChoice)
        CAMERA_MENU.grid(column=1, row=4, columnspan=2)
        self.settingsList.append(self.cameraVar)

        lbl5 = tk.Label(self.window, text='image x1')
        lbl5.grid(column=0, row=5)
        self.x1Box = tk.Entry(self.window)
        self.x1Box.config(width=5)
        self.x1Box.grid(column=1, row=5, sticky='W')
        self.settingsList.append(self.x1Box)

        lbl5 = tk.Label(self.window, text='image x2')
        lbl5.grid(column=2, row=5)
        self.x2Box = tk.Entry(self.window)
        self.x2Box.config(width=5)
        self.x2Box.grid(column=3, row=5, sticky='W')
        self.settingsList.append(self.x2Box)

        lbl5 = tk.Label(self.window, text='image y1')
        lbl5.grid(column=0, row=6)
        self.y1Box = tk.Entry(self.window)
        self.y1Box.config(width=5)
        self.y1Box.grid(column=1, row=6, sticky='W')
        self.settingsList.append(self.y1Box)

        lbl5 = tk.Label(self.window, text='image y2')
        lbl5.grid(column=2, row=6)
        self.y2Box = tk.Entry(self.window)
        self.y2Box.config(width=5)
        self.y2Box.grid(column=3, row=6, sticky='W')
        self.settingsList.append(self.y2Box)

        self.saveDataVar = tk.BooleanVar()
        saveDataCheckButton = tk.Checkbutton(self.window,
                                             text='save data',
                                             variable=self.saveDataVar)
        saveDataCheckButton.grid(column=1, row=7)
        self.settingsList.append(self.saveDataVar)

        self.ratioVar = tk.BooleanVar()
        ratioVarButton = tk.Checkbutton(self.window,
                                        text='ratio',
                                        variable=self.ratioVar)
        ratioVarButton.grid(column=1, row=8)
        self.settingsList.append(self.ratioVar)

        self.showPlotVar = tk.BooleanVar()
        showDataAnalysiButton = tk.Checkbutton(self.window,
                                               text='Show plot',
                                               variable=self.showPlotVar)
        showDataAnalysiButton.grid(column=1, row=9)
        self.settingsList.append(self.showPlotVar)

        lbl3 = tk.Label(self.window, text='Run name')
        lbl3.grid(column=0, row=15)

        self.fileName = tk.Entry(self.window)
        self.fileName.config(width=20)
        self.fileName.grid(column=1, row=15, sticky='W', columnspan=20)
        self.settingsList.append(self.fileName)

        lbl3 = tk.Label(self.window, text='Folder path')
        lbl3.grid(column=0, row=16)

        self.folderPath = tk.Entry(self.window)
        self.folderPath.config(width=30)
        self.folderPath.grid(column=1, row=16, sticky='W', columnspan=30)
        self.settingsList.append(self.folderPath)

        runButton = tk.Button(self.window,
                              text='RUN',
                              font=("Arial", 20),
                              background="green",
                              command=self.run)
        runButton.config(height=2, width=10)
        runButton.grid(column=0, row=17, columnspan=4, rowspan=4)

        coolCameraButton = tk.Button(self.window,
                                     text='cool camera',
                                     background="royal blue",
                                     command=self.cool_Camera)
        #coolCameraButton.config(height=2, width=10)
        coolCameraButton.grid(column=0, row=21, columnspan=4, rowspan=4)

        self.load_Settings()

        self.window.protocol("WM_DELETE_WINDOW", self.close_GUI)
        self.window.mainloop()

    def cool_Camera(self):
        if self.cameraVar.get() == "NEAR":
            print("YOU CAN'T COOL THE NEAR FIELD CAMERA")
            gv.warning_Sound()
        else:
            tempCamera = Camera(self.cameraVar.get(),
                                1000)  #the camera will cool down
            tempCamera.close()  #now close it. It will stay cool though

    def open_Aperture(self):
        self.shutterOut.write_High()
        time.sleep(.05)

    def close_Aperture(self):
        self.shutterOut.write_Low()
        time.sleep(.05)

    def close_GUI(self):
        self.save_Settings()
        self.window.destroy()
        sys.exit()

    def run(self):
        self.save_Settings()
        self.galvoOut = DAQPin(gv.galvoOutPin)
        self.shutterOut = DAQPin(gv.shutterPin)

        self.galvoOut.write(float(self.voltStartBox.get()))
        x1 = int(self.x1Box.get())
        y1 = int(self.y1Box.get())
        x2 = int(self.x2Box.get())
        y2 = int(self.y2Box.get())
        imageParams = [x1, x2, y1, y2]
        binSize = int(self.binSizeBox.get())
        self.camera = Camera(self.cameraVar.get(),
                             float(self.expTimeBox.get()),
                             imageParams=imageParams,
                             bin=binSize)

        self.voltArr = np.linspace(float(self.voltStartBox.get()),
                                   float(self.voltStopBox.get()),
                                   num=int(self.numImagesBox.get()))
        if os.path.isdir(self.folderPath.get()) == False:
            print('-----ERROR-----------')
            print('YOU HAVE ENTERED AN INVALID FOLDERPATH')
        if os.path.isfile(self.folderPath.get() + '\\' + self.fileName.get() +
                          '.png') == True:
            print('--------------ERROR-------')
            print('THERE IS ALREADY A FILE WITH THAT NAME IN THAT FOLDER')
            gv.error_Sound()
            sys.exit()

        plt.close('all')
        if self.ratioVar.get() == True:
            self.sweep_Ratio()
        else:
            self.sweep_Single()

    def take_Dark_Image_Average(self, num=3):
        image = self.camera.aquire_Image()
        for i in range(num - 1):
            image += self.camera.aquire_Image()
        image = image / num  #average the three images
        return image

    def sweep_Ratio(self):
        gv.begin_Sound()
        self.galvoOut.write(self.voltArr[0])

        image1MeanList = []  #shutter open list of image sums
        image2MeanList = []  #shutter closed list of image sums
        image1List = []
        image2List = []

        for volt in self.voltArr:
            self.galvoOut.write(volt)
            #take with shutter open
            self.open_Aperture()
            image1 = self.camera.aquire_Image()
            image1List.append(image1)
            image1MeanList.append(np.mean(image1))

            #take with shutter closed
            self.close_Aperture()
            image2 = self.camera.aquire_Image()
            image2List.append(image2)
            image2MeanList.append(np.mean(image2))

        self.galvoOut.close()
        self.shutterOut.close()
        self.camera.close()
        gv.finished_Sound()

        y1 = np.asarray(image1MeanList)  #shutter open
        y2 = np.asarray(image2MeanList)  #shutter closed

        numImages = 3
        delta1 = np.max(y1) - np.mean((y1[:numImages] + y1[-numImages:]) / 2)
        delta2 = np.max(y2) - np.mean((y2[:numImages] + y2[-numImages:]) / 2)

        ratio = delta1 / delta2
        plt.suptitle('Signal with shutter closed and open')
        plt.title('ratio of peaks of open to close = ' +
                  str(np.round(ratio, 6)))
        plt.plot(self.voltArr,
                 y1,
                 label='open,delta= ' + str(np.round(delta1, 1)))
        plt.plot(self.voltArr,
                 y2,
                 label='close,delta= ' + str(np.round(delta2, 1)))
        plt.xlabel('Volts')
        plt.ylabel('Pixel counts')
        plt.legend()
        plt.grid()

        if self.saveDataVar.get() == True:
            plt.savefig(self.folderPath.get() + '\\' + self.fileName.get() +
                        'Graph.png')
            image1SaveList = []
            image2SaveList = []
            for i in range(len(image1List)):
                image1SaveList.append(np.rot90(np.transpose(image1List[i])))
                image2SaveList.append(np.rot90(np.transpose(image2List[i])))
            hdu1 = fits.PrimaryHDU(
                image1SaveList)  #make a Header/Data Unit of images
            hdul1 = fits.HDUList([hdu1])  #list of HDUs to save
            hdu2 = fits.PrimaryHDU(
                image2SaveList)  #make a Header/Data Unit of images
            hdul2 = fits.HDUList([hdu2])  #list of HDUs to save

            fitsFileName = self.fileName.get()
            try:
                hdul1.writeto(self.folderPath.get() + '\\' + fitsFileName +
                              'ShutterOpen.fits')  #now save it
                hdul2.writeto(self.folderPath.get() + '\\' + fitsFileName +
                              'ShutterClosed.fits')  #now save it
            except:  #fits doesn't let you delete stuff accidently
                print('THAT FILE ALREADY EXISTS. DELETE IT TO OVERWRITE@')

        if self.showPlotVar.get() == True:
            plt.show()

    def sweep_Single(self):
        #self.close_Aperture()

        gv.begin_Sound()
        self.galvoOut.write(self.voltArr[0])
        darkImage = self.take_Dark_Image_Average()
        imageMeanList = []
        imageList = []
        for volt in self.voltArr:
            self.galvoOut.write(volt)
            image = self.camera.aquire_Image()
            imageList.append(image)
            image = image - darkImage * 0
            imageMeanList.append(np.mean(image))
        imageSumArr = np.asarray(imageMeanList)

        self.galvoOut.close()
        self.shutterOut.close()
        self.camera.close()
        gv.finished_Sound()

        numImages = 3
        delta = np.max(imageSumArr) - np.mean(
            (imageSumArr[:numImages] + imageSumArr[-numImages:]) / 2)

        plt.plot(self.voltArr, imageSumArr)
        plt.title('Peak minus first few values= ' + str(np.round(delta, 2)))
        plt.xlabel('Volts')
        plt.ylabel('Pixel counts')
        plt.grid()
        if self.saveDataVar.get() == True:
            print(self.folderPath.get() + '\\' + self.fileName.get() + 'Graph')
            plt.savefig(self.folderPath.get() + '\\' +
                        self.fileName.get())  #save plot
            #now save fits file
            saveImageList = []
            for item in imageList:
                saveImageList.append(np.rot90(np.transpose(item)))
            hdu = fits.PrimaryHDU(
                saveImageList)  #make a Header/Data Unit of images
            hdul = fits.HDUList([hdu])  #list of HDUs to save
            fitsFileName = self.fileName.get() + '.fits'
            try:
                hdul.writeto(self.folderPath.get() + '\\' +
                             fitsFileName)  #now save it
            except:  #fits doesn't let you delete stuff accidently
                print('THAT FILE ALREADY EXISTS. DELETE IT TO OVERWRITE@')

        if self.showPlotVar.get() == True:
            plt.show()

    def save_Settings(self):
        file = open("simpleScaneGUI_Settings.txt", "w")
        for item in self.settingsList:
            file.write(str(item.get()) + '\n')
        file.close()

    def load_Settings(self):
        try:
            file = open("simpleScaneGUI_Settings.txt", "r")
        except:
            print("NO SETTINGS FILE FOUND")
            return
        i = 0
        for item in file:
            item = item.strip()
            if i >= len(self.settingsList):
                pass
            else:
                if isinstance(self.settingsList[i], tk.StringVar):
                    self.settingsList[i].set(item)
                elif isinstance(self.settingsList[i], tk.Entry):
                    self.settingsList[i].insert(0, item)
                elif isinstance(self.settingsList[i], tk.BooleanVar):
                    if item == 'False' or item == 'True':
                        self.settingsList[i].set(item)
            i += 1
        file.close()
コード例 #8
0
ファイル: TwitterClass.py プロジェクト: epi-k/PiZeroPlant
class Twitter:
    def __init__(self, ckey, csecret, atoken, asecret, plant=False):
        self.auth = OAuthHandler(ckey, csecret)
        self.auth.set_access_token(atoken, asecret)
        self.api = tweepy.API(self.auth)
        self.twitterStream = Stream(self.auth, self.listener(self))
        self.twitterStream.filter(track=['@literally_plant'], is_async=True)
        self.plant = plant
        self.camera = Camera()

    def tweet(self, msg):
        self.api.update_status(msg)

    class listener(StreamListener):
        def __init__(self, tObj):
            self.tObj = tObj

        def on_data(self, data):
            data = json.loads(data)
            dataDict = {
                'id': data['id'],
                'text': data['text'],
                'user': {
                    'name': data['user']['name'],
                    'screen_name': data['user']['screen_name']
                }
            }

            print("Tweet Received By: @" + dataDict['user']['screen_name'] +
                  " - " + dataDict['text'])

            if "moist" in dataDict['text'] and "?" in dataDict['text']:
                print("Sending Moisture Level...")
                self.tObj.api.update_status(
                    "@" + dataDict['user']['screen_name'] +
                    " Soil Moisture: " +
                    str(self.tObj.plant.getPinInfo("P0")['data']) + "%\nAt " +
                    self.tObj.getFormattedTime(),
                    in_reply_to_status_id=dataDict['id'])
            elif "picture" in dataDict['text'] and "?" in dataDict['text']:
                print("Sending Picture...")
                filename = "./img/pic.jpg"
                self.tObj.camera.takePhoto(filename)
                self.tObj.api.update_with_media(
                    filename,
                    status="@" + dataDict['user']['screen_name'] +
                    " Picture taken at " + self.tObj.getFormattedTime() +
                    "\nDay: " + str(
                        abs((datetime.datetime.today() -
                             self.tObj.plant.startDate).days)),
                    in_reply_to_status_id=dataDict['id'])

        def on_error(self, status):
            print(status)

    def refresh(self, ckey, csecret, atoken, asecret):
        print("Refreshing Credentials...")
        self.auth = OAuthHandler(ckey, csecret)
        self.auth.set_access_token(atoken, asecret)
        self.api = tweepy.API(self.auth)
        # self.twitterStream = Stream(self.auth, self.listener(self))
        # self.twitterStream.filter(track=['@literally_plant'], is_async=True)

    def getFormattedTime(self):
        now = datetime.datetime.now() - datetime.timedelta(hours=7)
        fmt = '%I:%M:%S%p MDT %m/%d/%Y'

        return str(now.strftime(fmt))

    def takeTimelapse(self, filename):
        print("Taking Timelapse Picture...")
        filename = "./timelapse/" + filename + ".jpg"
        self.camera.takePhoto(filename)
        self.api.update_with_media(
            filename,
            status="Timelapse picture taken at " + self.getFormattedTime() +
            "\nDay: " +
            str(abs((datetime.datetime.today() - self.plant.startDate).days)))
コード例 #9
0
class Ui_MainWindow(object):
    db = Database()
    cam = Camera(0)
    camTimer = QtCore.QTimer()
    tempTimer = QtCore.QTimer()
    cam.setDaemon(True)
    holes = NetHoleDetection()
    clean = NetCleaning()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1002, 872)
        MainWindow.setWindowFlags(QtCore.Qt.CustomizeWindowHint)
        MainWindow.setWindowFlags(QtCore.Qt.FramelessWindowHint)

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(999, 872)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
        self.stackedWidget.setGeometry(QtCore.QRect(0, 0, 1000, 873))
        self.stackedWidget.setObjectName("stackedWidget")
        self.loginPage = QtWidgets.QWidget()
        self.loginPage.setStyleSheet(
            "border-image: url(:/Images/Resources/signInBG.png);")
        self.loginPage.setObjectName("loginPage")
        self.button_signIn_signIn = QtWidgets.QPushButton(self.loginPage)
        self.button_signIn_signIn.setGeometry(QtCore.QRect(320, 590, 320, 45))
        self.button_signIn_signIn.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/signIn.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/signInPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/signInPressed.png);\n"
            "}")
        self.button_signIn_signIn.setText("")
        self.button_signIn_signIn.setObjectName("button_signIn_signIn")
        self.button_faceID_signIn = QtWidgets.QPushButton(self.loginPage)
        self.button_faceID_signIn.setGeometry(QtCore.QRect(320, 660, 320, 45))
        self.button_faceID_signIn.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/faceID.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/faceIDClicked.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/faceIDClicked.png);\n"
            "}")
        self.button_faceID_signIn.setText("")
        self.button_faceID_signIn.setObjectName("button_faceID_signIn")
        self.button_signUp_signIn = QtWidgets.QPushButton(self.loginPage)
        self.button_signUp_signIn.setGeometry(QtCore.QRect(320, 730, 320, 45))
        self.button_signUp_signIn.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/signUp.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/signUpPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/signUpPressed.png);\n"
            "}")
        self.button_signUp_signIn.setText("")
        self.button_signUp_signIn.setObjectName("button_signUp_signIn")
        self.lineEdit_username_signIn = QtWidgets.QLineEdit(self.loginPage)
        self.lineEdit_username_signIn.setGeometry(
            QtCore.QRect(310, 345, 281, 31))
        self.lineEdit_username_signIn.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_username_signIn.setObjectName("lineEdit_username_signIn")
        self.lineEdit_password_signIn = QtWidgets.QLineEdit(self.loginPage)
        self.lineEdit_password_signIn.setGeometry(
            QtCore.QRect(310, 419, 281, 41))
        self.lineEdit_password_signIn.setContextMenuPolicy(
            QtCore.Qt.DefaultContextMenu)
        self.lineEdit_password_signIn.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);\n"
            "")
        self.lineEdit_password_signIn.setEchoMode(QtWidgets.QLineEdit.Password)
        self.lineEdit_password_signIn.setObjectName("lineEdit_password_signIn")
        self.button_close = QtWidgets.QPushButton(self.loginPage)
        self.button_close.setGeometry(QtCore.QRect(940, 40, 21, 21))
        self.button_close.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/exitBlue.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/exitRed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/exitRed.png);\n"
            "}")
        self.button_close.setText("")
        self.button_close.setObjectName("button_close")
        self.label_invalid = QtWidgets.QLabel(self.loginPage)
        self.label_invalid.setGeometry(QtCore.QRect(400, 300, 201, 16))
        self.label_invalid.setStyleSheet(
            "border-image: url(:/Images/Resources/semiDarkBG.png);\n"
            "color: rgb(255, 61, 55);")
        self.label_invalid.setText("")
        self.label_invalid.setObjectName("label_invalid")
        self.stackedWidget.addWidget(self.loginPage)
        self.signupPage = QtWidgets.QWidget()
        self.signupPage.setStyleSheet(
            "border-image: url(:/Images/Resources/signUpBG.png);")
        self.signupPage.setObjectName("signupPage")
        self.lineEdit_firstName_signUp = QtWidgets.QLineEdit(self.signupPage)
        self.lineEdit_firstName_signUp.setGeometry(
            QtCore.QRect(310, 330, 151, 29))
        self.lineEdit_firstName_signUp.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_firstName_signUp.setObjectName(
            "lineEdit_firstName_signUp")
        self.lineEdit_lastName_signUp = QtWidgets.QLineEdit(self.signupPage)
        self.lineEdit_lastName_signUp.setGeometry(
            QtCore.QRect(530, 330, 151, 29))
        self.lineEdit_lastName_signUp.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_lastName_signUp.setObjectName("lineEdit_lastName_signUp")
        self.lineEdit_email_signUp = QtWidgets.QLineEdit(self.signupPage)
        self.lineEdit_email_signUp.setGeometry(QtCore.QRect(310, 408, 371, 21))
        self.lineEdit_email_signUp.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_email_signUp.setObjectName("lineEdit_email_signUp")
        self.lineEdit_username_signUp = QtWidgets.QLineEdit(self.signupPage)
        self.lineEdit_username_signUp.setGeometry(
            QtCore.QRect(310, 490, 371, 21))
        self.lineEdit_username_signUp.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_username_signUp.setObjectName("lineEdit_username_signUp")
        self.lineEdit_password_signUp = QtWidgets.QLineEdit(self.signupPage)
        self.lineEdit_password_signUp.setGeometry(
            QtCore.QRect(310, 570, 371, 21))
        self.lineEdit_password_signUp.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_password_signUp.setObjectName("lineEdit_password_signUp")
        self.button_signUp_signUp = QtWidgets.QPushButton(self.signupPage)
        self.button_signUp_signUp.setGeometry(QtCore.QRect(340, 640, 320, 45))
        self.button_signUp_signUp.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/signUp.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/signUpPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/signUpPressed.png);\n"
            "}")
        self.button_signUp_signUp.setText("")
        self.button_signUp_signUp.setObjectName("button_signUp_signUp")
        self.button_backToSignIn = QtWidgets.QPushButton(self.signupPage)
        self.button_backToSignIn.setGeometry(QtCore.QRect(340, 720, 320, 45))
        self.button_backToSignIn.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/backSignInPressed.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/backSignIn.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/backSignIn.png);\n"
            "}")
        self.button_backToSignIn.setText("")
        self.button_backToSignIn.setObjectName("button_backToSignIn")
        self.button_close_2 = QtWidgets.QPushButton(self.signupPage)
        self.button_close_2.setGeometry(QtCore.QRect(940, 40, 21, 21))
        self.button_close_2.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/exitBlue.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/exitRed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/exitRed.png);\n"
            "}")
        self.button_close_2.setText("")
        self.button_close_2.setObjectName("button_close_2")
        self.stackedWidget.addWidget(self.signupPage)
        self.faceidPage = QtWidgets.QWidget()
        self.faceidPage.setStyleSheet(
            "border-image: url(:/Images/Resources/faceIDWidget.png);")
        self.faceidPage.setObjectName("faceidPage")
        self.label_cam = QtWidgets.QLabel(self.faceidPage)
        self.label_cam.setGeometry(QtCore.QRect(90, 230, 821, 401))
        self.label_cam.setStyleSheet(
            "border-image: url(:/Images/Resources/semiDarkBG.png);")
        self.label_cam.setText("")
        self.label_cam.setObjectName("label_cam")
        self.stackedWidget.addWidget(self.faceidPage)
        self.mainPage = QtWidgets.QWidget()
        self.mainPage.setStyleSheet(
            "border-image: url(:/Images/Resources/mainWidgetBG.png);")
        self.mainPage.setObjectName("mainPage")
        self.button_dashboard = QtWidgets.QPushButton(self.mainPage)
        self.button_dashboard.setGeometry(QtCore.QRect(0, 230, 291, 54))
        self.button_dashboard.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/dasboard.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/dashboardPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/dashboardPressed.png);\n"
            "}")
        self.button_dashboard.setText("")
        self.button_dashboard.setObjectName("button_dashboard")
        self.button_createTank = QtWidgets.QPushButton(self.mainPage)
        self.button_createTank.setGeometry(QtCore.QRect(0, 290, 291, 54))
        self.button_createTank.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/create.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/createPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/createPressed.png);\n"
            "}")
        self.button_createTank.setText("")
        self.button_createTank.setObjectName("button_createTank")
        self.button_analyzeTank = QtWidgets.QPushButton(self.mainPage)
        self.button_analyzeTank.setGeometry(QtCore.QRect(0, 350, 291, 54))
        self.button_analyzeTank.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/analyze.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/analyzePressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/analyzePressed.png);\n"
            "}")
        self.button_analyzeTank.setText("")
        self.button_analyzeTank.setObjectName("button_analyzeTank")
        self.button_settings = QtWidgets.QPushButton(self.mainPage)
        self.button_settings.setGeometry(QtCore.QRect(0, 410, 291, 54))
        self.button_settings.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/settings.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/settingsPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/settingsPressed.png);\n"
            "}")
        self.button_settings.setText("")
        self.button_settings.setObjectName("button_settings")
        self.button_logout = QtWidgets.QPushButton(self.mainPage)
        self.button_logout.setGeometry(QtCore.QRect(78, 790, 130, 42))
        self.button_logout.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/logoutPressed.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/logout.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/logout.png);\n"
            "}")
        self.button_logout.setText("")
        self.button_logout.setObjectName("button_logout")
        self.stackedWidget_2 = QtWidgets.QStackedWidget(self.mainPage)
        self.stackedWidget_2.setGeometry(QtCore.QRect(290, 0, 711, 861))
        self.stackedWidget_2.setStyleSheet(
            "border-image: url(:/Images/Resources/CreateBG.png);")
        self.stackedWidget_2.setObjectName("stackedWidget_2")
        self.dashboardPage = QtWidgets.QWidget()
        self.dashboardPage.setStyleSheet(
            "border-image: url(:/Images/Resources/dashboardWidget.png);")
        self.dashboardPage.setObjectName("dashboardPage")
        self.label_fishType_tankData = QtWidgets.QLabel(self.dashboardPage)
        self.label_fishType_tankData.setGeometry(QtCore.QRect(
            190, 176, 81, 16))
        self.label_fishType_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_fishType_tankData.setObjectName("label_fishType_tankData")
        self.label_harvestDate_tankData = QtWidgets.QLabel(self.dashboardPage)
        self.label_harvestDate_tankData.setGeometry(
            QtCore.QRect(220, 225, 111, 16))
        self.label_harvestDate_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_harvestDate_tankData.setObjectName(
            "label_harvestDate_tankData")
        self.label_feeding_tankData = QtWidgets.QLabel(self.dashboardPage)
        self.label_feeding_tankData.setGeometry(QtCore.QRect(
            250, 273, 101, 16))
        self.label_feeding_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_feeding_tankData.setObjectName("label_feeding_tankData")
        self.label_ph_tankData = QtWidgets.QLabel(self.dashboardPage)
        self.label_ph_tankData.setGeometry(QtCore.QRect(140, 324, 71, 16))
        self.label_ph_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_ph_tankData.setObjectName("label_ph_tankData")
        self.label_temperature_tankData = QtWidgets.QLabel(self.dashboardPage)
        self.label_temperature_tankData.setGeometry(
            QtCore.QRect(210, 370, 500, 20))
        self.label_temperature_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "color: rgb(255, 61, 55);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_temperature_tankData.setObjectName(
            "label_temperature_tankData")
        self.label_fishNetHoles_tankData = QtWidgets.QLabel(self.dashboardPage)
        self.label_fishNetHoles_tankData.setGeometry(
            QtCore.QRect(220, 418, 71, 16))
        self.label_fishNetHoles_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_fishNetHoles_tankData.setObjectName(
            "label_fishNetHoles_tankData")
        self.label_fishnetNeedsCleaning_tankData = QtWidgets.QLabel(
            self.dashboardPage)
        self.label_fishnetNeedsCleaning_tankData.setGeometry(
            QtCore.QRect(290, 465, 55, 16))
        self.label_fishnetNeedsCleaning_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_fishnetNeedsCleaning_tankData.setObjectName(
            "label_fishnetNeedsCleaning_tankData")
        self.label_pipesNeedChanging_tankData = QtWidgets.QLabel(
            self.dashboardPage)
        self.label_pipesNeedChanging_tankData.setGeometry(
            QtCore.QRect(280, 513, 55, 16))
        self.label_pipesNeedChanging_tankData.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_pipesNeedChanging_tankData.setObjectName(
            "label_pipesNeedChanging_tankData")
        self.comboBox = QtWidgets.QComboBox(self.dashboardPage)
        self.comboBox.setGeometry(QtCore.QRect(300, 70, 128, 33))
        self.comboBox.setStyleSheet(
            "QComboBox {\n"
            "border-image: url(:/Resources/comboBoxBG.png);\n"
            "    border-image: url(:/Images/Resources/comboBoxBG.png);\n"
            "    color: black;\n"
            "    font: 14px;\n"
            "    padding: 1px 0px 1px 3px; /* This (useless) line resolves a bug with the font color */\n"
            "}\n"
            "\n"
            "QComboBox:focus {\n"
            "    color: red;\n"
            "}\n"
            "\n"
            "QComboBox::drop-down \n"
            "{\n"
            "    border: 0px; /* This seems to replace the whole arrow of the combo box */\n"
            "}")
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.button_email = QtWidgets.QPushButton(self.dashboardPage)
        self.button_email.setGeometry(QtCore.QRect(220, 810, 127, 33))
        self.button_email.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/EmailButton.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/EmailButtonPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/EmailButtonPressed.png);\n"
            "}")
        self.button_email.setText("")
        self.button_email.setObjectName("button_email")
        self.button_report = QtWidgets.QPushButton(self.dashboardPage)
        self.button_report.setGeometry(QtCore.QRect(370, 810, 127, 33))
        self.button_report.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/report.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/reportPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/reportPressed.png);\n"
            "}")
        self.button_report.setText("")
        self.button_report.setObjectName("button_report")
        self.button_close_3 = QtWidgets.QPushButton(self.dashboardPage)
        self.button_close_3.setGeometry(QtCore.QRect(670, 40, 21, 21))
        self.button_close_3.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/exitBlue.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/exitGrey.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/exitGrey.png);\n"
            "}")
        self.button_close_3.setText("")
        self.button_close_3.setObjectName("button_close_3")
        self.stackedWidget_2.addWidget(self.dashboardPage)
        self.createtankPage = QtWidgets.QWidget()
        self.createtankPage.setObjectName("createtankPage")
        self.lineEdit_fishType_createTank = QtWidgets.QLineEdit(
            self.createtankPage)
        self.lineEdit_fishType_createTank.setGeometry(
            QtCore.QRect(480, 490, 71, 31))
        self.lineEdit_fishType_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_fishType_createTank.setObjectName(
            "lineEdit_fishType_createTank")
        self.lineEdit_date_createTank = QtWidgets.QLineEdit(
            self.createtankPage)
        self.lineEdit_date_createTank.setGeometry(
            QtCore.QRect(480, 540, 101, 22))
        self.lineEdit_date_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_date_createTank.setObjectName("lineEdit_date_createTank")
        self.lineEdit_feeding_createTank = QtWidgets.QLineEdit(
            self.createtankPage)
        self.lineEdit_feeding_createTank.setGeometry(
            QtCore.QRect(480, 590, 61, 22))
        self.lineEdit_feeding_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_feeding_createTank.setObjectName(
            "lineEdit_feeding_createTank")
        self.lineEdit_lowerTemperatureThreshold_createTank = QtWidgets.QLineEdit(
            self.createtankPage)
        self.lineEdit_lowerTemperatureThreshold_createTank.setGeometry(
            QtCore.QRect(480, 640, 81, 22))
        self.lineEdit_lowerTemperatureThreshold_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_lowerTemperatureThreshold_createTank.setObjectName(
            "lineEdit_lowerTemperatureThreshold_createTank")
        self.lineEdit_upperTemperatureThreshold_createTank = QtWidgets.QLineEdit(
            self.createtankPage)
        self.lineEdit_upperTemperatureThreshold_createTank.setGeometry(
            QtCore.QRect(480, 690, 81, 22))
        self.lineEdit_upperTemperatureThreshold_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_upperTemperatureThreshold_createTank.setObjectName(
            "lineEdit_upperTemperatureThreshold_createTank")
        self.lineEdit_waterQualityThreshold_createTank = QtWidgets.QLineEdit(
            self.createtankPage)
        self.lineEdit_waterQualityThreshold_createTank.setGeometry(
            QtCore.QRect(480, 740, 81, 22))
        self.lineEdit_waterQualityThreshold_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/darkBlackBG.png);\n"
            "color: rgb(167, 167, 167);")
        self.lineEdit_waterQualityThreshold_createTank.setObjectName(
            "lineEdit_waterQualityThreshold_createTank")
        self.button_create_createTank = QtWidgets.QPushButton(
            self.createtankPage)
        self.button_create_createTank.setGeometry(
            QtCore.QRect(290, 810, 127, 33))
        self.button_create_createTank.setStyleSheet(
            "border-image: url(:/Images/Resources/createButton.png);")
        self.button_create_createTank.setText("")
        self.button_create_createTank.setObjectName("button_create_createTank")
        self.button_close_4 = QtWidgets.QPushButton(self.createtankPage)
        self.button_close_4.setGeometry(QtCore.QRect(670, 40, 21, 21))
        self.button_close_4.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/exitWhiteBlue.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/exitRed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/exitRed.png);\n"
            "}")
        self.button_close_4.setText("")
        self.button_close_4.setObjectName("button_close_4")
        self.stackedWidget_2.addWidget(self.createtankPage)
        self.analyzetankPage = QtWidgets.QWidget()
        self.analyzetankPage.setStyleSheet(
            "border-image: url(:/Images/Resources/AnalyzeBG.png);")
        self.analyzetankPage.setObjectName("analyzetankPage")
        self.button_holes_analyzeTank = QtWidgets.QPushButton(
            self.analyzetankPage)
        self.button_holes_analyzeTank.setGeometry(
            QtCore.QRect(150, 530, 127, 33))
        self.button_holes_analyzeTank.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/Holes.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/HolesPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/HolesPressed.png);\n"
            "}")
        self.button_holes_analyzeTank.setText("")
        self.button_holes_analyzeTank.setObjectName("button_holes_analyzeTank")
        self.button_cleaning_analyzeTank = QtWidgets.QPushButton(
            self.analyzetankPage)
        self.button_cleaning_analyzeTank.setGeometry(
            QtCore.QRect(300, 530, 127, 33))
        self.button_cleaning_analyzeTank.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/Cleaning.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/CleaningPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/CleaningPressed.png);\n"
            "}")
        self.button_cleaning_analyzeTank.setText("")
        self.button_cleaning_analyzeTank.setObjectName(
            "button_cleaning_analyzeTank")
        self.button_pipes_analyzeTank = QtWidgets.QPushButton(
            self.analyzetankPage)
        self.button_pipes_analyzeTank.setGeometry(
            QtCore.QRect(450, 530, 127, 33))
        self.button_pipes_analyzeTank.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/Pipes.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/PipesPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/PipesPressed.png);\n"
            "}")
        self.button_pipes_analyzeTank.setText("")
        self.button_pipes_analyzeTank.setObjectName("button_pipes_analyzeTank")
        self.button_predict_analyzeTank = QtWidgets.QPushButton(
            self.analyzetankPage)
        self.button_predict_analyzeTank.setGeometry(
            QtCore.QRect(440, 740, 222, 34))
        self.button_predict_analyzeTank.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/predict.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/predictPressed.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/predictPressed.png);\n"
            "}")
        self.button_predict_analyzeTank.setText("")
        self.button_predict_analyzeTank.setObjectName(
            "button_predict_analyzeTank")
        self.label_fishnetNeedsPatching_analyzeTank = QtWidgets.QLabel(
            self.analyzetankPage)
        self.label_fishnetNeedsPatching_analyzeTank.setGeometry(
            QtCore.QRect(300, 613, 55, 16))
        self.label_fishnetNeedsPatching_analyzeTank.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_fishnetNeedsPatching_analyzeTank.setObjectName(
            "label_fishnetNeedsPatching_analyzeTank")
        self.label_fishnetNeedsCleaning_analyzeTank = QtWidgets.QLabel(
            self.analyzetankPage)
        self.label_fishnetNeedsCleaning_analyzeTank.setGeometry(
            QtCore.QRect(300, 655, 55, 16))
        self.label_fishnetNeedsCleaning_analyzeTank.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_fishnetNeedsCleaning_analyzeTank.setObjectName(
            "label_fishnetNeedsCleaning_analyzeTank")
        self.label_pipesNeedChanging_analyzeTank = QtWidgets.QLabel(
            self.analyzetankPage)
        self.label_pipesNeedChanging_analyzeTank.setGeometry(
            QtCore.QRect(300, 705, 55, 16))
        self.label_pipesNeedChanging_analyzeTank.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.label_pipesNeedChanging_analyzeTank.setObjectName(
            "label_pipesNeedChanging_analyzeTank")
        self.lineEdit_temperature_analyzeTank = QtWidgets.QLineEdit(
            self.analyzetankPage)
        self.lineEdit_temperature_analyzeTank.setGeometry(
            QtCore.QRect(570, 610, 113, 22))
        self.lineEdit_temperature_analyzeTank.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.lineEdit_temperature_analyzeTank.setObjectName(
            "lineEdit_temperature_analyzeTank")
        self.lineEdit_waterSalinity_analyzeTank = QtWidgets.QLineEdit(
            self.analyzetankPage)
        self.lineEdit_waterSalinity_analyzeTank.setGeometry(
            QtCore.QRect(570, 700, 113, 22))
        self.lineEdit_waterSalinity_analyzeTank.setStyleSheet(
            "border-image: url(:/Images/Resources/whiteBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";")
        self.lineEdit_waterSalinity_analyzeTank.setObjectName(
            "lineEdit_waterSalinity_analyzeTank")
        self.label_camFeed = QtWidgets.QLabel(self.analyzetankPage)
        self.label_camFeed.setGeometry(QtCore.QRect(80, 200, 551, 281))
        self.label_camFeed.setStyleSheet(
            "border-image: url(:/Images/Resources/semiDarkBG.png);")
        self.label_camFeed.setText("")
        self.label_camFeed.setObjectName("label_camFeed")
        self.button_close_5 = QtWidgets.QPushButton(self.analyzetankPage)
        self.button_close_5.setGeometry(QtCore.QRect(670, 40, 21, 21))
        self.button_close_5.setStyleSheet(
            "QPushButton{\n"
            "    border-image: url(:/Images/Resources/exitBlue.png);\n"
            "background-repeat: none;\n"
            "}\n"
            "\n"
            "QPushButton:hover{\n"
            "    border-image: url(:/Images/Resources/exitGrey.png);\n"
            "}\n"
            "\n"
            "QPushButton:pressed{\n"
            "    border-image: url(:/Images/Resources/exitGrey.png);\n"
            "}")
        self.button_close_5.setText("")
        self.button_close_5.setObjectName("button_close_5")
        self.stackedWidget_2.addWidget(self.analyzetankPage)
        self.settingsPage = QtWidgets.QWidget()
        self.settingsPage.setStyleSheet(
            "border-image: url(:/Images/Resources/settingsWidget.png);")
        self.settingsPage.setObjectName("settingsPage")
        self.stackedWidget_2.addWidget(self.settingsPage)
        self.label_username_mainPage = QtWidgets.QLabel(self.mainPage)
        self.label_username_mainPage.setGeometry(
            QtCore.QRect(120, 137, 141, 41))
        self.label_username_mainPage.setStyleSheet(
            "border-image: url(:/Images/Resources/blueBG.png);\n"
            "font: 11pt \"Helvetica LT Std\";\n"
            "color: rgb(229, 229, 229);")
        self.label_username_mainPage.setObjectName("label_username_mainPage")
        self.label_userLetter = QtWidgets.QLabel(self.mainPage)
        self.label_userLetter.setGeometry(QtCore.QRect(50, 137, 31, 31))
        self.label_userLetter.setStyleSheet(
            "border-image: url(:/Images/Resources/greyBG.png);\n"
            "font: 75 26pt \"Helvetica LT Std\";")
        self.label_userLetter.setObjectName("label_userLetter")
        self.stackedWidget.addWidget(self.mainPage)
        MainWindow.setCentralWidget(self.centralwidget)
        self.buttonsConnections()

        self.retranslateUi(MainWindow)
        self.stackedWidget.setCurrentIndex(0)
        self.button_close.clicked.connect(MainWindow.close)
        self.button_close_5.clicked.connect(MainWindow.close)
        self.button_close_2.clicked.connect(MainWindow.close)
        self.button_close_3.clicked.connect(MainWindow.close)
        self.button_close_4.clicked.connect(MainWindow.close)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.lineEdit_username_signIn.setText(_translate("MainWindow", ""))
        self.lineEdit_password_signIn.setText(_translate("MainWindow", ""))
        self.lineEdit_firstName_signUp.setText(
            _translate("MainWindow", "First name"))
        self.lineEdit_lastName_signUp.setText(
            _translate("MainWindow", "Last name"))
        self.lineEdit_email_signUp.setText(
            _translate("MainWindow", "Email address"))
        self.lineEdit_username_signUp.setText(
            _translate("MainWindow", "Username"))
        self.lineEdit_password_signUp.setText(
            _translate("MainWindow", "Password"))
        self.label_fishType_tankData.setText(_translate(
            "MainWindow", "Salmon"))
        self.label_harvestDate_tankData.setText(
            _translate("MainWindow", "29/7/2019"))
        self.label_feeding_tankData.setText(_translate("MainWindow",
                                                       "6:00:00"))
        self.label_ph_tankData.setText(_translate("MainWindow", "5"))
        self.label_temperature_tankData.setText(_translate("MainWindow", "22"))
        self.label_fishNetHoles_tankData.setText(_translate("MainWindow", "1"))
        self.label_fishnetNeedsCleaning_tankData.setText(
            _translate("MainWindow", "No"))
        self.label_pipesNeedChanging_tankData.setText(
            _translate("MainWindow", "No"))
        self.comboBox.setItemText(0, _translate("MainWindow", "Tank 1"))
        self.lineEdit_fishType_createTank.setText(
            _translate("MainWindow", "Salmon"))
        self.lineEdit_date_createTank.setText(
            _translate("MainWindow", "DD/MM/YY"))
        self.lineEdit_feeding_createTank.setText(_translate(
            "MainWindow", "DD"))
        self.lineEdit_lowerTemperatureThreshold_createTank.setText(
            _translate("MainWindow", "18"))
        self.lineEdit_upperTemperatureThreshold_createTank.setText(
            _translate("MainWindow", "24"))
        self.lineEdit_waterQualityThreshold_createTank.setText(
            _translate("MainWindow", "0.9"))
        self.label_fishnetNeedsPatching_analyzeTank.setText(
            _translate("MainWindow", "No"))
        self.label_fishnetNeedsCleaning_analyzeTank.setText(
            _translate("MainWindow", "No"))
        self.label_pipesNeedChanging_analyzeTank.setText(
            _translate("MainWindow", "No"))
        self.lineEdit_temperature_analyzeTank.setText(
            _translate("MainWindow", "24"))
        self.lineEdit_waterSalinity_analyzeTank.setText(
            _translate("MainWindow", "21"))
        self.label_username_mainPage.setText(
            _translate("MainWindow", "Abdullah Salah"))
        self.label_userLetter.setText(_translate("MainWindow", "A"))

    def signInIsClicked(self):
        username_signIn = self.lineEdit_username_signIn.text()
        password_signIn = self.lineEdit_password_signIn.text()
        self.label_temperature_tankData.setText("18.43")
        self.user = self.db.authenticateLogIn(username_signIn, password_signIn)
        self.tankList = self.db.loadTankList(self.user.getUserID())
        self.numberOfTanks = len(self.tankList)
        self.label_userLetter.setText("R")
        for i in range(self.numberOfTanks - 2):
            name = "Tank" + str(i + 2)
            self.comboBox.addItem(name)
        self.tankIndex = self.comboBox.currentIndex()
        self.waterQualityList = self.db.loadWaterQualityList(
            self.tankList[self.tankIndex].getTankID())
        self.sen = Sensors("http://192.168.43.223/")
        if (self.user):
            self.displayList(self.tankIndex)
            self.stackedWidget.setCurrentIndex(3)
            self.cam.start()
            self.camTimer.timeout.connect(lambda: self.camFeedFunc())
            self.camTimer.start(100)
        else:
            print("INVALID USERNAME OR PASSWORD")

    def camFeedFunc(self):
        self.fr = self.cam.getFrame()
        self.im = cv2.imread(
            "/Users/rowanhisham/Desktop/833a7b77-7744-4662-b1b9-5a22c948285b.jpg",
            1)
        frame = cv2.cvtColor(self.im, cv2.COLOR_BGR2RGB)
        img = QtGui.QImage(frame, frame.shape[1], frame.shape[0],
                           QtGui.QImage.Format_RGB888)
        pix = QtGui.QPixmap.fromImage(img)
        self.label_camFeed.setScaledContents(True)
        self.label_camFeed.setPixmap(pix)

    def captureImage(self):
        return self.im
        # return self.fr.copy()

    def displayList(self, tankIndex):
        if (self.user):
            self.label_username_mainPage.setText(self.user.getFirstName() +
                                                 " " + self.user.getLastName())
            # self.label_user_admin.setText("")
            self.label_fishType_tankData.setText(
                self.tankList[tankIndex].getFishType())
            self.label_harvestDate_tankData.setText(
                self.tankList[tankIndex].getHarvestDate())
            self.label_feeding_tankData.setText(
                self.tankList[tankIndex].getFeedingSchedule())
            self.label_ph_tankData.setText(
                str(self.waterQualityList[0].getpH()))
            self.temperatureReading()

    def temperatureReading(self):
        print("temp timerrrrr")
        self.temp = self.sen.getTemperature()
        if (float(self.temp) >= 18):
            self.label_temperature_tankData.setText(
                "WARNING! Temperature is " + self.temp + " C")
            self.em = emailNotifier(self.user, self.temp)
            self.em.sendEmail()
        else:
            self.label_temperature_tankData.setText(self.sen.getTemperature())

    def updateTankData(self):
        self.tankIndex = self.comboBox.currentIndex()
        self.displayList(self.tankIndex)

    def signUpfromLoginPageIsClicked(self):
        self.stackedWidget.setCurrentIndex(1)

    def signUpfromsignUpPageIsClicked(self):
        self.stackedWidget.setCurrentIndex(0)
        username_signUp = self.lineEdit_username_signUp.text()
        password_signUp = self.lineEdit_password_signUp.text()
        firstName_signUp = self.lineEdit_firstName_signUp.text()
        lastName_signUp = self.lineEdit_lastName_signUp.text()
        email_signUp = self.lineEdit_email_signUp.text()

    def faceIdIsClicked(self):
        self.stackedWidget.setCurrentIndex(2)

    def goToLoginPage(self):
        self.stackedWidget.setCurrentIndex(0)

    def dashboardIsClicked(self):
        self.stackedWidget_2.setCurrentIndex(0)

    def createTankIsClicked(self):
        self.stackedWidget_2.setCurrentIndex(1)

    def createTankButtonClicked(self):
        fishType_createTank = self.lineEdit_fishType_createTank.text()
        date_createTank = self.lineEdit_date_createTank.text()
        feeding_createTank = self.lineEdit_feeding_createTank.text()
        lowerTemperatureThreshold_createTank = self.lineEdit_lowerTemperatureThreshold_createTank.text(
        )
        upperTemperatureThreshold_createTank = self.lineEdit_upperTemperatureThreshold_createTank.text(
        )
        waterQualityThreshold_createTank = self.lineEdit_waterQualityThreshold_createTank.text(
        )

    def reportIsClicked(self):
        webbrowser.open(
            "https://app.powerbi.com/view?r=eyJrIjoiZjhkMzViNTUtMDU3Yy00NTBhLTg1OWUtZjU1OGU1NzcyZjFiIiwidCI6ImVhZjYyNGM4LWEwYzQtNDE5NS04N2QyLTQ0M2U1ZDc1MTZjZCIsImMiOjh9&fbclid=IwAR29_qNsg6Nwu1QKUFX6OjKhhUDT77pEpZHJDb0ZE1-OwoRCjhy1En90DAc"
        )

    def emailIsClicked(self):
        pass

    def analyzeTankIsClicked(self):
        self.stackedWidget_2.setCurrentIndex(2)

    def settingsIsClicked(self):
        self.stackedWidget_2.setCurrentIndex(3)

    def cleaningIsClicked(self):
        pred = self.clean.predict(self.captureImage())
        if (pred == "yes"):
            self.label_fishnetNeedsCleaning_analyzeTank.setText("Yes")
        elif (pred == "no"):
            self.label_fishnetNeedsCleaning_analyzeTank.setText("No")
        else:
            self.label_fishnetNeedsCleaning_analyzeTank.setText(
                "Can't determine")

    def holesIsClicked(self):
        pred = self.holes.predict(self.captureImage())

        if (pred == "yes"):
            self.label_fishnetNeedsPatching_analyzeTank.setText("Yes")
        elif (pred == "no"):
            self.label_fishnetNeedsPatching_analyzeTank.setText("No")
        else:
            self.label_fishnetNeedsPatching_analyzeTank.setText(
                "Can't determine")

    def pipesIsClicked(self):
        pass

    def predictIsClicked(self):
        pass

    def buttonsConnections(self):
        self.button_signIn_signIn.clicked.connect(self.signInIsClicked)
        self.button_signUp_signIn.clicked.connect(
            self.signUpfromLoginPageIsClicked)
        self.button_faceID_signIn.clicked.connect(self.faceIdIsClicked)
        self.button_backToSignIn.clicked.connect(self.goToLoginPage)
        self.button_signUp_signUp.clicked.connect(
            self.signUpfromsignUpPageIsClicked)
        self.button_logout.clicked.connect(self.goToLoginPage)
        self.button_dashboard.clicked.connect(self.dashboardIsClicked)
        self.button_createTank.clicked.connect(self.createTankIsClicked)
        self.button_analyzeTank.clicked.connect(self.analyzeTankIsClicked)
        self.button_settings.clicked.connect(self.settingsIsClicked)
        self.button_cleaning_analyzeTank.clicked.connect(
            self.cleaningIsClicked)
        self.button_holes_analyzeTank.clicked.connect(self.holesIsClicked)
        self.button_pipes_analyzeTank.clicked.connect(self.pipesIsClicked)
        self.button_predict_analyzeTank.clicked.connect(self.predictIsClicked)
        self.button_create_createTank.clicked.connect(
            self.createTankButtonClicked)
        self.button_report.clicked.connect(self.reportIsClicked)
        self.button_email.clicked.connect(self.emailIsClicked)
        self.comboBox.currentIndexChanged.connect(self.updateTankData)
コード例 #10
0
class AbsorptionImager:
    def __init__(self, path, runName, voltStart, voltEnd, numPoints,
                 exposure_Seconds):
        self.path = path
        self.runName = runName
        self.voltStart = voltStart
        self.numPoints = numPoints
        self.voltArr = np.linspace(voltStart, voltEnd, numPoints)
        self.exposure_MilliSeconds = exposure_Seconds * 1000

        self.MKSFullScale = 500.0  #full scale of N2, sccm
        self.scaleFact = 1.4  #scael factor for He
        self.flowRate = 50.0
        self.binning = 1  #don't use binnig for absorption

        self.nozzleWaitTime_Seconds = 5  #time to wait for turning on or off the nozzle
        self.waitTimeToFlow_Seconds = self.nozzleWaitTime_Seconds - exposure_Seconds
        if self.waitTimeToFlow_Seconds < 0.0:
            self.waitTimeToFlow_Seconds = 0.0
        self.waitTimeToStopFlow_Seconds = self.nozzleWaitTime_Seconds

        self.camera = Camera('FAR',
                             self.exposure_MilliSeconds,
                             bin=self.binning)
        self.galvoOut = DAQPin(gv.galvoOutPin)
        self.shutterOut = DAQPin(gv.shutterPin)  #open the shutter contorl pin
        self.darkImageList = []
        self.noFlowImageList = []
        self.flowImageList = []
        self.absorptionSignalImageList = []

    def catch_Errors(self):
        if self.flowRate <= 0:
            gv.error_Sound()
            raise Exception('The flowrate is zero or invalid!')
        if self.exposure_MilliSeconds < 500:
            gv.error_Sound()
            raise Exception(
                'The camera exposure is too low. Remember you enter it as seconds'
            )

    def make_Info_File(self):
        with open('info.txt', 'w') as file:
            file.write('Run Info \n')
            file.write('Exposure time: ' + str(self.exposure_MilliSeconds) +
                       ' ms \n')
            file.write('flow wait time: ' + str(self.nozzleWaitTime_Seconds) +
                       's \n')
            file.write('binning :' + str(self.binning) + '\n')
            file.write('Nozzle flow rate: ' + str(self.flowRate) + ' SCCM \n')
            file.write('Image galvo voltages: ' + str(self.voltArr) +
                       ' volts \n')

    def save_Images(self, name, imageList):
        hdu = fits.PrimaryHDU(np.asarray(imageList))
        hdul = fits.HDUList([hdu])
        hdul.writeto(name + '.fits')

    def make_Flow(self, flowDesired):
        flowOut = DAQPin(gv.flowOutPin)
        if flowDesired > 500.0:
            raise Exception('REQUESTED FLOW IS GREATER THAN MAXIMUM')
        elif flowDesired > 0.0:
            volt = (flowDesired / (self.MKSFullScale * self.scaleFact)) * 5.0
            flowOut.write(volt)
        else:
            flowOut.write(0.0)
        flowOut.close(zero=False)

    def take_Dark_Image(self):
        self.shutterOut.close_Shutter()
        image = self.camera.aquire_Image().astype(float)
        self.shutterOut.open_Shutter()
        return image

    def take_No_Flow_Image(self):
        image = self.camera.aquire_Image().astype(float)
        return image

    def take_Flow_Image(self):
        image = self.camera.aquire_Image().astype(float)
        return image

    def make_Copies_To_Not_Modify_Originals(self, darkImage, noFlowImage,
                                            flowImage):
        #copy the images to prevent modifying them by accident!
        noFlowImage = noFlowImage.copy()
        flowImage = flowImage.copy()
        darkImage = darkImage.copy()
        return darkImage, noFlowImage, flowImage

    def construct_Absorption_Signal_Image(self, darkImage, noFlowImage,
                                          flowImage):
        eps = 1.0  #to avoid divide by zero
        darkImage, noFlowImage, flowImage = self.make_Copies_To_Not_Modify_Originals(
            darkImage, noFlowImage, flowImage)
        noFlowImage = noFlowImage - darkImage
        flowImage = flowImage - darkImage
        flowImage[
            np.abs(flowImage) <
            eps] = eps  #get rid of small numbers to prevent divide by zero
        noFlowImage[np.abs(noFlowImage) < eps] = eps
        signalImage = flowImage / noFlowImage
        return signalImage

    def save_Image_Lists(self):
        self.save_Images(self.runName + '_darkImages', self.darkImageList)
        self.save_Images(self.runName + '_noFlowImages', self.noFlowImageList)
        self.save_Images(self.runName + '_flowImages', self.flowImageList)
        self.save_Images(self.runName + '_absorptionSignalImages',
                         self.absorptionSignalImageList)

    def change_Directory_And_Catch_File_Errors(self):
        imagesFolder = self.runName + 'Folder'
        try:
            os.mkdir(self.path + '\\' + imagesFolder)
        except FileExistsError:
            gv.error_Sound()
            print('That file already exists!!')
            exit()
        except:
            raise Exception('some other file issue')
        os.chdir(self.path + '\\' + imagesFolder)

    def update_Image_Lists(self, darkImage, noFlowImage, flowImage,
                           absorptionSignalImage):
        self.darkImageList.append(darkImage)
        self.noFlowImageList.append(noFlowImage)
        self.flowImageList.append(flowImage)
        self.absorptionSignalImageList.append(absorptionSignalImage)

    def close_Pins(self):
        self.galvoOut.close()
        self.shutterOut.close()

    def wait_To_Flow_After_Dark_Image(self, ):
        time.sleep(self.waitTimeToFlow_Seconds)

    def wait_To_Stop_Flow_After_Flow_Image(self):
        time.sleep(self.waitTimeToStopFlow_Seconds)

    def run(self):
        self.change_Directory_And_Catch_File_Errors()
        self.catch_Errors()
        gv.begin_Sound()
        self.make_Flow(0.0)
        self.shutterOut.open_Shutter()
        for volt in self.voltArr:
            print(volt)
            self.galvoOut.write(volt)
            noFlowImage = self.take_No_Flow_Image()
            self.make_Flow(self.flowRate)
            darkImage = self.take_Dark_Image()
            self.wait_To_Flow_After_Dark_Image()
            flowImage = self.take_Flow_Image()
            self.make_Flow(0.0)
            self.wait_To_Stop_Flow_After_Flow_Image()
            absorptionSignalImage = self.construct_Absorption_Signal_Image(
                darkImage, noFlowImage, flowImage)
            self.update_Image_Lists(darkImage, noFlowImage, flowImage,
                                    absorptionSignalImage)
        self.close_Pins()
        self.save_Image_Lists()
        self.make_Info_File()
        gv.finished_Sound()
コード例 #11
0
class Sweeper:
    def __init__(self, GUI):
        self.GUI = GUI
        self.cameraNear = None
        self.cameraFar = None
        self.DAQDataArr = None  #array to hold data read from DAQ board. each row is a sample of data like
        # [outputVoltage, Lithium reference chamber voltage]
        self.imageArrList = [
        ]  #list to hold array of images. looks like [[imageN1,imageF1],[imageN2,imageF2],..]
        #where each image is a numpy array. So first image in each pair is for near, second for far
        self.galvoOut = DAQPin(gv.galvoOutPin)
        self.lithiumRefIn = DAQPin(gv.lithiumRefInPin)

        self.minVolt = gv.minScanVal
        self.maxVolt = gv.maxScanVal
        self.DAQVoltArr = np.linspace(self.minVolt,
                                      self.maxVolt,
                                      num=int((self.maxVolt - self.minVolt) *
                                              gv.samplesPerVoltDAQ))

        x1N = int(GUI.x1NearBox.get())
        x2N = int(GUI.x2NearBox.get())
        y1N = int(GUI.y1NearBox.get())
        y2N = int(GUI.y2NearBox.get())
        self.imageParamNear = [x1N, x2N, y1N, y2N]
        x1F = int(GUI.x1FarBox.get())
        x2F = int(GUI.x2FarBox.get())
        y1F = int(GUI.y1FarBox.get())
        y2F = int(GUI.y2FarBox.get())
        self.imageParamFar = [x1F, x2F, y1F, y2F]
        self.numExp = int(GUI.expNumBox.get())
        self.imageStartVolt = float(GUI.startVoltBox.get())
        self.imageStopVolt = float(GUI.stopVoltBox.get())
        self.expTimeNear = int(GUI.expTimeNearBox.get())
        self.expTimeFar = int(GUI.expTimeFarBox.get())
        self.binSizeNear = int(self.GUI.binSizeNearBox.get())
        self.binSizeFarX = int(self.GUI.binSizeFarBoxX.get())
        self.binSizeFarY = int(self.GUI.binSizeFarBoxY.get())

        if self.imageStartVolt < self.minVolt or self.imageStartVolt > self.maxVolt or self.imageStopVolt < self.minVolt or self.imageStopVolt > self.maxVolt:
            raise Exception(
                'VOLTAGE RANGE FOR IMAGE SWEEP EXCEEDS MAXIMUM AND/OR MINIMUM ALLOWED RANGE!'
            )
        if self.imageStopVolt < self.imageStartVolt:
            raise Exception(
                'ENDING VOLTAGE IS BEFORE STARTING VOLTAGE FOR IMAGE SWEEP!')
        self.imageVoltArr = np.linspace(self.imageStartVolt,
                                        self.imageStopVolt,
                                        num=self.numExp)

    def sweep(self):
        #this sweeps the galvo output voltage. There are two arrays, DAQVoltArr and imageVoltArr. DAQVoltArr contains all
        #the voltage values to collect DAQ data at. imageVoltArr contains the values to take iamges at. imageVolt array's
        #range must be less than or equal to DAQVoltArr's range. The loop searchs for which step is next, jumps to that point
        #and then increments the counter.
        self._initialize_Cameras()
        if self.cameraNear is not None:
            for _ in range(10):
                self.cameraNear.aquire_Image()

        i = 0  #counter for DAQVoltArr
        j = 0  #coutner for imageVoltArr
        loop = True
        volt = 0
        tempList = []
        gv.begin_Sound()
        lastImage = False  #this is so that the last image is taken. It will flip from False to True once, and then no more
        #images
        takeImage = False  #wether to take images
        totalSteps = self.DAQVoltArr.shape[0] + self.imageVoltArr.shape[0]

        print('\n \n \n \n')
        print('-----SWEEPING NOW----')
        time.sleep(
            .001
        )  #if you don't wait a little then the progress bar and other messages will get messed up
        #in the terminal because they will try to write on top of each other
        progressBar = tqdm(total=totalSteps)
        while loop == True:
            progressBar.update()
            if i == self.DAQVoltArr.shape[
                    0] - 1 and j == self.imageVoltArr.shape[0] - 1:
                loop = False
                volt = self.DAQVoltArr[i]
                if lastImage == False:  #if the last image occurs at the last DAQ voltage as well
                    takeImage = True
                    lastImage = False
            else:
                if self.DAQVoltArr[i] == self.imageVoltArr[
                        j]:  #if potential next voltages are equal
                    volt = self.DAQVoltArr[i]
                    if i != self.DAQVoltArr.shape[
                            0] - 1:  #don't increment if its at the end!
                        i += 1
                    if j != self.imageVoltArr.shape[
                            0] - 1:  #don't increment if its at the end!
                        j += 1
                        takeImage = True
                elif self.DAQVoltArr[i] < self.imageVoltArr[j]:
                    if i != self.DAQVoltArr.shape[
                            0] - 1:  #don't increment if its at the end!
                        volt = self.DAQVoltArr[i]
                        i += 1
                    else:
                        volt = self.imageVoltArr[i]
                        j += 1
                        takeImage = True
                elif self.imageVoltArr[j] < self.DAQVoltArr[i]:
                    if j != self.imageVoltArr.shape[
                            0] - 1:  #don't increment if its at the end!
                        volt = self.imageVoltArr[j]
                        j += 1
                        takeImage = True
                    elif lastImage == False:  #special case for taking the last image
                        lastImage = True  #Now it won't do this again. The loop will come here from now on, but it won't
                        #do anything but increment the galvo voltage because j!=self.imageVoltArr.shape[0]-1 will be\
                        #false and lastImage==False will be false also
                        volt = self.imageVoltArr[j]
                        takeImage = True
                    else:
                        volt = self.DAQVoltArr[i]
                        i += 1
            self.galvoOut.write(volt)
            tempList.append([volt, self.lithiumRefIn.read(numSamples=1000)])
            if takeImage == True:
                #for i in range(10):
                #    self._take_Exposures()
                #print((time.time()-t)/10)
                self.imageArrList.append(
                    self._take_Exposures()
                )  #the appended object is a list like [imageNear,imageFar]. If
                #there is no camera active for a given image the entry is None
                takeImage = False
        progressBar.close()
        time.sleep(
            .01
        )  #like I said above. Pause to allow the progress bar to finish writting so it doesn't get messed up
        print('-----END OF SWEEP-----')
        self._close_DAQ_Pins()
        self._close_Cameras()
        self.DAQDataArr = np.asarray(tempList)
        gv.finished_Sound()
        #np.savetxt('data1.txt',self.DAQDataArr)
        #y=self.DAQDataArr[:,1]
        #plt.plot(y)
        #plt.show()
        self.GUI.imageArrList = self.imageArrList  #this way if there is a previous list it is overwritten
        self.GUI.DAQDataArr = self.DAQDataArr

    def _close_DAQ_Pins(self):
        self.galvoOut.close()
        self.lithiumRefIn.close()

    def _initialize_Cameras(self):
        binNearX = self.binSizeNear
        binNearY = self.binSizeNear
        binFarX = self.binSizeFarX
        binFarY = self.binSizeFarY
        if binFarX <= 0 and binFarY <= 0:
            raise Exception('Both bin values cannot be zero')
        elif binFarX == 0:
            binFarX = binFarY
        elif binFarY == 0:
            binFarY = binFarX

        if binNearX <= 0 and binNearY <= 0:
            raise Exception('Both bin values cannot be zero')
        elif binNearX == 0:
            binNearX = binNearY
        elif binNearY == 0:
            binNearY = binNearX

        if self.GUI.cameraVarData.get() == 'BOTH':
            self.cameraFar = Camera('FAR',
                                    self.expTimeFar,
                                    self.imageParamFar,
                                    binx=binFarX,
                                    biny=binFarY)
            self.cameraNear = Camera('NEAR',
                                     self.expTimeNear,
                                     self.imageParamNear,
                                     binx=binNearX,
                                     biny=binNearY)
        elif self.GUI.cameraVarData.get() == 'NEAR':
            self.cameraNear = Camera('NEAR',
                                     self.expTimeNear,
                                     self.imageParamNear,
                                     binx=binNearX,
                                     biny=binNearY)
        elif self.GUI.cameraVarData.get() == 'FAR':
            self.cameraFar = Camera('FAR',
                                    self.expTimeFar,
                                    self.imageParamFar,
                                    binx=binFarX,
                                    biny=binFarY)
        else:
            gv.error_Sound()
            raise Exception('NO VALID CAMERA NAME PROVIDED')

    def _take_Exposure_Wrapper(self, resultsDict, camera):
        #wrapper for taking images concurrently.
        if camera.camName == 'NEAR':
            resultsDict['NEAR'] = self.cameraNear.aquire_Image()
        elif camera.camName == 'FAR':
            resultsDict['FAR'] = self.cameraFar.aquire_Image()
        else:
            gv.error_Sound()
            raise Exception('NO VALID CAMERA NAME PROVIDED')

    def _take_Exposures(self):
        if self.GUI.cameraVarData.get() == 'BOTH':
            resultsDict = {
            }  #this is used to add the images taken concurrently. I use a dictionary so I can keep track of
            #which image belongs to which camera
            T1 = threading.Thread(target=self._take_Exposure_Wrapper,
                                  args=(resultsDict, self.cameraNear))
            T2 = threading.Thread(target=self._take_Exposure_Wrapper,
                                  args=(resultsDict, self.cameraFar))
            T1.start()
            T2.start()
            T1.join()
            T2.join()
            imgNear = resultsDict['NEAR']
            imgFar = resultsDict['FAR']
            return [imgNear, imgFar]
        elif self.GUI.cameraVarData.get() == 'NEAR':
            imgNear = self.cameraNear.aquire_Image()
            return [imgNear, None]
        elif self.GUI.cameraVarData.get() == 'FAR':
            imgFar = self.cameraFar.aquire_Image()
            return [None, imgFar]
        else:
            gv.error_Sound()
            raise Exception('NO VALID CAMERA NAME PROVIDED')

    def _close_Cameras(self):
        if self.GUI.cameraVarData.get() == 'BOTH':
            self.cameraNear.close()
            self.cameraFar.close()
        elif self.GUI.cameraVarData.get() == 'NEAR':
            self.cameraNear.close()
        elif self.GUI.cameraVarData.get() == 'FAR':
            self.cameraFar.close()
        else:
            raise Exception('NO VALID CAMERA NAME PROVIDED')
コード例 #12
0
ファイル: test.py プロジェクト: RowanHisham/codeGeist
from CameraClass import Camera
import cv2

while (1):
    cam = Camera(camAddress=0)
    cam.start()
    while (1):
        # cam.setDaemon(True)
        fr = cam.getFrame()
        cv2.imshow("fr", fr)
        cv2.waitKey(10)

    cam.closeCam()
class GUI:
    def __init__(self):
        self.settingsList = [
        ]  #list of tkinter field objects to save to a settings file
        self.x1Box = None  #tkinter box object for image parameters
        self.x2Box = None  #tkinter box object for image parameters
        self.y1Box = None  #tkinter box object for image parameters
        self.y2Box = None  #tkinter box object for image parameters
        self.voltOnResArr = None  #array to to hold voltage values to scan over near resonance
        self.voltPlotArr = None  #array to be used in plotting
        self.camera = None  #to hold the camera opject
        self.galvoOut = None  #galvo voltage control
        self.shutterOut = DAQPin(gv.shutterPin)  #shutter control for OP laser
        self.sigmaGuess = .025  #guess of value for sigma in volts
        self.gammaGuess = 1e-3  #guess for value of gamma in volts
        self.window = tk.Tk()
        self.window.title("Fast Height Finder")
        self.window.geometry('800x600')

        lbl1 = tk.Label(self.window, text='Profile Center (v)')
        lbl1.grid(column=0, row=0, sticky='E')

        self.v0Box = tk.Entry(self.window)
        self.v0Box.config(width=5)
        self.v0Box.grid(column=1, row=0, sticky='W')
        self.settingsList.append(self.v0Box)

        lbl32 = tk.Label(self.window, text='bin size')
        lbl32.grid(column=2, row=0)

        self.binSizeBox = tk.Entry(self.window)
        self.binSizeBox.config(width=5)
        self.binSizeBox.grid(column=3, row=0, sticky='W')
        self.settingsList.append(self.binSizeBox)

        lbl3 = tk.Label(self.window, text='FWHM (v)')
        lbl3.grid(column=0, row=1, sticky='E')

        self.fwhmBox = tk.Entry(self.window)
        self.fwhmBox.config(width=5)
        self.fwhmBox.grid(column=1, row=1, sticky='W')
        self.settingsList.append(self.fwhmBox)

        lbl3 = tk.Label(self.window, text='num images off resonance')
        lbl3.grid(column=0, row=2)

        self.numImgOffResBox = tk.Entry(self.window)
        self.numImgOffResBox.config(width=5)
        self.numImgOffResBox.grid(column=1, row=2, sticky='W')
        self.settingsList.append(self.numImgOffResBox)

        lbl31 = tk.Label(self.window, text='Exp time (ms)')
        lbl31.grid(column=2, row=1)

        self.expTimeBox = tk.Entry(self.window)
        self.expTimeBox.config(width=5)
        self.expTimeBox.grid(column=3, row=1, sticky='W')
        self.settingsList.append(self.expTimeBox)

        lbl3 = tk.Label(self.window, text='num images on resonance')
        lbl3.grid(column=0, row=3)

        self.numImgOnResBox = tk.Entry(self.window)
        self.numImgOnResBox.config(width=5)
        self.numImgOnResBox.grid(column=1, row=3, sticky='W')
        self.settingsList.append(self.numImgOnResBox)

        lbl5 = tk.Label(self.window, text='image x1')
        lbl5.grid(column=0, row=4)
        self.x1Box = tk.Entry(self.window)
        self.x1Box.config(width=5)
        self.x1Box.grid(column=1, row=4, sticky='W')
        self.settingsList.append(self.x1Box)

        lbl5 = tk.Label(self.window, text='image x2')
        lbl5.grid(column=2, row=4)
        self.x2Box = tk.Entry(self.window)
        self.x2Box.config(width=5)
        self.x2Box.grid(column=3, row=4, sticky='W')
        self.settingsList.append(self.x2Box)

        lbl5 = tk.Label(self.window, text='image y1')
        lbl5.grid(column=0, row=5)
        self.y1Box = tk.Entry(self.window)
        self.y1Box.config(width=5)
        self.y1Box.grid(column=1, row=5, sticky='W')
        self.settingsList.append(self.y1Box)

        lbl5 = tk.Label(self.window, text='image y2')
        lbl5.grid(column=2, row=5)
        self.y2Box = tk.Entry(self.window)
        self.y2Box.config(width=5)
        self.y2Box.grid(column=3, row=5, sticky='W')
        self.settingsList.append(self.y2Box)

        lbl4 = tk.Label(self.window, text='Camera')
        lbl4.grid(column=0, row=6)

        self.cameraVar = tk.StringVar(self.window)
        self.cameraVar.set("FAR")
        cameraChoice = ["NEAR", "FAR"]
        CAMERA_MENU = tk.OptionMenu(self.window, self.cameraVar, *cameraChoice)
        CAMERA_MENU.grid(column=1, row=6, columnspan=2, sticky='W')
        self.settingsList.append(self.cameraVar)

        lbl4 = tk.Label(self.window, text='Shutter')
        lbl4.grid(column=2, row=6)

        self.shutterVar = tk.StringVar(self.window)
        self.shutterVar.set("OPEN")
        shutterChoice = ["CLOSED", "OPEN"]
        shutter_MENU = tk.OptionMenu(self.window,
                                     self.shutterVar,
                                     *shutterChoice,
                                     command=self.toggle_Shutter)
        shutter_MENU.grid(column=3, row=6, columnspan=2, sticky='W')
        self.settingsList.append(self.shutterVar)

        self.saveDataVar = tk.BooleanVar()
        saveDataCheckButton = tk.Checkbutton(self.window,
                                             text='save data',
                                             variable=self.saveDataVar)
        saveDataCheckButton.grid(column=1, row=7)
        self.settingsList.append(self.saveDataVar)

        self.ratioVar = tk.BooleanVar()
        ratioVarButton = tk.Checkbutton(self.window,
                                        text='ratio',
                                        variable=self.ratioVar)
        ratioVarButton.grid(column=1, row=8)
        self.settingsList.append(self.ratioVar)

        self.showPlotVar = tk.BooleanVar()
        showDataAnalysiButton = tk.Checkbutton(self.window,
                                               text='Show plot',
                                               variable=self.showPlotVar)
        showDataAnalysiButton.grid(column=1, row=9)
        self.settingsList.append(self.showPlotVar)

        lbl3 = tk.Label(self.window, text='Run name')
        lbl3.grid(column=0, row=15)

        self.fileName = tk.Entry(self.window)
        self.fileName.config(width=60)
        self.fileName.grid(column=1, row=15, sticky='W', columnspan=40)
        self.settingsList.append(self.fileName)

        lbl3 = tk.Label(self.window, text='Folder path')
        lbl3.grid(column=0, row=16)

        self.folderPath = tk.Entry(self.window)
        self.folderPath.config(width=60)
        self.folderPath.grid(column=1, row=16, sticky='W', columnspan=40)
        self.settingsList.append(self.folderPath)

        runButton = tk.Button(self.window,
                              text='RUN',
                              font=("Arial", 20),
                              background="green",
                              command=self.run)
        runButton.config(height=2, width=10)
        runButton.grid(column=0, row=17, columnspan=4, rowspan=4)

        coolCameraButton = tk.Button(self.window,
                                     text='cool camera',
                                     background="royal blue",
                                     command=self.cool_Camera)
        #coolCameraButton.config(height=2, width=10)
        coolCameraButton.grid(column=0, row=21, columnspan=4, rowspan=4)

        self.load_Settings()

        self.window.protocol("WM_DELETE_WINDOW", self.close_GUI)
        self.window.mainloop()

    def toggle_Shutter(self, x):
        if x == 'CLOSED':
            self.close_Aperture()
        if x == 'OPEN':
            self.open_Aperture()

    def cool_Camera(self):
        #cool the far field camera down
        if self.cameraVar.get() == "NEAR":
            print("YOU CAN'T COOL THE NEAR FIELD CAMERA")
            gv.warning_Sound()
        else:
            tempCamera = Camera(self.cameraVar.get(),
                                1000)  #the camera will cool down
            tempCamera.close()  #now close it. It will stay cool though

    def open_Aperture(self):
        #open the OP shutter
        self.shutterOut.write_Low()
        time.sleep(.01)

    def close_Aperture(self):
        #close the OP shutter
        self.shutterOut.write_High()
        time.sleep(.01)

    def close_GUI(self):
        self.shutterOut.close()
        self.save_Settings()
        self.window.destroy()
        sys.exit()

    def initialize_Camera(self):
        x1 = int(self.x1Box.get())  #image region values
        y1 = int(self.y1Box.get())  #image region values
        x2 = int(self.x2Box.get())  #image region values
        y2 = int(self.y2Box.get())  #image region values
        imageParams = [x1, x2, y1, y2]
        binSize = int(self.binSizeBox.get())  #binning value

        #initialize camera object. can be near or far field camera
        expTime = int(self.expTimeBox.get())  #exposure time, ms
        whichCam = self.cameraVar.get()  #which camera to use, 'FAR' or 'NEAR'
        self.camera = Camera(whichCam,
                             expTime,
                             imageParams=imageParams,
                             bin=binSize)

    def close_Camera(self):
        self.camera.close()
        self.camera = None

    def initialize_Scan_And_Plot_Arrays(self):
        v0 = float(self.v0Box.get())  #center value of transition from user
        df = float(self.fwhmBox.get())  #fwhm value from user
        offResFact = 4  #go this many fwhm away from center for 'far' off resonance background
        numImagesOnRes = int(self.numImgOnResBox.get()
                             )  #number of images to take near the resonance
        numImagesOffRes = int(self.numImgOffResBox.get())
        self.voltOffResArr = np.linspace(
            v0 - offResFact * df - df / 2,
            v0 - offResFact * df + df / 2,
            num=numImagesOffRes
        )  #voltage value to take images at 'far' off resonance
        self.voltOnResArr = np.linspace(
            v0 - 1.5 * df, v0 + 1.5 * df, num=numImagesOnRes
        )  #array of voltages to take images of near the peak
        self.voltPlotArr = np.linspace(
            v0 - (offResFact + 1) * df, v0 + (offResFact + 1) * df,
            num=1000)  #voltages to make plot with. This should
        #be dense and uniform so it looks good
    def run(self):
        self.save_Settings()
        self.initialize_Camera()
        if os.path.isdir(self.folderPath.get()) == False:
            print('-----ERROR-----------')
            print('YOU HAVE ENTERED AN INVALID FOLDERPATH')
        if os.path.isfile(self.folderPath.get() + '\\' + self.fileName.get() +
                          '.png') == True:
            print('--------------ERROR-------')
            print('THERE IS ALREADY A FILE WITH THAT NAME IN THAT FOLDER')
            gv.error_Sound()
            sys.exit()

        if self.ratioVar.get() == True:
            self.sweep_With_Shutter()
        else:
            self.sweep_Without_Shutter()
        self.camera.close()

    def sweep_With_Shutter(self):
        self.initialize_Scan_And_Plot_Arrays()
        self.initialize_Camera()

        voltList = []  #list to hold voltage values of corresponding images
        signalList1 = []  #list for signal values for apeture open
        signalList2 = []  #list for signal values for apeture open

        gv.begin_Sound(noWait=True)  #beep without waiting after the beep
        self.galvoOut = DAQPin(gv.galvoOutPin)  #open the galvo control pin
        #take images 'far' off resonance. This scan is very close to together
        for volt in self.voltOffResArr:
            print(volt)
            self.galvoOut.write(volt)  #move galvo to new position
            voltList.append(volt)  #record the voltage value

            self.open_Aperture()  #'turn on' the optical pumping
            img = self.camera.aquire_Image()
            signalList1.append(np.mean(img))

            self.close_Aperture()  #'turn off' the optical pumping
            img = self.camera.aquire_Image()
            signalList2.append(np.mean(img))
        #now sweep around the peak near resonance
        for volt in self.voltOnResArr:
            self.galvoOut.write(volt)  #move galvo to new position
            voltList.append(volt)  #record the voltage value

            self.open_Aperture()  #'turn on' the optical pumping
            img = self.camera.aquire_Image()  #capture an image
            signalList1.append(np.mean(img))  #add the average of the pixels

            self.close_Aperture()  #'turn off' the optical pumping
            img = self.camera.aquire_Image()  #capture an image
            signalList2.append(np.mean(img))  #add the average of the pixels

        self.galvoOut.close()  #close and zero the pin
        self.open_Aperture()  #open the shutter up again when done
        gv.finished_Sound(noWait=True)  #beep without waiting after the beep

        #convert lists to arrays
        signalArr1 = np.asarray(signalList1)
        signalArr2 = np.asarray(signalList2)
        voltArr = np.asarray(voltList)

        #fit the data and get the optimal parameters and the error
        params1, perr1 = self.fit_Data(voltArr, signalArr1)
        params2, perr2 = self.fit_Data(voltArr, signalArr2)

        plt.close('all')
        plt.figure(figsize=(13, 8))
        plt.plot(self.voltPlotArr,
                 self.spectral_Profile(self.voltPlotArr, *params1),
                 c='blue',
                 label='fit, opened shutter')
        plt.plot(self.voltPlotArr,
                 self.spectral_Profile(self.voltPlotArr, *params2),
                 c='red',
                 label='fit, closed shutter')
        plt.scatter(voltArr,
                    signalArr1,
                    label='data, opened shutter',
                    c='blue')
        plt.scatter(voltArr,
                    signalArr2,
                    label='data, closed shutter',
                    c='red',
                    marker='x',
                    s=100)

        v0 = (params1[0] + params2[0]
              ) / 2  #Get the center from the average of the two centers
        floor = (params1[1] + params2[1]
                 ) / 2  #get the floor from the average of the two floors
        #now use the v0 above for when the user runs again. This helps compensate for the laser drifting without the user
        #having to
        self.v0Box.delete(0, 'end')  #clear existing number
        self.v0Box.insert(0, str(np.round(v0, 3)))  #insert new number
        plt.axvline(x=v0, c='r', linestyle=':')
        plt.grid()
        plt.text(v0, floor,
                 np.round(float(v0),
                          3))  #TODO: WHY IS THIS NOT WORKING ONLY HERE?

        plt.legend()
        ratio = np.round(params1[1] / params2[1], 2)
        error = np.round(
            ratio * np.sqrt((perr1[1] / params1[1])**2 +
                            (perr2[1] / params2[1])**2), 3)
        plt.suptitle('Ratio of open to close shutter height = ' + str(ratio) +
                     ' +/- ' + str(error))
        plt.title("shutter open= " + str(np.round(params1[1], 2)) + ' +/-' +
                  str(np.round(perr1[1], 1)) + " . shutter closed= " +
                  str(np.round(params2[1], 2)) + ' +/-' +
                  str(np.round(perr2[1], 1)))
        if self.saveDataVar.get() == True:
            plt.savefig(self.folderPath.get() + '\\' + self.fileName.get() +
                        'Graph.png')
        if self.showPlotVar.get() == True:
            plt.show()

    def sweep_Without_Shutter(self):
        self.initialize_Scan_And_Plot_Arrays()
        self.initialize_Camera()

        voltList = []
        signalList = []

        gv.begin_Sound(noWait=True)  #beep without waiting after the beep
        self.galvoOut = DAQPin(gv.galvoOutPin)
        #take images 'far' off resonance. This scan is very close to together
        for volt in self.voltOffResArr:
            self.galvoOut.write(volt)  #move the galvo to a new voltage value
            voltList.append(volt)  #record the voltage
            img = self.camera.aquire_Image()  #capture image
            signalList.append(
                np.mean(img))  #add the average of the image's pixels

        for volt in self.voltOnResArr:
            print(volt)
            self.galvoOut.write(volt)  #move the galvo to a new voltage value
            voltList.append(volt)  #record the voltage
            img = self.camera.aquire_Image()  #capture image
            print(np.mean(img))
            signalList.append(
                np.mean(img))  #add the average of the image's pixels
        self.galvoOut.close()  #close and zero the galvo
        self.camera.close()
        self.open_Aperture()  #open the apeture up when done
        gv.finished_Sound(noWait=True)  #beep without waiting after the beep
        voltArr = np.asarray(voltList)
        signalArr = np.asarray(signalList)

        params, perr = self.fit_Data(voltArr, signalArr)
        print(params)

        plt.close('all')
        plt.plot(self.voltPlotArr,
                 self.spectral_Profile(self.voltPlotArr, *params),
                 c='orange',
                 label='fit')
        plt.scatter(voltArr, signalArr, label='data')

        v0 = params[0]
        floor = params[2]
        #now use the v0 above for when the user runs again. This helps compensate for the laser drifting without the user
        #having to
        self.v0Box.delete(0, 'end')  #clear existing number
        self.v0Box.insert(0, str(np.round(v0, 3)))  #insert new number
        plt.axvline(x=v0, c='r', linestyle=':')
        plt.text(v0, floor, np.round(float(v0), 3))
        plt.legend()
        plt.grid()
        plt.title('Height = ' + str(np.round(params[1], 1)) + '+/- ' +
                  str(np.round(perr[1], 1)))

        if self.saveDataVar.get() == True:
            plt.savefig(self.folderPath.get() + '\\' + self.fileName.get() +
                        'Graph.png')
        if self.showPlotVar.get() == True:
            plt.show()

    def fit_Data(self, x, y):
        print('here')
        #fit the data to get the optimal parameters
        x0Guess = float(self.v0Box.get())
        aGuess = np.max(y) - np.min(y)
        bGuess = np.min(y)
        guess = [x0Guess, aGuess, bGuess, self.sigmaGuess, self.gammaGuess]
        bounds = ([-5, 0, 0, 0, 0], [5, 100000, 100000, .1, .1])
        if bGuess > bounds[1][2] or aGuess > bounds[1][1]:
            print(
                'GUESS VALUES ARE LARGER THAN BOUNDS. SIGNAL STRENGTH IS VERY HIGH'
            )
            gv.error_Sound()
            sys.exit()
        try:
            params, pcov = spo.curve_fit(self.spectral_Profile,
                                         x,
                                         y,
                                         p0=guess,
                                         bounds=bounds)
        except:
            print('FIT FAILED')
            plt.plot(x, y)
            plt.show()
        perr = np.sqrt(np.diag(pcov))

        return params, perr

    def spectral_Profile(self, x, x0, a, b, sigma, gamma):
        v0 = sps.voigt_profile(0, sigma, gamma)
        v = sps.voigt_profile(x - x0, sigma, gamma)
        return a * (v / v0) + b

    def save_Settings(self):
        file = open("fastHeightFinderGUI_Settings.txt", "w")
        for item in self.settingsList:
            file.write(str(item.get()) + '\n')
        file.close()

    def load_Settings(self):
        try:
            file = open("fastHeightFinderGUI_Settings.txt", "r")
        except:
            print("NO SETTINGS FILE FOUND")
            return
        i = 0
        for item in file:
            item = item.strip()
            if i >= len(self.settingsList):
                pass
            else:
                if isinstance(self.settingsList[i], tk.StringVar):
                    self.settingsList[i].set(item)
                elif isinstance(self.settingsList[i], tk.Entry):
                    self.settingsList[i].insert(0, item)
                elif isinstance(self.settingsList[i], tk.BooleanVar):
                    if item == 'False' or item == 'True':
                        self.settingsList[i].set(item)
            i += 1
        file.close()