def __init__(self, text, colour = None, size = None): Spectrum.__init__(self, text) self.colour = colour self.size = size self.make_spacer_line() self.construct()
def multi_readout_analyze(folder, ccd_height = 100., plot = True, freq = None): """Analyze several readout measurements in different files for readout diagnosys The readout files in dm3 format must be contained in a folder, preferentely numered in the order of acquisition. Parameters ---------- folder : string Folder where the dm3 readout files are stored ccd_heigh : float plot : bool freq : float Frequency of the camera Returns ------- Dictionary """ from spectrum import Spectrum files = glob.glob1(folder, '*.nc') if not files: files = glob.glob1(folder, '*.dm3') spectra = [] variances = [] binnings = [] for f in files: print os.path.join(folder,f) s = Spectrum(os.path.join(folder,f)) variance, channel_mean, norm_time_mean = analyze_readout(s) s.readout_analysis = {} s.readout_analysis['variance'] = variance.mean() s.readout_analysis['pattern'] = channel_mean s.readout_analysis['time'] = norm_time_mean if not hasattr(s,'binning'): s.binning = float(os.path.splitext(f)[0][1:]) if freq: s.readout_frequency = freq s.ccd_height = ccd_height s.save(f) spectra.append(s) binnings.append(s.binning) variances.append(variance.mean()) pixels = ccd_height / np.array(binnings) plt.scatter(pixels, variances, label = 'data') fit = np.polyfit(pixels, variances,1, full = True) if plot: x = np.linspace(0,pixels.max(),100) y = x*fit[0][0] + fit[0][1] plt.plot(x,y, label = 'linear fit') plt.xlabel('number of pixels') plt.ylabel('variance') plt.legend(loc = 'upper left') print "Variance = %s * pixels + %s" % (fit[0][0], fit[0][1]) dictio = {'pixels': pixels, 'variances': variances, 'fit' : fit, 'spectra' : spectra} return dictio
def __init__(self, P): self.power = P data = self.get_data() S = self.calc_scaling_factor() bins = data[:, 0] vals = data[:, 1][1:] err = data[:, 2][1:] Spectrum.__init__(self, bins, vals, err * vals, S)
def plottest(filename = None, outputpdf = "test.pdf"): """ Argument: filename Optional: outputpdf, default to test.pdf in current directory """ if filename ==None: raise IOError("Needs to give input filename.") s = Spectrum(filename) s.plot1D(outputpdf) return
def plot_unfolded_spectra(): """Docstring.""" # get data unfolded_data = Unfold_NEBP() # convert to spectrum object unfolded_spectrum_gravel = Spectrum(unfolded_data.eb, unfolded_data.sol_gravel, 0) unfolded_spectrum_maxed = Spectrum(unfolded_data.eb, unfolded_data.sol_maxed, 0) # fig = plt.figure(0, figsize=(10, 6)) ax = fig.add_subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('Energy $MeV$') ax.set_ylabel(r'$\Phi$ $\frac{1}{cm^2 s MeV}$') # ax.plot(*unfolded_spectrum_gravel.plot('plot', 'diff'), color='grey', label='Gravel') ax.plot(*unfolded_spectrum_maxed.plot('plot', 'diff'), color='indigo', label='MAXED') # ax.legend() fig.savefig('plot/nebp.png', dpi=300) # ------------------------------------------------------------------------- # evolution plot # setup plotting environment fig = plt.figure(1, figsize=(10, 6)) ax = fig.add_subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('Energy $MeV$') ax.set_ylabel(r'$\Phi$ $\frac{1}{cm^2 s MeV}$') # create some colors colors = cm.magma(np.linspace(0, 1, len(unfolded_data.evolution)))[::-1] for i, iteration in enumerate(unfolded_data.evolution): # convert to spectrum object unfolded_spectrum = Spectrum(unfolded_data.eb, iteration, 0) # plot the data ax.plot(*unfolded_spectrum.plot('plot', 'diff'), color=colors[i], lw=0.5) # save it fig.savefig('plot/nebp_gravel_evolution.png', dpi=300) return
def text_load(path: str, filename: str) -> Spectrum: """ Loads the standardized ASCII format Spectrum file as written by text_write. Note: If for some reason, the redshift and/or gmag values cannot be converted to a float, they will be assigned a value of -1 :param path: /path/to/input file :param filename: input file name :type path: str :type filename: str :return: Loaded Spectrum :rtype: Spectrum :raises: FileNotFoundError """ fileCheck(path, filename) with open(join(path, filename), 'r') as infile: """ Read header. File format: namestring=55555-4444-333,z=float(),gmag=float() wavelength,flux density,error Parse the first line, use the second as CSV reader input """ header = infile.readline().strip().split(',') namestring = fns(header[0]) try: z = float(header[1].strip("z=")) except ValueError: z = -1 try: gmag = float(header[2].strip("gmag=")) except ValueError: gmag = -1 reader = DictReader(infile, fieldnames=infile.readline().strip().split(',')) wls = [] flux = [] err = [] for row in reader: try: wls.append(int(row['wavelength'])) except ValueError: wls.append(float(row['wavelength'])) flux.append(float(row['flux density'])) err.append(float(row['error'])) spec = Spectrum(namestring=namestring, z=z, gmag=gmag) spec.setDict(wls, flux, err) return spec
def make_spectrum_plotitem( spec: Spectrum, color: str = None ) -> Gnuplot.Data: """ Takes in a Spectrum class and returns Gnuplot.Data format for plotting using the data within the Spectrum object :param spec: :type spec: Spectrum :param color: :type color: str :return: :rtype: Gnuplot.Data """ if color is not None: _with = f' lc "{color}"' return make_line_plotitem( spec.getWavelengths(), spec.getFluxlist(), title=spec.getNS(), with_=_with )
def mutli_scale( primary: Spectrum, speclist: Iterable[ Spectrum ], scale_wl: float = DEFAULT_SCALE_WL, scale_radius=DEFAULT_SCALE_RADIUS ) -> List[ Spectrum ]: """ Multiprocessing Spectrum.scale() method. Scales speclist members to that of the primary Spectrum, returning a list in the same order as it was provided. :param primary: Spectrum object to scale all speclist memebers to :type primary: Spectrum :param speclist: Iterable of Spectrum objects to scale to primary :type speclist: Iterable :param scale_wl: Wavelength at which to determine scale factor. Defaults to DEFAULT_SCALE_WL in common.constants :type scale_wl: float :param scale_radius: Radius at which to determine scale factor. Defaults to DEFAULT_SCALE_RADIUS :type scale_radius: float :return: List of scaled Spectrum objects :rtype: list """ from tools.async_tools import generic_ordered_multiprocesser scale_flux = primary.aveFlux( central_wl=scale_wl, radius=scale_radius ) inputV = [ (spec, scale_flux, scale_wl, scale_radius) for spec in speclist ] speclist = [ ] generic_ordered_multiprocesser( inputV, __multi_scale_wrapper, speclist ) return speclist
def divide(numerator: Spectrum, denominator: Spectrum, wl_low: float = None, wl_high: float = None) -> Spectrum: """ Performs a point-by-point division of the numerator spectrum by the denominator spectrum. If wavelength ranges are not specificed, will use the entirely of the overlapping spectra. :param numerator: :type numerator: Spectrum :param denominator: :type denominator: Spectrum :param wl_low: :type wl_low: float :param wl_high: :type wl_high: float :return: :rtype: Spectrum """ wls = align_wavelengths(denominator, numerator, wl_low, wl_high) divided = Spectrum() for wl in wls: n, n_e = numerator[wl] d, d_e = denominator[wl] flux = n / d err = (pow(n_e / d, 2) + pow(n / (d**2) * d_e, 2))**(0.5) divided[wl] = (flux, err) return divided
def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowTitle("NeutronPy") #We'll be using GridLayout so each pyqt instances such as Beamline, Materials, ImageViewer, Spectrum #can be displayed in their corresponding position as we desire layout = QGridLayout() #Creating an instance of these classes for our window #Robust so we can create multiply main.py windows for different operations in the future #TODO: Robustness to create new separate main windows for other imaging experiments beamline = Beamline() materials = Materials() imageviewer = ImageViewerWindow() spectrum = Spectrum(beamline, materials, imageviewer) #Defining where these instances go on the grid layout.addWidget(beamline, 0, 4, 1, 1) layout.addWidget(materials, 2, 2, 1, 3) layout.addWidget(spectrum, 0, 2, 2, 2) layout.addWidget(imageviewer, 0, 0, 3, 2) #Preset height and width height = 800 width = 1550 self.setMinimumSize(width, height) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
def __init__(self, settings, globalSession): self.settings = settings # global session self.globalSession = globalSession self.scanner = self.globalSession.scanner self.rate = 0.0 self.currentIndex = 0 self.lastSavedIndex = 0 self.currentSuperCycle = 0 self.cycles = 0 self.pulses = 0 # array that holds the data for each scan # Each entry in this array is a dictionary with data in it self.dataTypes = ['time','volt','freq','ion','thick','thin','power','lw','iscool'] for i in xrange(self.settings.aiChannel.count(',')+1): self.dataTypes.append('ai'+str(i)) self.allData = [] self.spectrum = Spectrum() self.spectra = [] self.addScan()
def __init__(self, instrument, spec_reso=1e5): self.spec_reso = spec_reso self.spec_data = instrument.thermal_background.data self.wavelength = self.spec_data["Wavelength"] self.flux = self.spec_data["Flux"] self.spectrum = Spectrum(self.wavelength, self.flux, spec_reso=self.spec_reso) self.spec_header = instrument.thermal_background.header
def main(grammar, failed_tests, passed_tests) : """ """ prepare = Preparation(grammar,failed_tests, passed_tests) # get the represention of rules and tests rules = prepare.get_rules() failed = prepare.construct_matrix("failed") total_failed = failed.shape[1] passed = prepare.construct_matrix("passed") total_passed = passed.shape[1] # print(total_passed) failed_counts = prepare.basic_counts(failed) passed_counts = prepare.basic_counts(passed) # print(passed_counts) spectrum = Spectrum(failed_counts, passed_counts, total_failed, total_passed) scores = spectrum.compute_suspiciousness() spit_csv(rules, scores)
def loadTestImage(): image_name = "test/test_image.fits" try: spec = Spectrum(image_name) except SpectrumError as e: message = "{}\nLoad error".format(e) return message, None return "Load successful", spec
def addScan(self): # dictionary that will hold all data for the new scan data = OrderedDict() # Ordered dictionary, so that we save the data with consistency for t in self.dataTypes: data[t] = np.array([]) self.allData.append(data) self.spectra.append(Spectrum())
def loadImage(): image_name = input("Enter image name --> ") try: spec = Spectrum(image_name) except SpectrumError as e: message = "{}\nLoad error".format(e) return message, None return "Load successful", spec
def chrono_align_and_sum(spectrum, energy_range=(None, None), spatial_shape=None): """Alignment and sum of a chrono-spim SI Parameters ---------- spectrum : Spectrum instance Chrono-spim energy_range : tuple of floats energy interval in which to perform the alignment in energy units axis : int """ from spectrum import Spectrum dc = spectrum.data_cube min_energy_size = dc.shape[0] # i = 0 new_dc = None # For the progress bar to work properly we must capture the output of the # functions that are called during the alignment process import cStringIO import sys capture_output = cStringIO.StringIO() from hyperspy.misc.progressbar import progressbar pbar = progressbar(maxval=dc.shape[2] - 1) for i in xrange(dc.shape[2]): pbar.update(i) sys.stdout = capture_output s = Spectrum({'calibration': {'data_cube': dc[:, :, i]}}) s.get_calibration_from(spectrum) s.find_low_loss_origin() s.align(energy_range, progress_bar=False) min_energy_size = min(s.data_cube.shape[0], min_energy_size) if new_dc is None: new_dc = s.data_cube.sum(1) else: new_dc = np.concatenate([ new_dc[:min_energy_size], s.data_cube.sum(1)[:min_energy_size] ], 1) sys.stdout = sys.__stdout__ pbar.finish() spectrum.data_cube = new_dc spectrum.get_dimensions_from_cube() spectrum.find_low_loss_origin() spectrum.align(energy_range) spectrum.find_low_loss_origin() if spatial_shape is not None: spectrum.data_cube = spectrum.data_cube.reshape( [spectrum.data_cube.shape[0]] + list(spatial_shape)) spectrum.data_cube = spectrum.data_cube.swapaxes(1, 2) spectrum.get_dimensions_from_cube()
def run(self, label): self.writeInputFiles() self.unfold() self.storeResult(label) data = np.loadtxt(data_path + '{}_unfolded.txt'.format(label)) data = data.T self.solution = Spectrum(self.ds.edges, data[1][:-1], data[2][:-1], dfde=True)
def loadRawCalibrationSpectrum(): image_name = "test/test_image_cal.fits" try: spec = Spectrum(image_name) except SpectrumError as e: message = "{}\nLoad error".format(e) return message, None if spec is None: return message, None extracted_spectrum = np.genfromtxt("test/test_image_cal_extracted.dat", names=True) try: spec.setExtractedSpectrum(extracted_spectrum["spectrum"]) except SpectrumError as e: message = "{}\nLoad error".format(e) return message, None return "Load successful", spec
def get_spectrum_info(self, line): """ Extract spectrum data from line and add it to the last SrtData created. Also extract the data timestamp if it is the first spectrum data parsed. """ spectrum = Spectrum(line) self.srtdata_list[-1].add_spectrum(spectrum) if self.datetime is None: self.datetime = spectrum.datetime
def set_spectrum(self, spectrum: Spectrum) -> bool: """Validate and set the spectrum of the result set.""" # Spectrum exists if spectrum is not None: return False # Input spectrum if spectrum.is_in(self.central_freq()): self.spectrum = spectrum return True else: return False
def load_experimental_data(self): # time correction factor c_t = 1 / (10 * 60) # 1 / (min * s/min) # power correction factor c_p = 250 / 1E5 # 250 W(th) / 100 kW(th) # detector efficiency e = 1 c_e = 1 / e # combine into one constant c = c_t * c_p * c_e spectrum_data = np.loadtxt('nai_gamma_spectrum.tka', skiprows=1) * c self.exp_gamma_raw = Spectrum(self.channels, spectrum_data) bg_data = np.loadtxt('background.tka', skiprows=1) * c self.background = Spectrum(self.channels, bg_data) true_data = spectrum_data - bg_data * c self.exp_gamma = Spectrum(self.channels, true_data)
def binned_source_to_rest(spec: Spectrum, z: float = None) -> Spectrum: """ Takes in a binned source spectrum and shifts it to rest frame. WARNING: Assumes desired wavelengths will be integer values and called (int) on them as a result. If integer wavelengths are NOT desired, this method will need to be modified. :param spec: Binned source spectrum :type spec: Spectrum :param z: Original redshift. If not passed, it will call spec.getRS() and use that value. :type z: float :return: Rest frame spectrum :rtype: Spectrum """ spec = spec.cpy() z = z or spec.getRS() wls = spec.getWavelengths() n = len(wls) for wl in wls: spec[int(wl / (1 + z))] = spec[wl] del spec[wl] return spec
def measure_background(self, num_frames, num_dropped_frames, **kwargs): '''Measures and returns the background and writes an image file to disk. :params num_frames: number of captured frames :type num_frames: int :params num_dropped_frames: number of dropped frames before collecting background spectrum :type num_dropped_frames: int :params show: If true show last grabbed frame :type show: bool :params name: The spectrum name :type name: str :returns: background_avg (ndarry): the averaged background spectrum ''' show = kwargs.get('show', False) name = kwargs.get('name') assert isinstance(show, bool), 'show must be of type bool.' assert isinstance(name, str), 'name must be of type str.' background = Spectrum(kind='background', name=name) background.add_data(self._measure(num_frames, num_dropped_frames, kind='background', show=show)) background.num_frames = num_frames return background
def plot_cf252(): """Docstring.""" # load data flux = cf252_source() eb = energy_groups('scale252') # spectrum object for ease of plotting spec = Spectrum(eb, flux, 0) # setup plotting environment fig = plt.figure(0) ax = fig.add_subplot(111) ax.set_xlim(0, 20) #ax.set_yscale('log') ax.set_xlabel('Energy $MeV$') ax.set_ylabel('Spectrum') # plot ax.plot(*spec.plot('plot', 'diff')) # save fig.savefig('plot/cf252.png', dpi=300)
def compose_speclist( speclist: List[ Spectrum ], namestring: str = "" ) -> Spectrum: """ Forms a composite spectrum from the given input spectra :param speclist: List of Spectrum to compose :param namestring: Namestring to assign to the composite. Defaults to "" :type speclist: list :type namestring: str :return: Composite Spectrum :rtype: Spectrum """ from numpy import std, mean joined = { } composite = Spectrum( ns=namestring ) for spec in speclist: for wl in spec: if wl not in joined: joined[ wl ] = list() joined[ wl ].append( spec.get( wl ) ) wavelength_list = [ ] fluxlist = [ ] errlist = [ ] for wl, v in joined.items(): wavelength_list.append( wl ) if len( v ) > 1: fluxlist.append( mean( [ f[ 0 ] for f in v ] ) ) errlist.append( std( [ e[ 1 ] for e in v ] ) ) else: fluxlist.append( v[ 0 ][ 0 ] ) errlist.append( v[ 0 ][ 1 ] ) composite.setDict( wavelength_list, fluxlist, errlist ) return composite
def measure_spectrum(self, num_frames, num_dropped_frames, **kwargs): '''Measures a spectrum. :params num_frames: number of captured frames :type num_frames: int :params num_dropped_frames: number of frames to drop before collecting spectrum frames :type num_dropped_frames: int :params show: If true show last grabbed frame :type show: bool :params name: The spectrum name :type name: str :returns: spectrum_avg (ndarry): the averaged spectrum :raises: AssertionError ''' show = kwargs.get('show', False) name = kwargs.get('name', None) assert isinstance(show, bool), 'show must be of type bool.' assert isinstance(name, str), 'name must be of type str.' spectrum = Spectrum(kind='spectrum', name=name) spectrum.add_data(self._measure(num_frames, num_dropped_frames, kind='spectrum', show=show)) spectrum.num_frames = num_frames return spectrum
def __init__(self, bins, s=1, r=2, thermal_t=600.0): self.bins = bins self.scaling = s self.e2 = 1e6 self.thermal_t = thermal_t # Maxwellian distribution, Eq.(9-6) self.m = lambda x: x ** 0.5 * np.exp(-x / (k * self.thermal_t)) # U235 chi distribution, Eq.(2-112) self.chi = lambda x: np.exp(-1.036e-6 * x) * np.sinh((2.29e-6 * x) ** 0.5) # Middle energy range self.f = lambda x: 1 / x self.r = 0 E = np.logspace(-5, 1, 1000) R = np.array([self.balance(e) for e in E]) self.e1 = np.interp(r, R, E) self.r = r self.c1 = 1.0 self.c2 = self.m(self.e1) / self.f(self.e1) self.c3 = self.c2 * self.f(self.e2) / self.chi(self.e2) vals = self.make_discrete(self.bins, self.scaling) Spectrum.__init__(self, self.bins, vals, False, dfde=True)
def main(): dirname = sys.argv[1] data = [] parameter = [] for filename in iglob(dirname + '/*.wav'): print(filename) sig, rate = read(filename, sr=16000) sig = (sig - np.mean(sig)) / np.var(sig) sp, yphase = Spectrum(sig, 512, 256, 512, 2) data.append(sp) parameter.append([yphase, filename.replace(dirname, '')]) with open(sys.argv[2] + '_parameter.txt', 'wb') as fp: pickle.dump(parameter, fp) with open(sys.argv[2] + '.txt', 'wb') as fp: pickle.dump(data, fp)
def chrono_align_and_sum(spectrum, energy_range = (None, None), spatial_shape = None): """Alignment and sum of a chrono-spim SI Parameters ---------- spectrum : Spectrum instance Chrono-spim energy_range : tuple of floats energy interval in which to perform the alignment in energy units axis : int """ from spectrum import Spectrum dc = spectrum.data_cube min_energy_size = dc.shape[0] # i = 0 new_dc = None # For the progress bar to work properly we must capture the output of the # functions that are called during the alignment process import cStringIO import sys capture_output = cStringIO.StringIO() from hyperspy.misc.progressbar import progressbar pbar = progressbar(maxval = dc.shape[2] - 1) for i in xrange(dc.shape[2]): pbar.update(i) sys.stdout = capture_output s = Spectrum({'calibration': {'data_cube' : dc[:,:,i]}}) s.get_calibration_from(spectrum) s.find_low_loss_origin() s.align(energy_range, progress_bar = False) min_energy_size = min(s.data_cube.shape[0], min_energy_size) if new_dc is None: new_dc = s.data_cube.sum(1) else: new_dc = np.concatenate([new_dc[:min_energy_size], s.data_cube.sum(1)[:min_energy_size]], 1) sys.stdout = sys.__stdout__ pbar.finish() spectrum.data_cube = new_dc spectrum.get_dimensions_from_cube() spectrum.find_low_loss_origin() spectrum.align(energy_range) spectrum.find_low_loss_origin() if spatial_shape is not None: spectrum.data_cube = spectrum.data_cube.reshape( [spectrum.data_cube.shape[0]] + list(spatial_shape)) spectrum.data_cube = spectrum.data_cube.swapaxes(1,2) spectrum.get_dimensions_from_cube()
def load_theoretical_data(self): # scale56 bin structure self.scale56 = np.loadtxt('scale56.txt') * 1E3 # normalize to keV # calculate normalization tally_area = tally_area = np.pi * (1.27**2) tally_area = 1 # for now not considering the tally area c = 8.32 / (200 * 1.60218e-13 * tally_area) c *= 250 # normalize to 250 W(th) # load theoretical gamma data data = np.loadtxt('gdata_total.txt') data = data.T[1][1:] data *= c # create spectrum self.the_gamma = Spectrum(self.scale56, data)
def __init__(self, instrument, distance=10.0, spec_path=None, exozodi_level=1.0, spec_reso=1e5): self.distance = distance self.instrument = instrument self.exozodi_level = exozodi_level #Level of zodi relative to Solar System self.spec_path = spec_path self.spec_reso = spec_reso self.spec_data = self.sumZodiFlux().data self.wavelength = self.spec_data["Wavelength"] self.flux = self.spec_data["Flux"] self.spectrum = Spectrum(self.wavelength, self.flux, spec_reso=self.spec_reso)
def interpolateSpectrum(self, pointDict): """ Interpoalte on grid spectra in given parameters return spectrum object """ if self.gridParams is None: print("First load GRID") return None surAll = self.findSurronding(pointDict) if surAll is None: print("Spectrum (%.0f %.2f %.2f %.1f) out of grid" % (pointDict["teff"], pointDict["logg"], pointDict["me"], pointDict["vmic"])) return None point = [pointDict[k] for k in self.paramsList] data = [] wave = self.wave for single in surAll: for i, (s, f) in enumerate(zip(self.gridParams, self.allFiles)): #print(s ,single) if np.array_equal(single, s): spec = pd.read_csv( f, header=None, delim_whitespace=True, comment=self.comments, skiprows=self.skipRows, ) flux = spec[self.fluxColumn].values if not self.ifCommonWavelength: #TODO: this needs to be tested if wave is None: wave = spec[self.waveColumn].values else: flux = np.interp(wave, spec[self.waveColumn].values, spec[self.fluxColumn].values) data.append(flux) interpFlux = self.multilinearInterpolation(surAll, data, point) return Spectrum(wave=self.wave, flux=interpFlux)
def plot_spectrum(spec: Spectrum, freq_range: Tuple[u.Quantity], table: Optional[Table] = None, key: Optional[str] = None, color_key: Optional[str] = None, top: Optional[int] = None) -> Plot: """Plot spectrum. Args: spec: spectrum. freq_range: frequency range. table: optiona; table with values for markers. key: optiona; table column to extract markers. color_key: optional; column to use for marker colors. top: optional; only plot the top n values from table. """ # Figure plt.close() fig = plt.figure(figsize=(5, 6)) ax1 = fig.add_subplot(111) ax2 = ax1.twinx() # Plot spectrum ax1.plot(spec.spectral_axis, spec.intensity, 'b-') xlim = get_freq_lim(freq_range) ax1.set_xlim(*xlim) cent = spec.centroid(*freq_range) ax1.axvline(cent.value, ls='--', c='#6f6f6f') ax1.set_ylim(bottom=-0.001) ax1.set_ylabel(f'Intensity ({spec.intensity.unit:latex_inline})', color='b') ax1.set_xlabel(f'Frequency ({spec.spectral_axis.unit:latex_inline})') # Spans ax1.axvspan(xlim[0], freq_range[0].value, facecolor='#6f6f6f', alpha=0.5) ax1.axvspan(freq_range[1].value, xlim[1], facecolor='#6f6f6f', alpha=0.5) # Plot table key if table is not None and key: plot_markers(ax2, table, key, top=top, color_key=color_key) return fig, ax1, ax2
def spectrum_plot( path: str, filename: str, spec: Spectrum, color: str = "royalblue", debug: bool = False ) -> None: """ Simple spectrum plotter. Passes values to Gnuplot.py. Plots in PDF format. If debug = True, no values will be written to the disk and Gnuplot will be initialized with persist = True and the path/filename values should be passed as empty strings "" to avoid an error. :param spec: Spectrum to be plot :type spec: Spectrum :param path: /path/to/output/file :type path: str :param filename: output file name :type filename: str :param color: Color to make the spectrum line. Defaults to "royalblue." Must be a color acceptable to Gnuplot :type color: str :param debug: Use the debug process, print outputs on the screen :type debug: bool :rtype: None """ from common.messaging import ANGSTROM, FLUX_UNITS from fileio.utils import dirCheck if not debug: dirCheck( path ) g = Gnuplot.Gnuplot( persist=debug ) g.title( spec.getNS() ) g.xlabel( f"Wavelength ({ANGSTROM})" ) g.ylabel( f"Flux Density ({FLUX_UNITS})" ) g( 'set key top right' ) g( 'set grid' ) if not debug: if not filename.lower().endswith( ".pdf" ): filename += ".pdf" g( 'set terminal pdf color enhanced size 9,6' ) g( f'set output {__fix_outpath( path, "%s" % filename )}' ) g.plot( make_spectrum_plotitem( spec, color=color ) ) if not debug: g( 'set output' ) g.close()
def __init__(self, distance=10.0, spec_path=None, inclination_deg=90.0, rotation_vel=5e3, radial_vel=1e4, spec_reso=1e5): self.distance = distance self.spec_path = spec_path self.spec_reso = spec_reso if self.spec_path != None: self.spec_data = pyfits.open(self.spec_path)[1].data self.wavelength = self.spec_data["Wavelength"] self.flux = self.spec_data["Flux"] self.spectrum = Spectrum(self.wavelength, self.flux, spec_reso=self.spec_reso) self.spec_header = pyfits.open(self.spec_path)[1].header self.PHXREFF = self.spec_header["PHXREFF"] self.inclination_deg = inclination_deg self.rotation_vel = rotation_vel self.radial_vel = radial_vel
def _parse_ms_file(self, f_path): # print "Parse file:",f_path # read ms/ms file in f = open(f_path) data = f.read() f.close() # create Spectrum instance spectrum = Spectrum(f_path) # set f_name spectrum.f_name = f_path # set metlin id spectrum.metlin_id = f_path[f_path.find("pos") + 3:f_path.find(".")] # set precursor _precursor = re.findall("parentmass[: ]+([0-9\.]+)", data) if len(_precursor) > 0: precursor = float(_precursor[0]) else: raise Exception("ERROR: precursor not set for %s!" % f_path) spectrum.precursor = precursor spectrum.mass = precursor - 1.00794 # set peaks and intensity _peaks = [] seg = False for line in data.split('\n'): if line.find("collision") != -1: seg = True continue if not line: seg = False continue if seg: words = line.split() mass = float(words[0]) inten = float(words[1]) _peaks.append((mass, inten)) spectrum.peaks = _peaks return spectrum
def __init__(self, molno, isono, Temp, N, regen=[False,False], resolution=ss.resolution, oversample=ss.oversample, ll_name='HITRAN04', v_turb=ss.vturb): #First of all lets see if we have made the requested template before #Regen syntax: [regenerate chunks, regenerate tau] filename = create_filename(molno, isono, ll_name, 'template', vturb=v_turb, Temp=Temp, N=N, resolution=resolution) print regen if (os.path.isfile(filename) == False) or ((regen[0] == True) or (regen[1] == True)): #Stuff to (re)generate template #check if this spectrum has been chunked #chunkinfo filename: fname = create_filename(molno, isono, ll_name, "chunkinfo") if not os.path.isfile(fname) or regen[0] == True: thislinelist = SpecificLineList() thislinelist.readlines(molno, isono, ll_name, regen) data = Spectrum() data.get_tau_chunks(molno, isono, ll_name, Temp, regen) data.do_rt(N) data.regrid(resolution=resolution, oversample=oversample) self.data = data outfile = open(filename,'w') pickle.dump(data, outfile) outfile.close() print 'saved template pickle' else: infile = open(filename,'r') #Can only get to this block if the .pickle file exists. Restore it, its faster. self.data = pickle.load(infile) infile.close() print 'restored template pickle'
def _parse_ms_file(self, f_path): # print "Parse file:",f_path # read ms/ms file in f = open(f_path) data = f.read() f.close() # create Spectrum instance spectrum = Spectrum(f_path) # set f_name spectrum.f_name = f_path # set metlin id spectrum.metlin_id = f_path[f_path.find("pos")+3:f_path.find(".")] # set precursor _precursor = re.findall("parentmass[: ]+([0-9\.]+)",data) if len(_precursor) > 0: precursor = float(_precursor[0]) else: raise Exception("ERROR: precursor not set for %s!" % f_path) spectrum.precursor = precursor spectrum.mass = precursor - 1.00794 # set peaks and intensity _peaks = [] seg = False for line in data.split('\n'): if line.find("collision") != -1: seg = True continue if not line: seg = False continue if seg: words = line.split() mass = float(words[0]) inten = float(words[1]) _peaks.append((mass,inten)) spectrum.peaks = _peaks return spectrum
def _parse_massbank_file(self, f_path): print "Parse file:",f_path # read ms/ms file in f = open(f_path) data = f.read() f.close() # create Spectrum instance spectrum = Spectrum(f_path) # set f_name spectrum.f_name = f_path # set mass _mass = re.findall("CH\$EXACT_MASS[: ]+([0-9\.]+)", data) if len(_mass) > 0: mass = float(_mass[0]) else: raise Exception("ERROR: mass filed error in file %s " % f_path) spectrum.mass = mass # set precursor _precursor = re.findall("MS\$FOCUSED_ION: PRECURSOR_M/Z[: ]+([0-9\.]+)",data) if len(_precursor) > 0: precursor = float(_precursor[0]) else: _basepeak = re.findall("MS\$FOCUSED_ION: BASE_PEAK[: ]+([0-9\.]+)",data) if len(_basepeak)>0 : print ("WARNING: using base peak as precursor for %s!" % f_path) precursor = float(_basepeak[0]) else: raise Exception("ERROR: precursor not set for %s!" % f_path) spectrum.precursor = precursor # set ion mode _mode = re.findall("ION_MODE ([A-Z]+)", data) if len(_mode) > 0: mode = _mode[0] else: _mode = re.findall("MODE ([A-Z]+)", data) if len(_mode)>0: print ("WARNING: ion mode is set by MODE for %s!" % f_path) mode = _mode[0] else: raise Exception("ERROR: mode not set for %s!" % f_path) spectrum.mode = mode # set peaks _peaks = [] lines = data.split("\n"); ready = False for line in lines: if len(line) == 0: continue if line.find("PK$PEAK") != -1: ready = True continue if ready: if line.find("N/A") != -1: raise Exception("ERROR: no peaks in %s" % f_path) words = line.split() mass = float(words[0]) inten = float(words[1]) #mass = mass+numpy.random.normal(0,1e-8,1) # add noise #mass = float("%.3f" % mass) _peaks.append((mass,inten)) spectrum.peaks = _peaks # set inchi _inchi = re.findall("IUPAC: (.+)",data) if len(_inchi) > 0: if _inchi[0].find('unknown') != -1: print f_path, 'has no inchi!' inchi = _inchi[0] #raise Exception("Error: no inchi for %s!" % f_path) else: inchi = _inchi[0] else: raise Exception("Error: no inchi for %s!" % f_path) if "InChI=" not in inchi: # some inchi may not contains the head inchi = "InChI=" + inchi spectrum.inchi = inchi # below are optional field for Spectrum _cas = re.findall("CH\$LINK: CAS[: ]+([0-9\-]+)", data) if len(_cas) > 0: cas = _cas[0] spectrum.cas = cas _metlin = re.findall("CH\$LINK: METLIN[: ]+([0-9]+)", data) if len(_metlin) > 0: metlin = _metlin[0] spectrum.metlin_id = metlin else: spectrum.metlin_id = 'NULL' _sid = re.findall("PUBCHEM SID[: ]+(\w+)", data) if len(_sid) > 0: sid = _sid[0] spectrum.pubchem_sid = sid else: _sid = re.findall("PUBCHEM[: ]+([0-9]+)", data) if len(_sid) > 0: sid = _sid[0] spectrum.pubchem_sid = sid _cid = re.findall("PUBCHEM CID[: ]+(\w+)", data) if len(_cid) > 0: cid = _cid[0] spectrum.pubchem_cid = cid _kegg_id = re.findall("LINK: KEGG (\w+)", data) if len(_kegg_id) > 0: kegg_id = _kegg_id[0] spectrum.kegg_id = kegg_id _ce = re.findall("COLLISION_ENERGY (\w+)",data) if len(_ce) > 0: ce = _ce[0] ce = ce.replace("eV","") if ce.isdigit(): spectrum.ce = int(ce) return spectrum
def main(options): """ main(options) Description: This is the main part of the code that executes the actual pyhammer algorithms. This is arrived at either by startCmd or startGui, both of which get all the necessary options from the user and pass them to this function. The general process of this function should be to: 1) Define a Spectrum object to be used in reading files 2) Call the measureLines() method to find the good lines 3) Run guessSpecType() to get the initial guessed spectral type. 4) Use the best-guess from guessSpecType() and run findRadialVelocity() to find the radial velocity measurements, cross correlate the lines to get the inital spectral type and metallicity guess. Repeat for all spectra 5) Bring up eyecheck GUI. Input: options - A dict containing the options the user can specify. These may already have default values if they were provided on the command line. Output: autoSpTResults.tbl - list of the spectra with the results of the auto spectral typing, radial velocity and metallicity results. """ # If the user has decided to not skip to the eyecheck, let's # do some processing if (not options['eyecheck']): # Open the input file and define a Spectrum object infile = open(options['infile'], 'r') spec = Spectrum() # Open and setup the output files outfile = open(options['outfile'], 'w') rejectfile = open(options['rejectfile'], 'w') outfile.write('Filename\t\tFile Type\t\tSpectra S/N\t\tSpectral Type\n') rejectfile.write('Filename\t\tFile Type\t\tSpectra S/N\n') for line in infile: # Remove extra whitespace and other unwanted characters and split fname, ftype = ' '.join(line.strip().split()).split(' ') # Now read in the current file success = spec.readFile(options['spectraPath']+fname, ftype) # If the attempt at reading the file did not succeed, then we # should just continue if (not success): rejectfile.write(fname + '\t' + ftype + '\tN/A\n') continue # Now that we have the necessary data in the spec object, let's # begin processing. ########################## ### OUTLINE OF PROCESS ### ########################## # Interpolate the observed spectrum to be logarithmically spaced. # Use interpSpec in spectrum class # Call the Spectrum.measureLines() function on the Spectrum object to get # the initial line measurements # Call the guessSpecType function to get an inital guess of the spectral type # Call findRadialVelocity function # Call a Spectrum.shiftToRest() that shifts the spectrum to rest # wavelengths. # Repeat the Spectrum.measurelines() on using the new rest-calibrated # spectrum. # Repeat guessSpecType function to get a better guess of the spectral type # and metallicity # End of the automatic guessing. We should have: # 1) Spectrum object with observed wavelength, flux, noise # 2) rest wavelength # 3) Spectral type (guessed) # 4) radial velocity and uncertainty, # 5) metallicity estimate, # 6) and line indice measurements. # 7) (eventually reddening?) # Write results in autoSpTResults.tbl # (includes spectral type, metallicity and RV measurements) ###################### ### END OF OUTLINE ### ###################### # We're done so let's close all the files for now. infile.close() outfile.close() rejectfile.close() # At this point, we should call up the GUI to do the eyechecking. eyecheck.main()
def extract_spectra(self): u""" Extract spectra from source imagery and creates well-defined spectrum objects. """ for img_id in self.image_data: self.img_src = self.image_data[img_id] self.convert_vector_to_raster(self.img_src) curr_coordinates = dict() if self.coverage: for fid in self.img_coordinates: loc_id = self.thematic_info[fid][self.roi_id] if loc_id in self.coverage[img_id]: curr_coordinates[fid] = self.img_coordinates[fid] else: curr_coordinates = self.img_coordinates if self.roi_type == "point": # extracting spectra as simple lists spectra = gdal_utils.extract_point_spectra( self.img_src, curr_coordinates, bad_bands=self.bad_bands, calibration=(self.slope, self.intercept), context_type=self.context_type, context_range=self.context_range, verbose=self.verbosity, ) elif self.roi_type == "polygon": # curr_coordinates = self.img_coordinates spectra = gdal_utils.extract_polygon_spectra( self.img_src, self.img_coordinates, bad_bands=self.bad_bands, calibration=(self.slope, self.intercept), aggregate=self.aggregate, verbose=self.verbosity, ) elif self.roi_type == "line string": spectra = gdal_utils.extract_line_spectra( self.img_src, self.img_coordinates, bad_bands=self.bad_bands, calibration=(self.slope, self.intercept), verbose=self.verbosity, ) # converting dict of raw spectra to spectrum objects for fid in spectra: # retrieving basic thematic information for current fid roi_id = self.thematic_info[fid][self.roi_id] x = self.thematic_info[fid]["x"] y = self.thematic_info[fid]["y"] # retrieving additional attributes for current fid if self.thematic_info[fid].has_key("attributes"): additional_attributes = self.thematic_info[fid]["attributes"].keys() # workaround to allow for subsequent iteration over a # single (aggregated polygon or simple point) spectrum if self.roi_type == "point" or self.aggregate: spectra[fid] = [spectra[fid]] if self.roi_type == "line string": cnt = 0 # i = 0 for sp in spectra[fid]: # i += 1 # if not i % 20 == 0: # continue # else: # i = 0 # creating new spectrum object using region of interest # id and according coordinates spectrum = Spectrum(roi_id, (x, y)) # copyying additional attributes for aa in additional_attributes: spectrum.set_attribute(aa, self.thematic_info[fid]["attributes"][aa]) if self.roi_type == "line string": cnt += 1 spectrum.set_attribute("_count", cnt) # setting context range and type to default values spectrum.set_context_range(self.context_range) spectrum.set_context_type(self.context_type) spectrum.set_source(img_id + 1) # copying values to spectrum object for gb, val in zip(self.good_bands, sp): spectrum.set_value(gb, val) # adding values of bad bands to spectrum for bb in self.bad_bands: spectrum.set_invalid(bb) # adding current spectrum to list of all extracted spectra self.spectra.append(spectrum)
from census import MedIncomeTable file = open("censuskey","r") key = file.read() survey = "acs5" mint = 2012 ctable = MedIncomeTable(survey, mint, key) file = open("spectrumkey","r") lines = file.readlines() uname = lines[0].strip() pwd = lines[1].strip() spectrum = Spectrum(uname, pwd) data = {} data['Data.AddressLine1'] = "1495 15th ave"#address.Street1 data['Data.AddressLine2'] = ""#address.Street2 data['Data.City'] = "San Francisco"#address.City data['Data.PostalCode'] = 94122#address.Zip data['Data.StateProvince'] = "CA"#address.State result = spectrum.geocodeUSAddress(data) geo = result['output_port'][0] lon = geo['Longitude'] lat = geo['Latitude'] conf = geo['Confidence']
def _parse_metlin_file(self, f_path, kegg_mass, inchi): tree = ET.parse(f_path) root = tree.getroot() eles = root.findall("./ExperimentInformations/Comment") for ele in eles: if ele.get('Id')=='kegg': kegg_id = ele.get('Value') if ele.get('Id') == 'Metlin-ID': metlin_id = ele.get('Value') if ele.get("Id") == 'cas': cas = ele.get('Value') eles = root.findall("./ExperimentInformations") for ele in eles: # should have only one element mass_diff = float(ele.attrib['ModificationMass']) c_name = ele.attrib['CompoundName'] c_formula = ele.attrib['MolecularFormula'] spectra = []; spectra_ms1 = [] eles = root.findall("./Spectra/Spectrum") for ele in eles: if ele.get("MSLevel") == "1": spectra_ms1.append(ele) if ele.get("MSLevel") == "2": spectra.append(ele) if kegg_id not in kegg_mass: print "Ignore %s:kegg_mass doesn't have %s" % (f_path,kegg_id) return [] if kegg_id not in inchi: print "Ignore %s:kegg_inchi doesn't have %s" % (f_path,kegg_id) return [] mass = kegg_mass[kegg_id] inchi = inchi[kegg_id] spectra_list = [] for spec in spectra: ce = int(spec.attrib['CollisionEnergy']) spectrum = Spectrum() spectrum.f_name = f_path spectrum.mass = float(mass) spectrum.precursor = mass + mass_diff spectrum.mode = "POSITIVE" spectrum.inchi = inchi spectrum.cas = cas spectrum.pubchem_sid = "NULL" spectrum.pubchem_cid = "NULL" spectrum.kegg_id = kegg_id spectrum.metlin_id = metlin_id spectrum.ce = ce peaks = spec.findall("Peak") _peaks = [] for peak in peaks: _mass = float(peak.get("Mass")); _inten = float(peak.get("Intensity")) if _inten > 1: _peaks.append((_mass,_inten/100)) spectrum.peaks = _peaks spectra_list.append(spectrum) return spectra_list
def __init__(self, text, on_char = "O", off_char = " "): Spectrum.__init__(self, text) self.on_char = on_char self.off_char = off_char * len(self.on_char)
def _parse_massbank_file(self, f_path): print "Parse file:",f_path # read ms/ms file in f = open(f_path) data = f.read() f.close() # create Spectrum instance spectrum = Spectrum(f_path) # set f_name spectrum.f_name = f_path # set precursor _precursor = re.findall("MS\$FOCUSED_ION: PRECURSOR_M/Z[: ]+([0-9\.]+)",data) if len(_precursor) > 0: precursor = float(_precursor[0]) else: _basepeak = re.findall("MS\$FOCUSED_ION: BASE_PEAK[: ]+([0-9\.]+)",data) if len(_basepeak)>0 : print ("WARNING: using base peak as precursor for %s!" % f_path) precursor = float(_basepeak[0]) else: raise Exception("ERROR: precursor not set for %s!" % f_path) spectrum.precursor = precursor # set ion mode _mode = re.findall("ION_MODE ([A-Z]+)", data) if len(_mode) > 0: mode = _mode[0] else: _mode = re.findall("MODE ([A-Z]+)", data) if len(_mode)>0: print ("WARNING: ion mode is set by MODE for %s!" % f_path) mode = _mode[0] else: raise Exception("ERROR: mode not set for %s!" % f_path) spectrum.mode = mode if spectrum.mode == 'POSITIVE': spectrum.mass = spectrum.precursor - 1.00794 else: spectrum.mass = spectrum.precursor + 1.00794 _ppm = re.findall("SE\$SEARCH_PPM[: ]+([0-9\.]+)",data) if len(_ppm) > 0: ppm = int(_ppm[0]) else: raise Exception("ERROR: PPM not set for %s!" % f_path) spectrum.ppm = ppm # set peaks _peaks = [] lines = data.split("\n"); ready = False for line in lines: if len(line) == 0: continue if line.find("PK$PEAK") != -1: ready = True continue if ready: if line.find("N/A") != -1: raise Exception("ERROR: no peaks in %s" % f_path) words = line.split() mass = float(words[0]) inten = float(words[1]) #mass = mass+numpy.random.normal(0,1e-8,1) # add noise #mass = float("%.3f" % mass) _peaks.append((mass,inten)) spectrum.peaks = _peaks _ce = re.findall("COLLISION_ENERGY (\w+)",data) if len(_ce) > 0: ce = _ce[0] ce = ce.replace("eV","") if ce.isdigit(): spectrum.ce = int(ce) return spectrum
def main(options): """ The main method of PyHammer which executes the overarching procedure. Description: This is the main part of the code that executes the actual pyhammer algorithms. This is arrived at either by startCmd or StartGUI, both of which get all the necessary options from the user and pass them to this function. The general process of this function should be to: - Define a Spectrum object to be used in reading files. - Load each spectrum sequentially. - Guess the spectral type. - Use the best guess for the spectral type and find the radial velocity shift. Shift the spectrum to rest. - Guess the spectral type again. - Repeat for all spectra - Bring up eyecheck GUI. Input: options: A dict containing the options the user has specified. Output: This program outputs two files, an outfile and a rejectfile. The outfile contains all results of the spectral type guess as well as the user's eyecheck guess and the rejectfile contains the list of spectra which could not be classified for some reason. """ # Create a Spectrum object spec = Spectrum() # If the user has decided to not skip to the eyecheck, let's # do some processing if not options["eyecheck"]: # Open the input file try: infile = open(options["infile"], "r") except IOError as e: notifyUser(options["useGUI"], str(e)) return # Open and setup the output files outfile = open(options["outfile"], "w") rejectfile = open(options["rejectfile"], "w") outfile.write( "#Filename,Radial Velocity (km/s),Guessed Spectral Type,Guessed [Fe/H],User Spectral Type,User [Fe/H]\n" ) rejectfile.write("#Filename,File Type,Spectra S/N\n") # Define the string to contain all failure messages. These will be compiled # and printed once at the end, if anything is put into it. rejectMessage = "" for i, line in enumerate(infile): # Remove extra whitespace and other unwanted characters and split line = line.strip() if line.find(",") > 0: line = line.replace(",", " ") fname, ftype = " ".join(line.split()).rsplit(" ", 1) # Print statement of progress for user print(i + 1, ") Processing ", os.path.basename(fname), sep="") # Now read in the current file (this process reads in the file, converts air to # vac when necessary and interpolates onto the template grid) success, message = spec.readFile(options["spectraPath"] + fname, ftype) # If the attempt at reading the file did not succeed, then we # should just continue if not success: rejectfile.write(fname + "," + ftype + ",N/A\n") rejectMessage += "FILE: " + fname + " REASON: " + message.replace("\n", "") + "\n" continue # Now that we have the necessary data in the spec object, let's # begin processing. # --- 1 --- # Calculate the signal to noise of the spectrum to potentially reject if options["sncut"] is not None: snVal = spec.calcSN() if snVal < options["sncut"]: rejectfile.write(fname + "," + ftype + "," + str(snVal) + "\n") rejectMessage += ( "FILE: " + fname + " REASON: S/N = " + str(snVal) + " < " + str(options["sncut"]) + "\n" ) continue # --- 2 --- # Normalize the input spectrum to the same place where the templates are normalized (8000A) spec.normalizeFlux() # --- 3 --- # Call guessSpecType function for the initial guess # this function measures the lines then makes a guess of all parameters spec.guessSpecType() # --- 4 --- # Call findRadialVelocity function using the initial guess shift = spec.findRadialVelocity() # --- 5 --- # Call shiftToRest that shifts the spectrum to rest wavelengths, # then interp back onto the grid spec.shiftToRest(shift) spec.interpOntoGrid() # --- 6 --- # Repeat guessSpecType function to get a better guess of the spectral # type and metallicity spec.guessSpecType() # End of the automatic guessing. We should have: # 1. Spectrum object with observed wavelength, flux, var, # 2. rest wavelength, # 3. spectral type (guessed), # 4. radial velocity and uncertainty, # 5. metallicity estimate, # 6. and line indice measurements # --- 7 --- # Translate the numbered spectral types into letters letterSpt = ["O", "B", "A", "F", "G", "K", "M", "L"][spec.guess["specType"]] # Write the file outfile.write( fname + "," + str(shift) + "," + letterSpt + str(spec.guess["subType"]) + "," + "{:+2.1f}".format(spec.guess["metal"]) + ",nan,nan" + "\n" ) # We're done so let's close all the files. infile.close() outfile.close() rejectfile.close() # Check that we processed every spectrum in the infile. If not, print out # the reject method. if rejectMessage != "": # Prepend to the reject message rejectMessage = ( "The following is a list of rejected spectra\n" "along with the reason for its rejection.\n\n" + rejectMessage ) notifyUser(options["useGUI"], rejectMessage) # Check if all spectra were skipped by seeing if the number of # lines in the reject message is equal to the number of spectra # processed (plus three lines for the prepended message). If # they were all skipped, theres nothing to eyecheck so return. if rejectMessage.count("\n") == i + 4: notifyUser(options["useGUI"], "All spectra were bad. Exiting PyHammer.") # Clean up any temporary input files created if os.path.basename(options["infile"])[:11] == "temp_input_": os.remove(options["infile"]) return # At this point, we should call up the GUI to do the eyechecking. Eyecheck(spec, options) # Clean up any temporary input files created if os.path.basename(options["infile"])[:11] == "temp_input_": os.remove(options["infile"])
class SCNR(QMainWindow): _window_title = "SCNR" _heartbeat = 100 # ms delay at which the plot/gui is refreshed, and the gamepad moves the stage def __init__(self, parent=None): super(SCNR, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.positions = np.matrix([ [0.0,0.0], [0.0,10.0], [10.0,0.0]]) self.posModel = NumpyModel(self.positions) self.ui.posTable.setModel(self.posModel) self.vh = self.ui.posTable.verticalHeader() self.vh.setVisible(False) self.hh = self.ui.posTable.horizontalHeader() self.hh.setModel(self.posModel) self.hh.setVisible(True) self.settings = Settings() self.fig = Figure() self.axes = self.fig.add_subplot(111) self.axes.hold(False) #self.axes.autoscale(False) #self.axes.set_xlim([self.settings.min_wl, self.settings.max_wl]) self.Canvas = FigureCanvas(self.fig) self.Canvas.setParent(self.ui.plotwidget) self.Canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.Canvas.updateGeometry() l = QVBoxLayout(self.ui.plotwidget) l.addWidget(self.Canvas) self.ui.status.setText("Ready") #self.savedir = "."+path.sep+"Spectra"+path.sep #self.path = "."+path.sep self.savedir = "./Spectra/" self.path = "./" self.x_step = .0 self.y_step = .0 self.step_distance = 1 # in um try: #pass self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port) except: self.stage = None self.stage = PIStage.Dummy() print("Could not initialize PIStage, using Dummy instead") self.spectrum = Spectrum(self.stage, self.settings, self.ui.status, self.ui.progressBar, self.enable_buttons, self.disable_buttons) # logger class which coordinates the spectrometer and the stage self.spec = self.spectrum.get_spec() # get an initial spectrum for display self._wl = self.spectrum.get_wl() # get the wavelengths #self.update_plot(None) #self.spectrum.getspecthread.dynamicSpecSignal.connect(self.update_plot) self.spectrum.specSignal.connect(self.update_plot) self.spectrum.updatePositions.connect(self.update_positions) self.padthread = GamepadThread() self.padthread.BSignal.connect(self.on_search_clicked) self.padthread.XSignal.connect(self.on_addpos_clicked) self.padthread.YSignal.connect(self.on_stepup_clicked) self.padthread.ASignal.connect(self.on_stepdown_clicked) self.padthread.xaxisSignal.connect(self.on_xaxis) self.padthread.yaxisSignal.connect(self.on_yaxis) self.ax = 0.0 self.ay = 0.0 self.padthread.start() self.timer = QTimer(self) self.timer.timeout.connect(self.check_pad_analog) self.timer.start(100) self.pad_active = True self.settings_dialog = dialogs.Settings_Dialog(self.settings) self.settings_dialog.updateSignal.connect(self.update_settings) self.update_settings() self.ui.label_stepsize.setText(str(self.settings.stepsize)) def disable_buttons(self): self.ui.tabWidget.setDisabled(True) self.ui.stage_frame.setDisabled(True) self.ui.Button_searchmax.setDisabled(True) self.ui.Button_stepup.setDisabled(True) self.ui.Button_stepdown.setDisabled(True) self.ui.Button_stop.setDisabled(False) #self.pad_active = False def enable_buttons(self): self.ui.tabWidget.setDisabled(False) self.ui.stage_frame.setDisabled(False) self.ui.Button_searchmax.setDisabled(False) self.ui.Button_stepup.setDisabled(False) self.ui.Button_stepdown.setDisabled(False) self.ui.Button_stop.setDisabled(True) self.pad_active = True @pyqtSlot() def update_settings(self): self.spectrum._spectrometer.integration_time_micros(self.settings.integration_time*1000) @pyqtSlot(float) def on_xaxis(self, x): self.ax = x @pyqtSlot(float) def on_yaxis(self, y): self.ay = y @pyqtSlot() def check_pad_analog(self): if self.pad_active: x_step = self.ax if abs(x_step) > 0.0001: x_step = x_step * self.settings.stepsize else: x_step = 0.0 y_step = -1*self.ay if abs(y_step) > 0.0001: y_step = y_step * self.settings.stepsize else: y_step = 0.0 if abs(x_step) > 0.0001: if abs(y_step) > 0.0001: self.stage.moverel(dx=x_step, dy=y_step) else: self.stage.moverel(dx=x_step) elif abs(y_step) > 0.001: self.stage.moverel(dy=y_step) self.show_pos() # ## ----------- scan Listview connect functions @pyqtSlot() def on_addpos_clicked(self): self.stage.query_pos() x,y,z = self.stage.last_pos() positions = self.posModel.getMatrix() if positions.shape[1] == 2: positions = np.append(positions,np.matrix([x,y]), axis = 0) else: positions = np.matrix([x,y]) self.posModel.update(positions) @pyqtSlot() def on_spangrid_clicked(self): xl, yl, ok = dialogs.SpanGrid_Dialog.getXY() positions = self.posModel.getMatrix() if (positions.shape[0] >= 3) & ((xl is not 0) | (yl is not 0)): a = np.ravel(positions[0,:]) b = np.ravel(positions[1,:]) c = np.ravel(positions[2,:]) grid = np.zeros((xl*yl,2)) if abs(b[0]) > abs(c[0]): grid_vec_1 = [b[0] - a[0], b[1] - a[1]] grid_vec_2 = [c[0] - a[0], c[1] - a[1]] else: grid_vec_2 = [b[0] - a[0], b[1] - a[1]] grid_vec_1 = [c[0] - a[0], c[1] - a[1]] print(grid_vec_1) print(grid_vec_2) i = 0 for x in range(xl): for y in range(yl): vec_x = a[0] + grid_vec_1[0] * x + grid_vec_2[0] * y vec_y = a[1] + grid_vec_1[1] * x + grid_vec_2[1] * y grid[i,0] = vec_x grid[i,1] = vec_y i += 1 self.posModel.update(grid) @pyqtSlot() def on_scan_add(self): positions = self.posModel.getMatrix() if positions.shape[1] == 2: positions = np.append(positions,np.matrix([0.0,0.0]), axis = 0) else: positions = np.matrix([0.0,0.0]) self.posModel.update(positions) @pyqtSlot() def on_scan_remove(self): indices = self.ui.posTable.selectionModel().selectedIndexes() rows = np.array([],dtype=int) for index in indices: rows = np.append(rows,index.row()) positions = self.posModel.getMatrix() positions = np.delete(positions,rows,axis=0) self.posModel.update(positions) @pyqtSlot() def on_scan_clear(self): self.posModel.update(np.matrix([[]])) @pyqtSlot(np.ndarray) def update_positions(self, pos): self.posModel.update(pos) # ## ----------- END scan Listview connect functions # ##---------------- button connect functions ---------- @pyqtSlot() def on_start_scan_clicked(self): prefix, ok = QInputDialog.getText(self, 'Save Folder', 'Enter Folder to save spectra to:') if ok: try: # os.path.exists(prefix) os.mkdir(self.savedir+prefix) except: #print("Error creating directory ."+path.sep + prefix) print("Error creating directory ./" + prefix) #path = self.savedir + prefix + path.sep path = self.savedir + prefix + "/" self.ui.status.setText("Scanning ...") #self.spectrum.make_scan(self.scan_store, path, self.button_searchonoff.get_active(), self.button_lockinonoff.get_active()) self.spectrum.make_scan(self.posModel.getMatrix(), path, self.ui.checkBox_lockin.isChecked(), self.ui.checkBox_search.isChecked()) self.disable_buttons() @pyqtSlot() def on_stop_clicked(self): self.ui.status.setText('Stopped') self.spectrum.stop_process() self.enable_buttons() @pyqtSlot() def on_reset_clicked(self): self.spectrum.reset() @pyqtSlot() def on_acquirelockin_clicked(self): self.ui.status.setText('Acquiring ...') self.spectrum.take_lockin() self.disable_buttons() @pyqtSlot() def on_direction_clicked(self): self.direction_dialog.rundialog() @pyqtSlot() def on_live_clicked(self): self.ui.status.setText('Liveview') self.spectrum.take_live() self.disable_buttons() @pyqtSlot() def on_searchgrid_clicked(self): self.ui.status.setText("Searching Max.") self.spectrum.scan_search_max(self.posModel.getMatrix()) self.disable_buttons() @pyqtSlot() def on_search_clicked(self): self.ui.status.setText("Searching Max.") self.spectrum.search_max() self.disable_buttons() @pyqtSlot() def on_save_clicked(self): self.ui.status.setText("Saving Data ...") prefix, ok = QInputDialog.getText(self, 'Save Folder', 'Enter Folder to save spectra to:') if ok: try: # os.path.exists(prefix) os.mkdir(self.savedir+prefix) except: #print("Error creating directory ."+path.sep + prefix) print("Error creating directory ./" + prefix) #path = self.savedir + prefix + path.sep path = self.savedir + prefix + "/" self.spectrum.save_data(path) @pyqtSlot() def on_saveas_clicked(self): self.ui.status.setText("Saving Data ...") save_as = QFileDialog.getSaveFileName(self, "Save currently shown Spectrum as", './spectra/','CSV Files (*.csv)') print(save_as) #prefix, ok = QInputDialog.getText(self, 'Save Folder', 'Enter Folder to save spectra to:') if not self.spectrum.mean is None: try: self.spectrum.save_spectrum(self.spectrum.mean, save_as[0], None, False, True) except: print("Error Saving file " + save_as[0]) @pyqtSlot() def on_settings_clicked(self): self.settings_dialog.show() #self.spectrum.reset() @pyqtSlot() def on_dark_clicked(self): self.ui.status.setText('Taking Dark Spectrum') self.spectrum.take_dark() self.disable_buttons() @pyqtSlot() def on_lamp_clicked(self): self.ui.status.setText('Taking Lamp Spectrum') self.spectrum.take_lamp() self.disable_buttons() @pyqtSlot() def on_mean_clicked(self): self.ui.status.setText('Taking Normal Spectrum') self.spectrum.take_mean() self.disable_buttons() @pyqtSlot() def on_bg_clicked(self): self.ui.status.setText('Taking Background Spectrum') self.spectrum.take_bg() self.disable_buttons() @pyqtSlot() def on_series_clicked(self): self.ui.status.setText('Taking Time Series') prefix = self.prefix_dialog.rundialog() if prefix is not None: try: # os.path.exists(prefix) os.mkdir(self.savedir+prefix) except: #print("Error creating directory ."+path.sep + prefix) print("Error creating directory ./" + prefix) #path = self.savedir + prefix + path.sep path = self.savedir + prefix + "/" else: self.ui.status.setText("Error") self.spectrum.take_series(path) self.disable_buttons() @pyqtSlot() def on_loaddark_clicked(self): buf = self._load_spectrum_from_file() if not buf is None: self.spectrum.dark = buf @pyqtSlot() def on_loadlamp_clicked(self): buf = self._load_spectrum_from_file() if not buf is None: self.spectrum.lamp = buf @pyqtSlot() def on_loadbg_clicked(self): buf = self._load_spectrum_from_file() if not buf is None: self.spectrum.bg = buf @pyqtSlot() def on_lockin_clicked(self): pass @pyqtSlot() def on_aquirelockin_clicked(self): pass # ##---------------- END button connect functions ---------- def _load_spectrum_from_file(self): #save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", os.path.expanduser('~'), 'CSV Files (*.csv)') #save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", '.'+path.sep+'spectra'+path.sep, 'CSV Files (*.csv)') save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", './spectra/', 'CSV Files (*.csv)') if len(save_dir[0])>1: save_dir = save_dir[0] #data = pandas.DataFrame(pandas.read_csv(save_dir,skiprows=8)) #data = data['counts'] data = np.genfromtxt(save_dir, delimiter=',',skip_header=12) data = data[:,1] return np.array(data) return None # ##---------------- Stage Control Button Connect functions ---------- def show_pos(self): pos = self.stage.last_pos() # print(pos) self.ui.label_x.setText("x: {0:+8.4f}".format(pos[0])) self.ui.label_y.setText("y: {0:+8.4f}".format(pos[1])) self.ui.label_z.setText("z: {0:+8.4f}".format(pos[2])) @pyqtSlot() def on_xup_clicked(self): self.stage.moverel(dx=self.settings.stepsize) self.show_pos() @pyqtSlot() def on_xdown_clicked(self): self.stage.moverel(dx=-self.settings.stepsize) self.show_pos() @pyqtSlot() def on_yup_clicked(self): self.stage.moverel(dy=self.settings.stepsize) self.show_pos() @pyqtSlot() def on_ydown_clicked(self): self.stage.moverel(dy=-self.settings.stepsize) self.show_pos() @pyqtSlot() def on_zup_clicked(self): self.stage.moverel(dz=self.settings.stepsize) self.show_pos() @pyqtSlot() def on_zdown_clicked(self): self.stage.moverel(dz=-self.settings.stepsize) self.show_pos() @pyqtSlot() def on_stepup_clicked(self): self.settings.stepsize *= 10 if self.settings.stepsize > 10: self.settings.stepsize = 10.0 self.ui.label_stepsize.setText(str(self.settings.stepsize)) self.settings.save() @pyqtSlot() def on_stepdown_clicked(self): self.settings.stepsize /= 10 if self.settings.stepsize < 0.001: self.settings.stepsize = 0.001 self.ui.label_stepsize.setText(str(self.settings.stepsize)) self.settings.save() def on_moverel_clicked(self): self.moverel_dialog.rundialog() self.show_pos() def on_moveabs_clicked(self): self.moveabs_dialog.rundialog() self.show_pos() @pyqtSlot(np.ndarray) def update_plot(self): self.spec = self.spectrum.get_spec(self.ui.CheckBox_correct.isChecked()) mask = (self._wl >= self.settings.min_wl) & (self._wl <= self.settings.max_wl) self.axes.plot(self._wl[mask], self.spec[mask]) #self.axes.plot(self._wl, spec) self.Canvas.draw() self.show_pos() return True
def extract_spectra(self, description_field = '', verbose = True): u""" Extract spectra from source imagery and creates well-defined spectrum objects. """ # extracting spectra as simple lists spectra = gdal_utils.extract_spectra(self.img_src, self.extract_locations, neighborhood = self.neighborhood, verbose = verbose, bad_bands = self.bad_bands, scale_factor = self.slope, nb_type = self.neighborhood_type) # converting lists to spectrum objects # defining list of all extracted spectra # iterating over location/spectrum pairs for cp, sp in zip(self.extract_locations, spectra): # retrieving location id if cp.has_key('attributes'): additional_attributes = cp['attributes'].keys() additional_attributes.remove(self.loc_id_field) loc_id = cp[self.loc_id_field] # creating new spectrum object using location id and according coordinates spectrum = Spectrum(loc_id, (cp['x'], cp['y'])) for aa in additional_attributes: spectrum.set_attribute(aa, cp['attributes'][aa]) spectrum.set_neighborhood(self.neighborhood) spectrum.set_neighborhood_type(self.neighborhood_type) spectrum.set_source(self.img_id) if description_field: spectrum.set_description(cp[description_field]) # adding values to spectrum for gb, val in zip(self.good_bands, sp): spectrum.set_value(gb, val) # adding values of bad bands to spectrum for bb in self.bad_bands: spectrum.set_invalid(bb) # adding current spectrum to list of all extracted spectra self.spectra.append(spectrum)
def __init__(self, parent=None): super(SCNR, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.positions = np.matrix([ [0.0,0.0], [0.0,10.0], [10.0,0.0]]) self.posModel = NumpyModel(self.positions) self.ui.posTable.setModel(self.posModel) self.vh = self.ui.posTable.verticalHeader() self.vh.setVisible(False) self.hh = self.ui.posTable.horizontalHeader() self.hh.setModel(self.posModel) self.hh.setVisible(True) self.settings = Settings() self.fig = Figure() self.axes = self.fig.add_subplot(111) self.axes.hold(False) #self.axes.autoscale(False) #self.axes.set_xlim([self.settings.min_wl, self.settings.max_wl]) self.Canvas = FigureCanvas(self.fig) self.Canvas.setParent(self.ui.plotwidget) self.Canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.Canvas.updateGeometry() l = QVBoxLayout(self.ui.plotwidget) l.addWidget(self.Canvas) self.ui.status.setText("Ready") #self.savedir = "."+path.sep+"Spectra"+path.sep #self.path = "."+path.sep self.savedir = "./Spectra/" self.path = "./" self.x_step = .0 self.y_step = .0 self.step_distance = 1 # in um try: #pass self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port) except: self.stage = None self.stage = PIStage.Dummy() print("Could not initialize PIStage, using Dummy instead") self.spectrum = Spectrum(self.stage, self.settings, self.ui.status, self.ui.progressBar, self.enable_buttons, self.disable_buttons) # logger class which coordinates the spectrometer and the stage self.spec = self.spectrum.get_spec() # get an initial spectrum for display self._wl = self.spectrum.get_wl() # get the wavelengths #self.update_plot(None) #self.spectrum.getspecthread.dynamicSpecSignal.connect(self.update_plot) self.spectrum.specSignal.connect(self.update_plot) self.spectrum.updatePositions.connect(self.update_positions) self.padthread = GamepadThread() self.padthread.BSignal.connect(self.on_search_clicked) self.padthread.XSignal.connect(self.on_addpos_clicked) self.padthread.YSignal.connect(self.on_stepup_clicked) self.padthread.ASignal.connect(self.on_stepdown_clicked) self.padthread.xaxisSignal.connect(self.on_xaxis) self.padthread.yaxisSignal.connect(self.on_yaxis) self.ax = 0.0 self.ay = 0.0 self.padthread.start() self.timer = QTimer(self) self.timer.timeout.connect(self.check_pad_analog) self.timer.start(100) self.pad_active = True self.settings_dialog = dialogs.Settings_Dialog(self.settings) self.settings_dialog.updateSignal.connect(self.update_settings) self.update_settings() self.ui.label_stepsize.setText(str(self.settings.stepsize))
class LockinGui(object): _window_title = "Lock-in Spectrum" _heartbeat = 100 # ms delay at which the plot/gui is refreshed, and the gamepad moves the stage def __init__(self): self.savedir = "./Spectra/" self.path = "./" self.settings = Settings() self.x_step = .0 self.y_step = .0 self.step_distance = 1 # in um try: self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port) except: self.stage = None self.stage = PIStage.Dummy() print("Could not initialize PIStage, using Dummy instead") GObject.threads_init() # only GObject.idle_add() is in the background thread self.window = Gtk.Window(title=self._window_title) # self.window.set_resizable(False) self.window.set_border_width(3) self.grid = Gtk.Grid() self.grid.set_row_spacing(5) self.grid.set_column_spacing(5) self.window.add(self.grid) # Buttons for spectrum stack self.button_live = Gtk.Button(label="Liveview") self.button_live.set_tooltip_text("Start/Stop Liveview of Spectrum") self.button_stop = Gtk.Button(label="Stop") self.button_stop.set_tooltip_text("Stop any ongoing Action") self.button_stop.set_sensitive(False) self.button_aquire = Gtk.Button(label="Aquire Spectrum") self.button_aquire.set_tooltip_text("Start/Stop aquiring Lock-In Spectrum") self.button_direction = Gtk.Button(label="Set Direction") self.button_direction.set_tooltip_text("Set Direction of Stage Movement") self.button_settings = Gtk.Button(label="Settings") self.button_settings.set_tooltip_text("Set Integration Time and Number of Samples") self.button_search = Gtk.Button(label="Search for Max") self.button_search.set_tooltip_text("Search for position with maximum Intensity") self.button_save = Gtk.Button(label="Save Data") self.button_save.set_tooltip_text("Save all spectral Data in .csv") self.button_dark = Gtk.Button(label="Take Dark Spectrum") self.button_dark.set_tooltip_text("Take dark spectrum which will substracted from spectrum") self.button_lamp = Gtk.Button(label="Take Lamp Spectrum") self.button_lamp.set_tooltip_text("Take lamp spectrum to normalize spectrum") self.button_normal = Gtk.Button(label="Take Normal Spectrum") self.button_normal.set_tooltip_text("Start/Stop taking a normal spectrum") self.button_bg = Gtk.Button(label="Take Background Spectrum") self.button_bg.set_tooltip_text("Start/Stop taking a Background spectrum") self.button_series = Gtk.Button(label="Take Time Series") self.button_series.set_tooltip_text("Start/Stop taking a Time Series of Spectra") self.button_reset = Gtk.Button(label="Reset") self.button_reset.set_tooltip_text("Reset all spectral data (if not saved data is lost!)") self.button_loaddark = Gtk.Button(label="Load Dark Spectrum") self.button_loaddark.set_tooltip_text("Load Dark Spectrum from file") self.button_loadlamp = Gtk.Button(label="Load Lamp Spectrum") self.button_loadlamp.set_tooltip_text("Load Lamp Spectrum from file") # Stage Control Buttons self.button_xup = Gtk.Button(label="x+") self.button_xdown = Gtk.Button(label="x-") self.button_yup = Gtk.Button(label="y+") self.button_ydown = Gtk.Button(label="y-") self.button_zup = Gtk.Button(label="z+") self.button_zdown = Gtk.Button(label="z-") self.button_stepup = Gtk.Button(label="+") self.button_stepdown = Gtk.Button(label="-") self.label_stepsize = Gtk.Label(label=str(self.settings.stepsize)) self.button_moverel = Gtk.Button(label="Move Stage rel.") self.button_moveabs = Gtk.Button(label="Move Stage abs.") # Stage position labels self.label_x = Gtk.Label() self.label_y = Gtk.Label() self.label_z = Gtk.Label() self.show_pos() # Connect Buttons self.window.connect("delete-event", self.quit) self.button_aquire.connect("clicked", self.on_lockin_clicked) self.button_direction.connect("clicked", self.on_direction_clicked) self.button_live.connect("clicked", self.on_live_clicked) self.button_stop.connect("clicked", self.on_stop_clicked) self.button_settings.connect("clicked", self.on_settings_clicked) self.button_search.connect("clicked", self.on_search_clicked) self.button_save.connect("clicked", self.on_save_clicked) self.button_dark.connect("clicked", self.on_dark_clicked) self.button_lamp.connect("clicked", self.on_lamp_clicked) self.button_normal.connect("clicked", self.on_normal_clicked) self.button_bg.connect("clicked", self.on_bg_clicked) self.button_series.connect("clicked", self.on_series_clicked) self.button_reset.connect("clicked", self.on_reset_clicked) self.button_loaddark.connect("clicked", self.on_loaddark_clicked) self.button_loadlamp.connect("clicked", self.on_loadlamp_clicked) # Connect Stage Control Buttons self.button_xup.connect("clicked", self.on_xup_clicked) self.button_xdown.connect("clicked", self.on_xdown_clicked) self.button_yup.connect("clicked", self.on_yup_clicked) self.button_ydown.connect("clicked", self.on_ydown_clicked) self.button_zup.connect("clicked", self.on_zup_clicked) self.button_zdown.connect("clicked", self.on_zdown_clicked) self.button_stepup.connect("clicked", self.on_stepup_clicked) self.button_stepdown.connect("clicked", self.on_stepdown_clicked) self.button_moverel.connect("clicked", self.on_moverel_clicked) self.button_moveabs.connect("clicked", self.on_moveabs_clicked) # Stage Control Button Table self.table_stagecontrol = Gtk.Table(3, 4, True) self.table_stagecontrol.attach(self.button_xup, 0, 1, 1, 2) self.table_stagecontrol.attach(self.button_xdown, 2, 3, 1, 2) self.table_stagecontrol.attach(self.button_yup, 1, 2, 0, 1) self.table_stagecontrol.attach(self.button_ydown, 1, 2, 2, 3) self.table_stagecontrol.attach(self.button_zup, 3, 4, 0, 1) self.table_stagecontrol.attach(self.button_zdown, 3, 4, 2, 3) # Stage Stepsize Table self.table_stepsize = Gtk.Table(1, 3, True) self.table_stepsize.attach(self.button_stepup, 0, 1, 0, 1) self.table_stepsize.attach(self.label_stepsize, 1, 2, 0, 1) self.table_stepsize.attach(self.button_stepdown, 2, 3, 0, 1) self.status = Gtk.Label(label="Initialized") self.progress = Gtk.ProgressBar() self._progress_fraction = 0 self.progress.set_fraction(self._progress_fraction) # Box for control of taking single spectra self.SpectrumBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(self.button_live) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(Gtk.Label("Lock-In Spectrum")) self.SpectrumBox.add(self.button_aquire) self.SpectrumBox.add(self.button_direction) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(Gtk.Label(label="Additional Spectra")) self.SpectrumBox.add(self.button_dark) self.SpectrumBox.add(self.button_lamp) self.SpectrumBox.add(self.button_normal) self.SpectrumBox.add(self.button_bg) self.SpectrumBox.add(self.button_series) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(Gtk.Label(label="Miscellaneous")) self.SpectrumBox.add(self.button_save) self.SpectrumBox.add(self.button_settings) self.SpectrumBox.add(self.button_reset) self.SpectrumBox.add(self.button_loaddark) self.SpectrumBox.add(self.button_loadlamp) self.SpectrumBox.add(Gtk.Separator()) # Switch corrected Spectrum yes/no self.button_corronoff = Gtk.Switch() self.label_corronoff = Gtk.Label('Correct Spectrum') self.corronoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.corronoff_box.set_homogeneous(True) self.corronoff_box.add(self.label_corronoff) self.corronoff_box.add(self.button_corronoff) # box for Stage control self.stage_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) # self.stage_hbox.add(Gtk.Separator()) self.stage_hbox.add(self.corronoff_box) self.stage_hbox.add(self.button_search) self.stage_hbox.add(Gtk.Label(label="Stage Control")) self.stage_hbox.add(self.table_stagecontrol) self.stage_hbox.add(Gtk.Label(label="Set Stepsize [um]")) self.stage_hbox.add(self.table_stepsize) self.stage_hbox.add(self.button_moverel) self.stage_hbox.add(self.button_moveabs) self.labels_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.labels_hbox.add(self.label_x) self.labels_hbox.add(self.label_y) self.labels_hbox.add(self.label_z) # Buttons for scanning stack self.button_add_position = Gtk.Button('Add Position to List') self.button_spangrid = Gtk.Button('Span Grid') self.button_searchonoff = Gtk.Switch() self.label_searchonoff = Gtk.Label('Search Max.') self.searchonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.searchonoff_box.set_homogeneous(True) self.searchonoff_box.add(self.label_searchonoff) self.searchonoff_box.add(self.button_searchonoff) self.button_lockinonoff = Gtk.Switch() self.label_lockinonoff = Gtk.Label('Use Lock-In') self.lockinonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.lockinonoff_box.set_homogeneous(True) self.lockinonoff_box.add(self.label_lockinonoff) self.lockinonoff_box.add(self.button_lockinonoff) self.button_scan_start = Gtk.Button('Start Scan') self.scan_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.button_scan_add = Gtk.ToolButton(Gtk.STOCK_ADD) self.button_scan_remove = Gtk.ToolButton(Gtk.STOCK_REMOVE) self.button_scan_clear = Gtk.ToolButton(Gtk.STOCK_DELETE) self.scan_hbox.set_homogeneous(True) self.scan_hbox.add(self.button_scan_add) self.scan_hbox.add(self.button_scan_remove) self.scan_hbox.add(self.button_scan_clear) # Treeview for showing/settings scanning grid self.scan_store = Gtk.ListStore(float, float) self.scan_view = Gtk.TreeView(model=self.scan_store) self.scan_xrenderer = Gtk.CellRendererText() self.scan_xrenderer.set_property("editable", True) self.scan_xcolumn = Gtk.TreeViewColumn("x", self.scan_xrenderer, text=0) self.scan_xcolumn.set_min_width(100) self.scan_xcolumn.set_alignment(0.5) self.scan_view.append_column(self.scan_xcolumn) self.scan_yrenderer = Gtk.CellRendererText() self.scan_yrenderer.set_property("editable", True) self.scan_ycolumn = Gtk.TreeViewColumn("y", self.scan_yrenderer, text=1) self.scan_ycolumn.set_min_width(100) self.scan_ycolumn.set_alignment(0.5) self.scan_view.append_column(self.scan_ycolumn) self.scan_scroller = Gtk.ScrolledWindow() self.scan_scroller.set_vexpand(True) self.scan_scroller.add(self.scan_view) self.scan_store.append([10.0, 10.0]) self.scan_store.append([10.1, 10.0]) self.scan_store.append([10.0, 10.1]) #Connections for scanning stack self.button_add_position.connect("clicked", self.on_add_position_clicked) self.button_spangrid.connect("clicked", self.on_spangrid_clicked) self.button_scan_start.connect("clicked", self.on_scan_start_clicked) self.button_scan_add.connect("clicked", self.on_scan_add) self.button_scan_remove.connect("clicked", self.on_scan_remove) self.button_scan_clear.connect("clicked", self.on_scan_clear) self.scan_xrenderer.connect("edited", self.on_scan_xedited) self.scan_yrenderer.connect("edited", self.on_scan_yedited) #Box for control of scanning self.ScanningBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.ScanningBox.add(Gtk.Separator()) self.ScanningBox.add(self.button_add_position) self.ScanningBox.add(self.button_spangrid) self.ScanningBox.add(self.searchonoff_box) self.ScanningBox.add(self.lockinonoff_box) self.ScanningBox.add(Gtk.Separator()) self.ScanningBox.add(Gtk.Label("Scanning Positions")) self.ScanningBox.add(self.scan_hbox) self.ScanningBox.add(self.scan_scroller) self.ScanningBox.add(Gtk.Separator()) self.ScanningBox.add(self.button_scan_start) # MPL stuff self.figure = Figure() self.ax = self.figure.add_subplot(1, 1, 1) self.ax.grid(True) self.ax.set_xlabel("Wavelength [nm]") self.ax.set_ylabel("Intensity") self.ax.set_xlim([400, 900]) self.canvas = FigureCanvas(self.figure) self.canvas.set_hexpand(True) self.canvas.set_vexpand(True) self.canvas.set_size_request(700, 700) self.stack = Gtk.Stack() self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT) self.stack.set_transition_duration(500) self.stack.add_titled(self.SpectrumBox, "spec", "Spectra") self.stack.add_titled(self.ScanningBox, "scan", "Scanning") self.stack_switcher = Gtk.StackSwitcher() self.stack_switcher.set_stack(self.stack) self.SideBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.SideBox.add(self.stack_switcher) self.ScanningBox.add(Gtk.Separator()) self.SideBox.add(self.button_stop) self.SideBox.add(self.stack) self.SideBox.add(self.stage_hbox) self.SideBox.add(self.labels_hbox) self.grid.add(self.canvas) self.grid.attach_next_to(self.SideBox, self.canvas, Gtk.PositionType.RIGHT, 1, 1) self.grid.attach_next_to(self.progress, self.canvas, Gtk.PositionType.BOTTOM, 1, 1) self.grid.attach_next_to(self.status, self.SideBox, Gtk.PositionType.BOTTOM, 1, 1) self.window.show_all() self.spectrum = Spectrum(self.stage, self.settings, self.status, self.progress, self.enable_buttons, self.disable_buttons) # logger class which coordinates the spectrometer and the stage spec = self.spectrum.get_spec() # get an initial spectrum for display self._wl = self.spectrum.get_wl() # get the wavelengths print(self._wl) self.lines = [] self.lines.extend(self.ax.plot(self._wl, spec, "-")) self.lines.extend(self.ax.plot(self._wl, self.spectrum.smooth(spec), "-", c="black")) # plot initial spectrum #Dialogs self.settings_dialog = dialogs.SettingsDialog(self.window, self.settings) self.direction_dialog = dialogs.DirectionDialog(self.window, self.settings) self.moveabs_dialog = dialogs.MoveAbsDialog(self.window, self.stage) self.moverel_dialog = dialogs.MoveRelDialog(self.window, self.stage) self.spangrid_dialog = dialogs.SpanGridDialog(self.window) self.prefix_dialog = dialogs.PrefixDialog(self.window) self.pad = None try: #pass self.pad = Gamepad(True) except: print("Could not initialize Gamepad") def quit(self, *args): """ Function for quitting the program, will also stop the worker thread :param args: """ self.spectrum = None self.pad = None Gtk.main_quit(*args) def disable_buttons(self): # self.stack_switcher.set_sensitive(False) self.scan_hbox.set_sensitive(False) self.SpectrumBox.set_sensitive(False) self.stage_hbox.set_sensitive(False) self.ScanningBox.set_sensitive(False) self.button_stop.set_sensitive(True) def enable_buttons(self): # self.stack_switcher.set_sensitive(True) self.scan_hbox.set_sensitive(True) self.SpectrumBox.set_sensitive(True) self.stage_hbox.set_sensitive(True) self.ScanningBox.set_sensitive(True) self.button_stop.set_sensitive(False) def _on_pad_change(self, io, condition): a, b, x, y, ax, ay = self.pad.receiver.recv() if a: self.on_stepdown_clicked(None) if b: self.on_add_position_clicked(None) if x: self.on_search_clicked(None) if y: self.on_stepup_clicked(None) self.x_step = float((ax - 128)) if abs(self.x_step) > 8: self.x_step = self.x_step / 128 * self.settings.stepsize else: self.x_step = 0.0 self.y_step = float((ay - 128)) if abs(self.y_step) > 8: self.y_step = self.y_step / 128 * self.settings.stepsize else: self.y_step = 0.0 # print('x_step: {0:3.2f} um y_step: {1:3.2f} um'.format( self.x_step, self.y_step)) return True def _pad_make_step(self): if self.pad is not None: if abs(self.x_step) > 0.0001: if abs(self.y_step) > 0.0001: self.stage.moverel(dx=self.x_step, dy=self.y_step) else: self.stage.moverel(dx=self.x_step) elif abs(self.y_step) > 0.001: self.stage.moverel(dy=self.y_step) return True # ##---------------- button connect functions ---------- def on_scan_start_clicked(self, widget): prefix = self.prefix_dialog.rundialog() if prefix is not None: try: # os.path.exists(prefix) os.mkdir(self.savedir+prefix) except: print("Error creating directory ./" + prefix) path = self.savedir + prefix + '/' self.status.set_label('Scanning') self.spectrum.make_scan(self.scan_store, path, self.button_searchonoff.get_active(), self.button_lockinonoff.get_active()) self.disable_buttons() def on_add_position_clicked(self, widget): self.stage.query_pos() pos = self.stage.last_pos() self.scan_store.append([pos[0], pos[1]]) def on_spangrid_clicked(self, widget): iterator = self.scan_store.get_iter_first() grid = self.spangrid_dialog.rundialog() if (len(self.scan_store) >= 3) & ((grid[0] is not 0) | (grid[1] is not 0)): a = self.scan_store[iterator][:] iterator = self.scan_store.iter_next(iterator) b = self.scan_store[iterator][:] iterator = self.scan_store.iter_next(iterator) c = self.scan_store[iterator][:] if abs(b[0]) > abs(c[0]): grid_vec_1 = [b[0] - a[0], b[1] - a[1]] grid_vec_2 = [c[0] - a[0], c[1] - a[1]] else: grid_vec_2 = [b[0] - a[0], b[1] - a[1]] grid_vec_1 = [c[0] - a[0], c[1] - a[1]] self.scan_store.clear() for x in range(int(grid[0])): for y in range(int(grid[1])): vec_x = a[0] + grid_vec_1[0] * x + grid_vec_2[0] * y vec_y = a[1] + grid_vec_1[1] * x + grid_vec_2[1] * y self.scan_store.append([vec_x, vec_y]) def on_stop_clicked(self, widget): self.spectrum.stop_process() self.enable_buttons() self.status.set_label('Stopped') def on_reset_clicked(self, widget): self.spectrum.reset() self.spectrum.dark = None self.spectrum.lamp = None self.spectrum.lockin = None self.spectrum.mean = None def on_lockin_clicked(self, widget): self.status.set_label('Acquiring ...') self.spectrum.take_lockin() self.disable_buttons() def on_direction_clicked(self, widget): self.direction_dialog.rundialog() def on_live_clicked(self, widget): self.status.set_label('Liveview') self.spectrum.take_live() self.disable_buttons() def on_search_clicked(self, widget): self.status.set_text("Searching Max.") self.spectrum.search_max() self.disable_buttons() def on_save_clicked(self, widget): self.status.set_label("Saving Data ...") self.save_data() def on_settings_clicked(self, widget): self.settings_dialog.rundialog() self.ax.set_xlim([self.settings.min_wl, self.settings.max_wl]) #self.spectrum.reset() def on_dark_clicked(self, widget): self.status.set_label('Taking Dark Spectrum') self.spectrum.take_dark() self.disable_buttons() def on_lamp_clicked(self, widget): self.status.set_label('Taking Lamp Spectrum') self.spectrum.take_lamp() self.disable_buttons() def on_normal_clicked(self, widget): self.status.set_label('Taking Normal Spectrum') self.spectrum.take_normal() self.disable_buttons() def on_bg_clicked(self, widget): self.status.set_label('Taking Background Spectrum') self.spectrum.take_bg() self.disable_buttons() def on_series_clicked(self, widget): self.status.set_label('Taking Time Series') prefix = self.prefix_dialog.rundialog() if prefix is not None: try: # os.path.exists(prefix) os.mkdir(self.savedir+prefix) except: print("Error creating directory ./" + prefix) path = self.savedir + prefix + '/' else: self.status.set_text("Error") self.spectrum.take_series(path) self.disable_buttons() def on_loaddark_clicked(self, widget): buf = self._load_spectrum_from_file() if not buf is None: self.spectrum.dark = buf def on_loadlamp_clicked(self, widget): buf = self._load_spectrum_from_file() if not buf is None: self.spectrum.lamp = buf # ##---------------- END button connect functions ---------- def _load_spectrum_from_file(self): dialog = Gtk.FileChooserDialog("Please choose a file", self.window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) data = None filter_text = Gtk.FileFilter() filter_text.set_name("CSV Spectrum files") filter_text.add_pattern("*.csv") dialog.add_filter(filter_text) dialog.set_current_folder(os.path.dirname(os.path.abspath(__file__))) response = dialog.run() if response == Gtk.ResponseType.OK: data = pandas.DataFrame(pandas.read_csv(dialog.get_filename())) data = data['intensity'] elif response == Gtk.ResponseType.CANCEL: data = None dialog.destroy() return data # ## ----------- scan Listview connect functions def on_scan_xedited(self, widget, path, number): self.scan_store[path][0] = float(number.replace(',', '.')) # self.plotpoints() def on_scan_yedited(self, widget, path, number): self.scan_store[path][1] = float(number.replace(',', '.')) # self.plotpoints() def on_scan_add(self, widget): self.scan_store.append() def on_scan_remove(self, widget): select = self.scan_view.get_selection() model, treeiter = select.get_selected() if treeiter is not None: self.scan_store.remove(treeiter) def on_scan_clear(self, widget): self.scan_store.clear() # ## ----------- END scan Listview connect functions # ##---------------- Stage Control Button Connect functions ---------- def show_pos(self): pos = self.stage.last_pos() # print(pos) self.label_x.set_text("x: {0:+8.4f}".format(pos[0])) self.label_y.set_text("y: {0:+8.4f}".format(pos[1])) self.label_z.set_text("z: {0:+8.4f}".format(pos[2])) def on_xup_clicked(self, widget): self.stage.moverel(dx=self.settings.stepsize) self.show_pos() def on_xdown_clicked(self, widget): self.stage.moverel(dx=-self.settings.stepsize) self.show_pos() def on_yup_clicked(self, widget): self.stage.moverel(dy=self.settings.stepsize) self.show_pos() def on_ydown_clicked(self, widget): self.stage.moverel(dy=-self.settings.stepsize) self.show_pos() def on_zup_clicked(self, widget): self.stage.moverel(dz=self.settings.stepsize) self.show_pos() def on_zdown_clicked(self, widget): self.stage.moverel(dz=-self.settings.stepsize) self.show_pos() def on_stepup_clicked(self, widget): self.settings.stepsize *= 10 if self.settings.stepsize > 10: self.settings.stepsize = 10.0 self.label_stepsize.set_text(str(self.settings.stepsize)) self.settings.save() def on_stepdown_clicked(self, widget): self.settings.stepsize /= 10 if self.settings.stepsize < 0.001: self.settings.stepsize = 0.001 self.label_stepsize.set_text(str(self.settings.stepsize)) self.settings.save() def on_moverel_clicked(self, widget): self.moverel_dialog.rundialog() self.show_pos() def on_moveabs_clicked(self, widget): self.moveabs_dialog.rundialog() self.show_pos() # ##---------------- END Stage Control Button Connect functions ------ def run(self): """ run main gtk thread """ try: GLib.timeout_add(self._heartbeat, self._update_plot) GLib.timeout_add(self._heartbeat, self._pad_make_step) GLib.io_add_watch(self.spectrum.conn_for_main, GLib.IO_IN | GLib.IO_PRI, self.spectrum.callback, args=(self.spectrum,)) if self.pad is not None: GLib.io_add_watch(self.pad.receiver, GLib.IO_IN | GLib.IO_PRI, self._on_pad_change, args=(self,)) Gtk.main() except KeyboardInterrupt: pass def _update_plot(self): spec = self.spectrum.get_spec(self.button_corronoff.get_active()) self.lines[0].set_ydata(spec) self.lines[1].set_ydata(self.spectrum.smooth(spec)) #self.ax.set_ylim(min(spec[262:921]), max(spec[262:921])) self.ax.autoscale_view(None, False, True) self.canvas.draw() self.show_pos() return True def save_data(self): prefix = self.prefix_dialog.rundialog() if prefix is not None: try: # os.path.exists(prefix) os.mkdir(self.savedir+prefix) except: print("Error creating directory ./" + prefix) path = self.savedir + prefix + '/' self.spectrum.save_data(path) self.status.set_text("Data saved") else: self.status.set_text("Could not save data")
def __init__(self): self.savedir = "./Spectra/" self.path = "./" self.settings = Settings() self.x_step = .0 self.y_step = .0 self.step_distance = 1 # in um try: self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port) except: self.stage = None self.stage = PIStage.Dummy() print("Could not initialize PIStage, using Dummy instead") GObject.threads_init() # only GObject.idle_add() is in the background thread self.window = Gtk.Window(title=self._window_title) # self.window.set_resizable(False) self.window.set_border_width(3) self.grid = Gtk.Grid() self.grid.set_row_spacing(5) self.grid.set_column_spacing(5) self.window.add(self.grid) # Buttons for spectrum stack self.button_live = Gtk.Button(label="Liveview") self.button_live.set_tooltip_text("Start/Stop Liveview of Spectrum") self.button_stop = Gtk.Button(label="Stop") self.button_stop.set_tooltip_text("Stop any ongoing Action") self.button_stop.set_sensitive(False) self.button_aquire = Gtk.Button(label="Aquire Spectrum") self.button_aquire.set_tooltip_text("Start/Stop aquiring Lock-In Spectrum") self.button_direction = Gtk.Button(label="Set Direction") self.button_direction.set_tooltip_text("Set Direction of Stage Movement") self.button_settings = Gtk.Button(label="Settings") self.button_settings.set_tooltip_text("Set Integration Time and Number of Samples") self.button_search = Gtk.Button(label="Search for Max") self.button_search.set_tooltip_text("Search for position with maximum Intensity") self.button_save = Gtk.Button(label="Save Data") self.button_save.set_tooltip_text("Save all spectral Data in .csv") self.button_dark = Gtk.Button(label="Take Dark Spectrum") self.button_dark.set_tooltip_text("Take dark spectrum which will substracted from spectrum") self.button_lamp = Gtk.Button(label="Take Lamp Spectrum") self.button_lamp.set_tooltip_text("Take lamp spectrum to normalize spectrum") self.button_normal = Gtk.Button(label="Take Normal Spectrum") self.button_normal.set_tooltip_text("Start/Stop taking a normal spectrum") self.button_bg = Gtk.Button(label="Take Background Spectrum") self.button_bg.set_tooltip_text("Start/Stop taking a Background spectrum") self.button_series = Gtk.Button(label="Take Time Series") self.button_series.set_tooltip_text("Start/Stop taking a Time Series of Spectra") self.button_reset = Gtk.Button(label="Reset") self.button_reset.set_tooltip_text("Reset all spectral data (if not saved data is lost!)") self.button_loaddark = Gtk.Button(label="Load Dark Spectrum") self.button_loaddark.set_tooltip_text("Load Dark Spectrum from file") self.button_loadlamp = Gtk.Button(label="Load Lamp Spectrum") self.button_loadlamp.set_tooltip_text("Load Lamp Spectrum from file") # Stage Control Buttons self.button_xup = Gtk.Button(label="x+") self.button_xdown = Gtk.Button(label="x-") self.button_yup = Gtk.Button(label="y+") self.button_ydown = Gtk.Button(label="y-") self.button_zup = Gtk.Button(label="z+") self.button_zdown = Gtk.Button(label="z-") self.button_stepup = Gtk.Button(label="+") self.button_stepdown = Gtk.Button(label="-") self.label_stepsize = Gtk.Label(label=str(self.settings.stepsize)) self.button_moverel = Gtk.Button(label="Move Stage rel.") self.button_moveabs = Gtk.Button(label="Move Stage abs.") # Stage position labels self.label_x = Gtk.Label() self.label_y = Gtk.Label() self.label_z = Gtk.Label() self.show_pos() # Connect Buttons self.window.connect("delete-event", self.quit) self.button_aquire.connect("clicked", self.on_lockin_clicked) self.button_direction.connect("clicked", self.on_direction_clicked) self.button_live.connect("clicked", self.on_live_clicked) self.button_stop.connect("clicked", self.on_stop_clicked) self.button_settings.connect("clicked", self.on_settings_clicked) self.button_search.connect("clicked", self.on_search_clicked) self.button_save.connect("clicked", self.on_save_clicked) self.button_dark.connect("clicked", self.on_dark_clicked) self.button_lamp.connect("clicked", self.on_lamp_clicked) self.button_normal.connect("clicked", self.on_normal_clicked) self.button_bg.connect("clicked", self.on_bg_clicked) self.button_series.connect("clicked", self.on_series_clicked) self.button_reset.connect("clicked", self.on_reset_clicked) self.button_loaddark.connect("clicked", self.on_loaddark_clicked) self.button_loadlamp.connect("clicked", self.on_loadlamp_clicked) # Connect Stage Control Buttons self.button_xup.connect("clicked", self.on_xup_clicked) self.button_xdown.connect("clicked", self.on_xdown_clicked) self.button_yup.connect("clicked", self.on_yup_clicked) self.button_ydown.connect("clicked", self.on_ydown_clicked) self.button_zup.connect("clicked", self.on_zup_clicked) self.button_zdown.connect("clicked", self.on_zdown_clicked) self.button_stepup.connect("clicked", self.on_stepup_clicked) self.button_stepdown.connect("clicked", self.on_stepdown_clicked) self.button_moverel.connect("clicked", self.on_moverel_clicked) self.button_moveabs.connect("clicked", self.on_moveabs_clicked) # Stage Control Button Table self.table_stagecontrol = Gtk.Table(3, 4, True) self.table_stagecontrol.attach(self.button_xup, 0, 1, 1, 2) self.table_stagecontrol.attach(self.button_xdown, 2, 3, 1, 2) self.table_stagecontrol.attach(self.button_yup, 1, 2, 0, 1) self.table_stagecontrol.attach(self.button_ydown, 1, 2, 2, 3) self.table_stagecontrol.attach(self.button_zup, 3, 4, 0, 1) self.table_stagecontrol.attach(self.button_zdown, 3, 4, 2, 3) # Stage Stepsize Table self.table_stepsize = Gtk.Table(1, 3, True) self.table_stepsize.attach(self.button_stepup, 0, 1, 0, 1) self.table_stepsize.attach(self.label_stepsize, 1, 2, 0, 1) self.table_stepsize.attach(self.button_stepdown, 2, 3, 0, 1) self.status = Gtk.Label(label="Initialized") self.progress = Gtk.ProgressBar() self._progress_fraction = 0 self.progress.set_fraction(self._progress_fraction) # Box for control of taking single spectra self.SpectrumBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(self.button_live) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(Gtk.Label("Lock-In Spectrum")) self.SpectrumBox.add(self.button_aquire) self.SpectrumBox.add(self.button_direction) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(Gtk.Label(label="Additional Spectra")) self.SpectrumBox.add(self.button_dark) self.SpectrumBox.add(self.button_lamp) self.SpectrumBox.add(self.button_normal) self.SpectrumBox.add(self.button_bg) self.SpectrumBox.add(self.button_series) self.SpectrumBox.add(Gtk.Separator()) self.SpectrumBox.add(Gtk.Label(label="Miscellaneous")) self.SpectrumBox.add(self.button_save) self.SpectrumBox.add(self.button_settings) self.SpectrumBox.add(self.button_reset) self.SpectrumBox.add(self.button_loaddark) self.SpectrumBox.add(self.button_loadlamp) self.SpectrumBox.add(Gtk.Separator()) # Switch corrected Spectrum yes/no self.button_corronoff = Gtk.Switch() self.label_corronoff = Gtk.Label('Correct Spectrum') self.corronoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.corronoff_box.set_homogeneous(True) self.corronoff_box.add(self.label_corronoff) self.corronoff_box.add(self.button_corronoff) # box for Stage control self.stage_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) # self.stage_hbox.add(Gtk.Separator()) self.stage_hbox.add(self.corronoff_box) self.stage_hbox.add(self.button_search) self.stage_hbox.add(Gtk.Label(label="Stage Control")) self.stage_hbox.add(self.table_stagecontrol) self.stage_hbox.add(Gtk.Label(label="Set Stepsize [um]")) self.stage_hbox.add(self.table_stepsize) self.stage_hbox.add(self.button_moverel) self.stage_hbox.add(self.button_moveabs) self.labels_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.labels_hbox.add(self.label_x) self.labels_hbox.add(self.label_y) self.labels_hbox.add(self.label_z) # Buttons for scanning stack self.button_add_position = Gtk.Button('Add Position to List') self.button_spangrid = Gtk.Button('Span Grid') self.button_searchonoff = Gtk.Switch() self.label_searchonoff = Gtk.Label('Search Max.') self.searchonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.searchonoff_box.set_homogeneous(True) self.searchonoff_box.add(self.label_searchonoff) self.searchonoff_box.add(self.button_searchonoff) self.button_lockinonoff = Gtk.Switch() self.label_lockinonoff = Gtk.Label('Use Lock-In') self.lockinonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.lockinonoff_box.set_homogeneous(True) self.lockinonoff_box.add(self.label_lockinonoff) self.lockinonoff_box.add(self.button_lockinonoff) self.button_scan_start = Gtk.Button('Start Scan') self.scan_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3) self.button_scan_add = Gtk.ToolButton(Gtk.STOCK_ADD) self.button_scan_remove = Gtk.ToolButton(Gtk.STOCK_REMOVE) self.button_scan_clear = Gtk.ToolButton(Gtk.STOCK_DELETE) self.scan_hbox.set_homogeneous(True) self.scan_hbox.add(self.button_scan_add) self.scan_hbox.add(self.button_scan_remove) self.scan_hbox.add(self.button_scan_clear) # Treeview for showing/settings scanning grid self.scan_store = Gtk.ListStore(float, float) self.scan_view = Gtk.TreeView(model=self.scan_store) self.scan_xrenderer = Gtk.CellRendererText() self.scan_xrenderer.set_property("editable", True) self.scan_xcolumn = Gtk.TreeViewColumn("x", self.scan_xrenderer, text=0) self.scan_xcolumn.set_min_width(100) self.scan_xcolumn.set_alignment(0.5) self.scan_view.append_column(self.scan_xcolumn) self.scan_yrenderer = Gtk.CellRendererText() self.scan_yrenderer.set_property("editable", True) self.scan_ycolumn = Gtk.TreeViewColumn("y", self.scan_yrenderer, text=1) self.scan_ycolumn.set_min_width(100) self.scan_ycolumn.set_alignment(0.5) self.scan_view.append_column(self.scan_ycolumn) self.scan_scroller = Gtk.ScrolledWindow() self.scan_scroller.set_vexpand(True) self.scan_scroller.add(self.scan_view) self.scan_store.append([10.0, 10.0]) self.scan_store.append([10.1, 10.0]) self.scan_store.append([10.0, 10.1]) #Connections for scanning stack self.button_add_position.connect("clicked", self.on_add_position_clicked) self.button_spangrid.connect("clicked", self.on_spangrid_clicked) self.button_scan_start.connect("clicked", self.on_scan_start_clicked) self.button_scan_add.connect("clicked", self.on_scan_add) self.button_scan_remove.connect("clicked", self.on_scan_remove) self.button_scan_clear.connect("clicked", self.on_scan_clear) self.scan_xrenderer.connect("edited", self.on_scan_xedited) self.scan_yrenderer.connect("edited", self.on_scan_yedited) #Box for control of scanning self.ScanningBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.ScanningBox.add(Gtk.Separator()) self.ScanningBox.add(self.button_add_position) self.ScanningBox.add(self.button_spangrid) self.ScanningBox.add(self.searchonoff_box) self.ScanningBox.add(self.lockinonoff_box) self.ScanningBox.add(Gtk.Separator()) self.ScanningBox.add(Gtk.Label("Scanning Positions")) self.ScanningBox.add(self.scan_hbox) self.ScanningBox.add(self.scan_scroller) self.ScanningBox.add(Gtk.Separator()) self.ScanningBox.add(self.button_scan_start) # MPL stuff self.figure = Figure() self.ax = self.figure.add_subplot(1, 1, 1) self.ax.grid(True) self.ax.set_xlabel("Wavelength [nm]") self.ax.set_ylabel("Intensity") self.ax.set_xlim([400, 900]) self.canvas = FigureCanvas(self.figure) self.canvas.set_hexpand(True) self.canvas.set_vexpand(True) self.canvas.set_size_request(700, 700) self.stack = Gtk.Stack() self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT) self.stack.set_transition_duration(500) self.stack.add_titled(self.SpectrumBox, "spec", "Spectra") self.stack.add_titled(self.ScanningBox, "scan", "Scanning") self.stack_switcher = Gtk.StackSwitcher() self.stack_switcher.set_stack(self.stack) self.SideBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) self.SideBox.add(self.stack_switcher) self.ScanningBox.add(Gtk.Separator()) self.SideBox.add(self.button_stop) self.SideBox.add(self.stack) self.SideBox.add(self.stage_hbox) self.SideBox.add(self.labels_hbox) self.grid.add(self.canvas) self.grid.attach_next_to(self.SideBox, self.canvas, Gtk.PositionType.RIGHT, 1, 1) self.grid.attach_next_to(self.progress, self.canvas, Gtk.PositionType.BOTTOM, 1, 1) self.grid.attach_next_to(self.status, self.SideBox, Gtk.PositionType.BOTTOM, 1, 1) self.window.show_all() self.spectrum = Spectrum(self.stage, self.settings, self.status, self.progress, self.enable_buttons, self.disable_buttons) # logger class which coordinates the spectrometer and the stage spec = self.spectrum.get_spec() # get an initial spectrum for display self._wl = self.spectrum.get_wl() # get the wavelengths print(self._wl) self.lines = [] self.lines.extend(self.ax.plot(self._wl, spec, "-")) self.lines.extend(self.ax.plot(self._wl, self.spectrum.smooth(spec), "-", c="black")) # plot initial spectrum #Dialogs self.settings_dialog = dialogs.SettingsDialog(self.window, self.settings) self.direction_dialog = dialogs.DirectionDialog(self.window, self.settings) self.moveabs_dialog = dialogs.MoveAbsDialog(self.window, self.stage) self.moverel_dialog = dialogs.MoveRelDialog(self.window, self.stage) self.spangrid_dialog = dialogs.SpanGridDialog(self.window) self.prefix_dialog = dialogs.PrefixDialog(self.window) self.pad = None try: #pass self.pad = Gamepad(True) except: print("Could not initialize Gamepad")