def aquire_Data(self): self.catch_Errors_Aquisition() self.save_Settings() # #check that there is flow. This is not foolproof because I do not use the dawboard if int(float(self.flowRateBox.get())) == 0: gv.error_Sound() print('FLOW RATE IS ZERO') #turn on the nozzle and open the shutter gv.begin_Flow_Sound() self.make_Flow() shutterOut = DAQPin(gv.shutterPin) #open the shutter contorl pin shutterOut.open_Shutter() #open the shutter time.sleep(int(self.nozzleWaitBox.get())) # SWEEP t = time.time() sweeper = Sweeper(self) sweeper.sweep() print(time.time() - t) #turn off the nozzle and close shutter shutterOut.close_Shutter() #close the aperture shutterOut.close() #close the shutter control pin self.flowRateBox.delete(0, 'end') self.flowRateBox.insert(0, '0') self.make_Flow() self.save_Fits_Files() self.save_Data() self.make_Info_File()
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()