def populate(self, unks): keys = set([ki for ui in unks for ki in ui.isotope_keys]) keys = sort_isotopes(list(keys)) blanks = [] for ki in keys: blank = next((bi for bi in self.blanks if bi.name == ki), None) if blank is None: blank = UValue(name=ki) blanks.append(blank) self.blanks = blanks keys = set([iso.detector for ui in unks for iso in ui.isotopes.itervalues()]) keys = sort_isotopes(list(keys)) values = [] for ki in keys: # vi.name includes "IC " value = next((vi for vi in self.values if vi.name[3:] == ki), None) if value is None: value = UValue(name='IC {}'.format(ki)) values.append(value) self.values = [UValue(name='disc')] + values
def populate(self, unks): keys = set([ki for ui in unks for ki in ui.isotope_keys]) keys = sort_isotopes(list(keys)) blanks = [] for ki in keys: blank = next((bi for bi in self.blanks if bi.name == ki), None) if blank is None: blank = UValue(name=ki) blanks.append(blank) self.blanks = blanks keys = set( [iso.detector for ui in unks for iso in ui.isotopes.itervalues()]) keys = sort_isotopes(list(keys)) values = [] for ki in keys: # vi.name includes "IC " value = next((vi for vi in self.values if vi.name[3:] == ki), None) if value is None: value = UValue(name='IC {}'.format(ki)) values.append(value) self.values = [UValue(name='disc')] + values
def run(self, state): super(FitIsotopeEvolutionNode, self).run(state) po = self.plotter_options self._fits = [pi for pi in po.get_loadable_aux_plots()] fs = progress_loader(state.unknowns, self._assemble_result, threshold=1) if self.editor: self.editor.analysis_groups = [(ai, ) for ai in state.unknowns] for ai in state.unknowns: ai.graph_id = 0 self._set_saveable(state) # self.name = '{} Fit IsoEvo'.format(self.name) # if self.has_save_node and po.confirm_save: # if confirmation_dialog('Would you like to review the iso fits before saving?'): # state.veto = self if fs: k = lambda an: an.isotope fs = sort_isotopes(fs, key=k) fs = [ a for _, gs in groupby(fs, key=k) for x in (gs, (IsoEvoResult(), )) for a in x ][:-1] e = IsoEvolutionResultsEditor(fs) state.editors.append(e)
def run(self, state): super(FitIsotopeEvolutionNode, self).run(state) po = self.plotter_options self._fits = [pi for pi in po.get_loadable_aux_plots()] fs = progress_loader(state.unknowns, self._assemble_result, threshold=1) if self.editor: self.editor.analysis_groups = [(ai,) for ai in state.unknowns] for ai in state.unknowns: ai.graph_id = 0 self._set_saveable(state) # self.name = '{} Fit IsoEvo'.format(self.name) # if self.has_save_node and po.confirm_save: # if confirmation_dialog('Would you like to review the iso fits before saving?'): # state.veto = self if fs: k = lambda an: an.isotope fs = sort_isotopes(fs, key=k) fs = [a for _, gs in groupby(fs, key=k) for x in (gs, (IsoEvoResult(),)) for a in x][:-1] e = IsoEvolutionResultsEditor(fs) state.editors.append(e)
def _find_peaks(self): if self.graph.plots: #clear peaks self.graph.remove_rulers() data = self.graph.plots[0].data xs = data.get_data('x0') ys = data.get_data('y0') if len(xs) and len(ys): lookahead = max(1, int(self.min_peak_separation / self.fstep_dac)) mxp, mip = find_peaks(ys, xs, lookahead=lookahead, delta=self.delta) pks = [] isos = self.spectrometer.molecular_weights.keys() isos = sort_isotopes(isos) for dac, v in mxp: if v > self.min_peak_height: l = self.graph.add_vertical_rule(dac) pks.append(CalibrationPeak(dac=dac, isotopes=isos, ruler=l)) self.calibration_peaks = pks self._redraw()
def _find_peaks(self): if self.graph.plots: # clear peaks self.graph.remove_rulers() data = self.graph.plots[0].data xs = data.get_data('x0') ys = data.get_data('y0') if len(xs) and len(ys): lookahead = max(1, int(self.min_peak_separation / self.fstep_dac)) mxp, mip = find_peaks(ys, xs, lookahead=lookahead, delta=self.delta) pks = [] isos = list(self.spectrometer.molecular_weights.keys()) isos = sort_isotopes(isos) for dac, v in mxp: if v > self.min_peak_height: l = self.graph.add_vertical_rule(dac) pks.append( CalibrationPeak(dac=dac, isotopes=isos, ruler=l)) self.calibration_peaks = pks self._redraw()
def test_sorted_iter_isotopes(self): e = self.spec with self.spec.open_file(): isotopes = list(e.iter_isotopes()) isotopes = sort_isotopes(isotopes, key=lambda x: x[0]) for (iso, det), siso in zip(isotopes, ('Ar40', 'Ar39', 'Ar38', 'Ar37', 'Ar36')): self.assertEqual(iso, siso)
def test_sorted_iter_isotopes(self): e = self.spec with self.spec.open_file(): isotopes = list(e.iter_isotopes()) isotopes = sort_isotopes(isotopes, key=lambda x: x[0]) for (iso, det), siso in zip(isotopes, ('Ar40', 'Ar39', 'Ar38', 'Ar37', 'Ar36')): self.assertEqual(iso, siso)
def set_columns(self, isos, dets): cs = [('RunID', 'record_id'), ('Date', 'rundate')] for i in sort_isotopes(isos): for k in ('rev.', 'fit', 'bs. fit'): cs.append(('{} {}'.format(i, k), 'iso:{}:{}'.format(k, i))) for d in sort_detectors(dets): for k in ('rev.', ): cs.append(('{} IC {}'.format(d, k), 'ic:{}:{}'.format(k, d))) self.columns = cs
def set_columns(self, isos, dets): cs = [('RunID', 'record_id'), ('Date', 'rundate')] for i in sort_isotopes(isos): for k in ('rev.', 'fit', 'bs. fit'): cs.append(('{} {}'.format(i, k), 'iso:{}:{}'.format(k, i))) for d in sort_detectors(dets): for k in ('rev.',): cs.append(('{} IC {}'.format(d, k), 'ic:{}:{}'.format(k, d))) self.columns = cs
def _configure_hook(self): if self.unknowns or self.references: uisokeys = get_isotope_set(self.unknowns) risokeys = get_isotope_set(self.references) isokeys = list(uisokeys.union(risokeys)) self.available_isotopes = [Isot(name=i) for i in sort_isotopes(isokeys)] # if self.unknowns: # ref = self.unknowns[0] # else: # ref = self.references[0] temps = ('lab_temperature', 'east_diffuser_temperature', 'east_return_temperature', 'outside_temperature') self.available_meta_attributes = list(('rundate', 'timestamp') + META_ATTRS + EXTRACTION_ATTRS + temps) self._select_all_meta_fired()
def _add_isotopes(self, analysis, spec, refdet, runtype): # with spec.open_file(): isotopes = list(spec.iter_isotopes()) isotopes = sort_isotopes(isotopes, key=lambda x: x[0]) bs = [] for iso, det in isotopes: self.debug('adding isotope {} {}'.format(iso, det)) dbiso, dbdet = self._add_isotope(analysis, spec, iso, det, refdet) if dbdet.detector_type.Label not in bs: self._add_baseline(spec, dbiso, dbdet, det) bs.append(dbdet.detector_type.Label) self._add_signal(spec, dbiso, dbdet, det, runtype)
def _add_isotopes(self, analysis, spec, refdet, runtype): # with spec.open_file(): isotopes = list(spec.iter_isotopes()) isotopes = sort_isotopes(isotopes, key=lambda x: x[0]) bs = [] for iso, det in isotopes: self.debug('adding isotope {} {}'.format(iso, det)) dbiso, dbdet = self._add_isotope(analysis, spec, iso, det, refdet) if dbdet.detector_type.Label not in bs: self._add_baseline(spec, dbiso, dbdet, det) bs.append(dbdet.detector_type.Label) self._add_signal(spec, dbiso, dbdet, det, runtype)
def _get_peak_center_config(self, config_name): if config_name is None: config_name = 'default' config = self.peak_center_config.get(config_name) config.detectors = self.spectrometer.detectors_names if config.detector_name: config.detector = next((di for di in config.detectors if di == config.detector_name), None) if not config.detector: config.detector = config.detectors[0] keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) return config
def _get_peak_center_config(self, config_name): if config_name is None: config_name = 'default' config = self.peak_center_config.get(config_name) config.detectors = self.spectrometer.detectors_names if config.detector_name: config.detector = next( (di for di in config.detectors if di == config.detector_name), None) if not config.detector: config.detector = config.detectors[0] keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) return config
def _coincidence_config_default(self): config = None p = os.path.join(paths.hidden_dir, 'coincidence_config.p') if os.path.isfile(p): try: with open(p) as rfile: config = pickle.load(rfile) config.detectors = dets = self.spectrometer.detectors config.detector = next((di for di in dets if di.name == config.detector_name), None) except Exception as e: print('coincidence config', e) if config is None: config = CoincidenceConfig() config.detectors = self.spectrometer.detectors config.detector = config.detectors[0] keys = list(self.spectrometer.molecular_weights.keys()) config.isotopes = sort_isotopes(keys) return config
def show_blank_time_series(self): g = StackedRegressionGraph(window_height=0.75) isotopes = self.blank_selected[0].isotopes keys = sort_isotopes([iso.isotope for iso in isotopes], reverse=False) _mi, _ma = None, None for k in keys: iso = next((i for i in isotopes if i.isotope == k)) # print iso.analyses g.new_plot(padding_right=10) g.set_time_xaxis() g.set_y_title(iso.isotope) g.new_series([self.timestamp], [iso.value], marker_size=3, fit=False, type='scatter', marker_color='black') vs = iso.values if vs: ts = [vi.timestamp for vi in vs] _mi = min(ts) _ma = max(ts) g.new_series(ts, [vi.value for vi in vs], yerror=ArrayDataSource([vi.error for vi in vs]), marker_size=3, fit=(iso.fit, 'SD'), type='scatter', marker_color='red') if not _mi: _mi, _ma = self.timestamp - 86400, self.timestamp + 86400 g.set_x_limits(_mi, _ma, pad='0.1') g.refresh() g.set_x_title('Time', plotid=0) g.edit_traits()
def _advanced_filter_button_fired(self): self.debug('advanced filter') # self.warning_dialog('Advanced filtering currently disabled') attrs = self.dvc.get_search_attributes() if attrs: attrs = sort_isotopes(list({a[0].split('_')[0] for a in attrs})) m = self.advanced_filter m.attributes = attrs m.demo() info = m.edit_traits(kind='livemodal') if info.result: uuids = None at = self.analysis_table if not m.apply_to_current_selection and not m.apply_to_current_samples: lns = self.dvc.get_analyses_advanced(m, return_labnumbers=True) sams = self._load_sample_record_views(lns) self.samples = sams self.osamples = sams elif m.apply_to_current_selection: ans = self.analysis_table.get_selected_analyses() if ans: uuids = [ai.uuid for ai in ans] identifiers = None if m.apply_to_current_samples: identifiers = [si.identifier for si in self.samples] ans = self.dvc.get_analyses_advanced(m, uuids=uuids, identifiers=identifiers, include_invalid=not m.omit_invalid, limit=m.limit) if m.apply_to_current_selection and not ans: self.warning_dialog('No analyses match criteria') return ans = self._make_records(ans) self.analysis_table.set_analyses(ans)
def show_blank_time_series(self): g = StackedRegressionGraph(window_height=0.75) isotopes = self.blank_selected[0].isotopes keys = sort_isotopes([iso.isotope for iso in isotopes], reverse=False) _mi, _ma = None, None for k in keys: iso = next((i for i in isotopes if i.isotope == k)) # print iso.analyses g.new_plot(padding_right=10) g.set_time_xaxis() g.set_y_title(iso.isotope) g.new_series([self.timestamp], [iso.value], marker_size=3, fit=False, type='scatter', marker_color='black') vs = iso.values if vs: ts = [vi.timestamp for vi in vs] _mi = min(ts) _ma = max(ts) g.new_series(ts, [vi.value for vi in vs], yerror=ArrayDataSource([vi.error for vi in vs]), marker_size=3, fit=(iso.fit, 'SD'), type='scatter', marker_color='red') if not _mi: _mi, _ma = self.timestamp - 86400, self.timestamp + 86400 g.set_x_limits(_mi, _ma, pad='0.1') g.refresh() g.set_x_title('Time', plotid=0) g.edit_traits()
def _coincidence_config_default(self): config = None p = os.path.join(paths.hidden_dir, 'coincidence_config.p') if os.path.isfile(p): try: with open(p) as rfile: config = pickle.load(rfile) config.detectors = dets = self.spectrometer.detectors config.detector = next( (di for di in dets if di.name == config.detector_name), None) except Exception as e: print('coincidence config', e) if config is None: config = CoincidenceConfig() config.detectors = self.spectrometer.detectors config.detector = config.detectors[0] keys = list(self.spectrometer.molecular_weights.keys()) config.isotopes = sort_isotopes(keys) return config
def _make_references(self): keys = set([ki for ui in self._references for ki in ui.isotope_keys]) keys = sort_isotopes(keys) if 'Ar40' in keys and 'Ar36' in keys: self.tool.load_fits(['Ar40/Ar36'])
def _get_union_detectors(self): x = set(self.udetectors).union(self.rdetectors) return sort_isotopes(x)
def _get_union_detectors(self): x = set(self.udetectors).union(self.rdetectors) return sort_isotopes(x)
def show_evolutions_factory(record_id, isotopes, show_evo=True, show_equilibration=False, show_baseline=False): if WINDOW_CNT > 20: information(None, 'You have too many Isotope Evolution windows open. Close some before proceeding') return from pychron.graph.stacked_regression_graph import StackedRegressionGraph if not show_evo: xmi = Inf xma = -Inf else: xmi, xma = 0, -Inf g = StackedRegressionGraph(resizable=True) g.plotcontainer.spacing = 10 g.window_height = min(275 * len(isotopes), 800) g.window_x = OX + XOFFSET * WINDOW_CNT g.window_y = OY + YOFFSET * WINDOW_CNT isotopes = sort_isotopes(isotopes, reverse=False, key=lambda x: x.name) for i, iso in enumerate(isotopes): ymi, yma = Inf, -Inf p = g.new_plot(padding=[80, 10, 10, 40]) g.add_limit_tool(p, 'x') g.add_limit_tool(p, 'y') g.add_axis_tool(p, p.x_axis) g.add_axis_tool(p, p.y_axis) p.y_axis.title_spacing = 50 if show_equilibration: sniff = iso.sniff g.new_series(sniff.xs, sniff.ys, type='scatter', fit=None, color='red') ymi, yma = min_max(ymi, yma, sniff.ys) xmi, xma = min_max(xmi, xma, sniff.xs) if show_evo: g.new_series(iso.xs, iso.ys, fit=iso.fit, filter_outliers_dict=iso.filter_outliers_dict, color='black') ymi, yma = min_max(ymi, yma, iso.ys) xmi, xma = min_max(xmi, xma, iso.xs) if show_baseline: baseline = iso.baseline g.new_series(baseline.xs, baseline.ys, type='scatter', fit=baseline.fit, filter_outliers_dict=baseline.filter_outliers_dict, color='blue') ymi, yma = min_max(ymi, yma, baseline.ys) xmi, xma = min_max(xmi, xma, baseline.xs) g.set_x_limits(min_=xmi, max_=xma, pad='0.025,0.05') g.set_y_limits(min_=ymi, max_=yma, pad='0.05', plotid=i) g.set_x_title('Time (s)', plotid=i) g.set_y_title('{} (fA)'.format(iso.name), plotid=i) g.refresh() g.window_title = '{} {}'.format(record_id, ','.join([i.name for i in reversed(isotopes)])) return g
def isotope_keys(self): keys = self.isotopes.keys() return sort_isotopes(keys)
def _get_isotope_keys(self): keys = list(self.isotopes.keys()) return sort_isotopes(keys)
def _setup_config(self): config = self.peak_center_config config.detectors = self.spectrometer.detector_names keys = list(self.spectrometer.molecular_weights.keys()) config.isotopes = sort_isotopes(keys) config.integration_times = self.spectrometer.integration_times
class IonOpticsManager(Manager): reference_detector = Instance(BaseDetector) reference_isotope = Any magnet_dac = Range(0.0, 6.0) graph = Instance(Graph) peak_center_button = Button('Peak Center') stop_button = Button('Stop') alive = Bool(False) spectrometer = Any peak_center = Instance(PeakCenter) coincidence = Instance(Coincidence) peak_center_config = Instance(PeakCenterConfigurer) # coincidence_config = Instance(CoincidenceConfig) canceled = False peak_center_result = None _centering_thread = None def close(self): self.cancel_peak_center() def cancel_peak_center(self): self.alive = False self.canceled = True self.peak_center.canceled = True self.peak_center.stop() self.info('peak center canceled') def get_mass(self, isotope_key): spec = self.spectrometer molweights = spec.molecular_weights return molweights[isotope_key] def set_mftable(self, name=None): """ if mt is None set to the default mftable located at setupfiles/spectrometer/mftable.csv :param mt: :return: """ if name and name != os.path.splitext(os.path.basename( paths.mftable))[0]: self.spectrometer.use_deflection_correction = False else: self.spectrometer.use_deflection_correction = True self.spectrometer.magnet.set_mftable(name) def get_position(self, *args, **kw): kw['update_isotopes'] = False return self._get_position(*args, **kw) def position(self, pos, detector, *args, **kw): dac = self._get_position(pos, detector, *args, **kw) mag = self.spectrometer.magnet self.info('positioning {} ({}) on {}'.format(pos, dac, detector)) return mag.set_dac(dac) def do_coincidence_scan(self, new_thread=True): if new_thread: t = Thread(name='ion_optics.coincidence', target=self._coincidence) t.start() self._centering_thread = t def setup_coincidence(self): pcc = self.coincidence_config pcc.dac = self.spectrometer.magnet.dac info = pcc.edit_traits() if not info.result: return detector = pcc.detector isotope = pcc.isotope detectors = [d for d in pcc.additional_detectors] # integration_time = pcc.integration_time if pcc.use_nominal_dac: center_dac = self.get_position(isotope, detector) elif pcc.use_current_dac: center_dac = self.spectrometer.magnet.dac else: center_dac = pcc.dac # self.spectrometer.save_integration() # self.spectrometer.set_integration(integration_time) cs = Coincidence(spectrometer=self.spectrometer, center_dac=center_dac, reference_detector=detector, reference_isotope=isotope, additional_detectors=detectors) self.coincidence = cs return cs def get_center_dac(self, det, iso): spec = self.spectrometer det = spec.get_detector(det) molweights = spec.molecular_weights mass = molweights[iso] dac = spec.magnet.map_mass_to_dac(mass, det.name) # correct for deflection return spec.correct_dac(det, dac) def do_peak_center(self, save=True, confirm_save=False, warn=False, new_thread=True, message='', on_end=None, timeout=None): self.debug('doing pc') self.canceled = False self.alive = True self.peak_center_result = None args = (save, confirm_save, warn, message, on_end, timeout) if new_thread: t = Thread(name='ion_optics.peak_center', target=self._peak_center, args=args) t.start() self._centering_thread = t return t else: self._peak_center(*args) def setup_peak_center(self, detector=None, isotope=None, integration_time=1.04, directions='Increase', center_dac=None, plot_panel=None, new=False, standalone_graph=True, name='', show_label=False, window=0.015, step_width=0.0005, min_peak_height=1.0, percent=80, deconvolve=None, use_interpolation=False, interpolation_kind='linear', dac_offset=None, calculate_all_peaks=False, config_name=None, use_configuration_dac=True): if deconvolve is None: n_peaks, select_peak = 1, 1 if dac_offset is not None: use_dac_offset = True spec = self.spectrometer spec.save_integration() self.debug('setup peak center. detector={}, isotope={}'.format( detector, isotope)) self._setup_config() pcc = None if detector is None or isotope is None: self.debug('ask user for peak center configuration') self.peak_center_config.load(dac=spec.magnet.dac) if config_name: self.peak_center_config.active_name = config_name info = self.peak_center_config.edit_traits() if not info.result: return else: pcc = self.peak_center_config.active_item elif config_name: self.peak_center_config.load(dac=spec.magnet.dac) self.peak_center_config.active_name = config_name pcc = self.peak_center_config.active_item if pcc: if not detector: detector = pcc.active_detectors if not isotope: isotope = pcc.isotope directions = pcc.directions integration_time = pcc.integration_time window = pcc.window min_peak_height = pcc.min_peak_height step_width = pcc.step_width percent = pcc.percent use_interpolation = pcc.use_interpolation interpolation_kind = pcc.interpolation_kind n_peaks = pcc.n_peaks select_peak = pcc.select_n_peak use_dac_offset = pcc.use_dac_offset dac_offset = pcc.dac_offset calculate_all_peaks = pcc.calculate_all_peaks if center_dac is None and use_configuration_dac: center_dac = pcc.dac spec.set_integration_time(integration_time) period = int(integration_time * 1000 * 0.9) if not isinstance(detector, (tuple, list)): detector = (detector, ) ref = detector[0] ref = self.spectrometer.get_detector(ref) self.reference_detector = ref self.reference_isotope = isotope if center_dac is None: center_dac = self.get_center_dac(ref, isotope) if len(detector) > 1: ad = detector[1:] else: ad = [] pc = self.peak_center if not pc or new: pc = PeakCenter() pc.trait_set(center_dac=center_dac, period=period, window=window, percent=percent, min_peak_height=min_peak_height, step_width=step_width, directions=directions, reference_detector=ref, additional_detectors=ad, reference_isotope=isotope, spectrometer=spec, show_label=show_label, use_interpolation=use_interpolation, interpolation_kind=interpolation_kind, n_peaks=n_peaks, select_peak=select_peak, use_dac_offset=use_dac_offset, dac_offset=dac_offset, calculate_all_peaks=calculate_all_peaks) self.peak_center = pc graph = pc.graph graph.name = name if plot_panel: plot_panel.set_peak_center_graph(graph) else: graph.close_func = self.close if standalone_graph: # set graph window attributes graph.window_title = 'Peak Center {}({}) @ {:0.3f}'.format( ref, isotope, center_dac) graph.window_width = 300 graph.window_height = 250 open_view(graph) return self.peak_center # private def _setup_config(self): config = self.peak_center_config config.detectors = self.spectrometer.detector_names keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) def _get_peak_center_config(self, config_name): if config_name is None: config_name = 'default' config = self.peak_center_config.get(config_name) config.detectors = self.spectrometer.detectors_names if config.detector_name: config.detector = next( (di for di in config.detectors if di == config.detector_name), None) if not config.detector: config.detector = config.detectors[0] keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) return config def _timeout_func(self, timeout, evt): st = time.time() while not evt.is_set(): if not self.alive: break if time.time() - st > timeout: self.warning( 'Peak Centering timed out after {}s'.format(timeout)) self.cancel_peak_center() break time.sleep(0.01) def _peak_center(self, save, confirm_save, warn, message, on_end, timeout): pc = self.peak_center spec = self.spectrometer ref = self.reference_detector isotope = self.reference_isotope if timeout: evt = Event() self.timeout_thread = Thread(target=self._timeout_func, args=(timeout, evt)) self.timeout_thread.start() dac_d = pc.get_peak_center() self.peak_center_result = dac_d if dac_d: args = ref, isotope, dac_d self.info('new center pos {} ({}) @ {}'.format(*args)) det = spec.get_detector(ref) dac_a = spec.uncorrect_dac(det, dac_d) self.info('dac uncorrected for HV and deflection {}'.format(dac_a)) if save: if confirm_save: msg = 'Update Magnet Field Table with new peak center- {} ({}) @ RefDetUnits= {}'.format( *args) save = self.confirmation_dialog(msg) if save: spec.magnet.update_field_table(det, isotope, dac_a, message) spec.magnet.set_dac(dac_d) elif not self.canceled: msg = 'centering failed' if warn: self.warning_dialog(msg) self.warning(msg) # needs to be called on the main thread to properly update # the menubar actions. alive=False enables IonOptics>Peak Center # d = lambda:self.trait_set(alive=False) # still necessary with qt? and tasks if on_end: on_end() self.trait_set(alive=False) if timeout: evt.set() self.spectrometer.restore_integration() def _get_position(self, pos, detector, use_dac=False, update_isotopes=True): """ pos can be str or float "Ar40", "39.962", 39.962 to set in DAC space set use_dac=True """ if pos == NULL_STR: return spec = self.spectrometer mag = spec.magnet if isinstance(detector, str): det = spec.get_detector(detector) else: det = detector self.debug('detector {}'.format(det)) if use_dac: dac = pos else: self.debug('POSITION {} {}'.format(pos, detector)) if isinstance(pos, str): try: pos = float(pos) except ValueError: # pos is isotope if update_isotopes: # if the pos is an isotope then update the detectors spec.update_isotopes(pos, detector) pos = self.get_mass(pos) mag.mass_change(pos) # pos is mass i.e 39.962 dac = mag.map_mass_to_dac(pos, det.name) dac = spec.correct_dac(det, dac) return dac def _coincidence(self): self.coincidence.get_peak_center() self.info('coincidence finished') self.spectrometer.restore_integration() # =============================================================================== # handler # =============================================================================== def _coincidence_config_default(self): config = None p = os.path.join(paths.hidden_dir, 'coincidence_config.p') if os.path.isfile(p): try: with open(p) as rfile: config = pickle.load(rfile) config.detectors = dets = self.spectrometer.detectors config.detector = next( (di for di in dets if di.name == config.detector_name), None) except Exception, e: print 'coincidence config', e if config is None: config = CoincidenceConfig() config.detectors = self.spectrometer.detectors config.detector = config.detectors[0] keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) return config
def show_evolutions_factory(record_id, isotopes, show_evo=True, show_equilibration=False, show_baseline=False, show_statistics=False, ncols=1, scale_to_equilibration=False): if WINDOW_CNT > 20: information( None, 'You have too many Isotope Evolution windows open. Close some before proceeding' ) return if not show_evo: xmi = Inf xma = -Inf else: xmi, xma = 0, -Inf if ncols > 1: isotopes = sort_isotopes(isotopes, reverse=True, key=attrgetter('name')) def reorder(l, n): l = [l[i:i + n] for i in range(0, len(l), n)] nl = [] for ri in range(len(l[0])): for col in l: try: nl.append(col[ri]) except IndexError: pass return nl nrows = ceil(len(isotopes) / ncols) isotopes = reorder(isotopes, nrows) g = ColumnStackedRegressionGraph(resizable=True, ncols=ncols, nrows=nrows, container_dict={ 'padding_top': 15 * nrows, 'spacing': (0, 15), 'padding_bottom': 40 }) resizable = 'hv' else: resizable = 'h' isotopes = sort_isotopes(isotopes, reverse=False, key=attrgetter('name')) g = StackedRegressionGraph(resizable=True, container_dict={'spacing': 15}) # g.plotcontainer.spacing = 10 g.window_height = min(275 * len(isotopes), 800) g.window_x = OX + XOFFSET * WINDOW_CNT g.window_y = OY + YOFFSET * WINDOW_CNT for i, iso in enumerate(isotopes): ymi, yma = Inf, -Inf p = g.new_plot(padding=[80, 10, 10, 40], resizable=resizable) g.add_limit_tool(p, 'x') g.add_limit_tool(p, 'y') g.add_axis_tool(p, p.x_axis) g.add_axis_tool(p, p.y_axis) if show_statistics: g.add_statistics(i) p.y_axis.title_spacing = 50 if show_equilibration: sniff = iso.sniff if sniff.xs.shape[0]: g.new_series(sniff.offset_xs, sniff.ys, type='scatter', fit=None, color='red') ymi, yma = min_max(ymi, yma, sniff.ys) xmi, xma = min_max(xmi, xma, sniff.offset_xs) if show_evo: if iso.fit is None: iso.fit = 'linear' g.new_series(iso.offset_xs, iso.ys, fit=iso.efit, truncate=iso.truncate, filter_outliers_dict=iso.filter_outliers_dict, color='black') g.set_regressor(iso.regressor, i) xmi, xma = min_max(xmi, xma, iso.offset_xs) if not scale_to_equilibration: ymi, yma = min_max(ymi, yma, iso.ys) if show_baseline: baseline = iso.baseline g.new_series(baseline.offset_xs, baseline.ys, type='scatter', fit=baseline.efit, filter_outliers_dict=baseline.filter_outliers_dict, color='blue') xmi, xma = min_max(xmi, xma, baseline.offset_xs) if not scale_to_equilibration: ymi, yma = min_max(ymi, yma, baseline.ys) xpad = '0.025,0.05' ypad = '0.05' if scale_to_equilibration: ypad = None r = (yma - ymi) * 0.02 # ymi = yma - r fit = iso.fit if fit != 'average': fit, _ = convert_fit(iso.fit) fy = polyval(polyfit(iso.offset_xs, iso.ys, fit), 0) if ymi > fy: ymi = fy - r fy = polyval(polyfit(iso.offset_xs, iso.ys, fit), xma) if fy > yma: yma = fy elif fy < ymi: ymi = fy - r # yma += r g.set_x_limits(min_=xmi, max_=xma, pad=xpad) g.set_y_limits(min_=ymi, max_=yma, pad=ypad, plotid=i) g.set_x_title('Time (s)', plotid=i) g.set_y_title('{} ({})'.format(iso.name, iso.units), plotid=i) g.refresh() g.window_title = '{} {}'.format( record_id, ','.join([i.name for i in reversed(isotopes)])) return g
def show_evolutions_factory(record_id, isotopes, show_evo=True, show_equilibration=False, show_baseline=False): if WINDOW_CNT > 20: information( None, 'You have too many Isotope Evolution windows open. Close some before proceeding' ) return from pychron.graph.stacked_regression_graph import StackedRegressionGraph if not show_evo: xmi = Inf xma = -Inf else: xmi, xma = 0, -Inf g = StackedRegressionGraph(resizable=True) g.plotcontainer.spacing = 10 g.window_height = min(275 * len(isotopes), 800) g.window_x = OX + XOFFSET * WINDOW_CNT g.window_y = OY + YOFFSET * WINDOW_CNT isotopes = sort_isotopes(isotopes, reverse=False, key=lambda x: x.name) for i, iso in enumerate(isotopes): ymi, yma = Inf, -Inf p = g.new_plot(padding=[80, 10, 10, 40]) g.add_limit_tool(p, 'x') g.add_limit_tool(p, 'y') g.add_axis_tool(p, p.x_axis) g.add_axis_tool(p, p.y_axis) p.y_axis.title_spacing = 50 if show_equilibration: sniff = iso.sniff g.new_series(sniff.xs, sniff.ys, type='scatter', fit=None, color='red') ymi, yma = min_max(ymi, yma, sniff.ys) xmi, xma = min_max(xmi, xma, sniff.xs) if show_evo: g.new_series(iso.xs, iso.ys, fit=iso.fit, filter_outliers_dict=iso.filter_outliers_dict, color='black') ymi, yma = min_max(ymi, yma, iso.ys) xmi, xma = min_max(xmi, xma, iso.xs) if show_baseline: baseline = iso.baseline g.new_series(baseline.xs, baseline.ys, type='scatter', fit=baseline.fit, filter_outliers_dict=baseline.filter_outliers_dict, color='blue') ymi, yma = min_max(ymi, yma, baseline.ys) xmi, xma = min_max(xmi, xma, baseline.xs) g.set_x_limits(min_=xmi, max_=xma, pad='0.025,0.05') g.set_y_limits(min_=ymi, max_=yma, pad='0.05', plotid=i) g.set_x_title('Time (s)', plotid=i) g.set_y_title('{} (fA)'.format(iso.name), plotid=i) g.refresh() g.window_title = '{} {}'.format( record_id, ','.join([i.name for i in reversed(isotopes)])) return g
def _get_isotope_keys(self): keys = list(self.isotopes.keys()) return sort_isotopes(keys)
def _setup_config(self): config = self.peak_center_config config.detectors = self.spectrometer.detector_names keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys)
class IonOpticsManager(Manager): magnet_dac = Range(0.0, 6.0) graph = Instance(Graph) peak_center_button = Button('Peak Center') stop_button = Button('Stop') alive = Bool(False) spectrometer = Any peak_center = Instance(PeakCenter) peak_center_config = Instance(PeakCenterConfig) canceled = False peak_center_result = None _ointegration_time = None def get_mass(self, isotope_key): spec = self.spectrometer molweights = spec.molecular_weights return molweights[isotope_key] def position(self, pos, detector, use_dac=False, update_isotopes=True): if pos == NULL_STR: return spec = self.spectrometer mag = spec.magnet det = spec.get_detector(detector) self.debug('detector {}'.format(det)) if use_dac: dac = pos else: self.debug('POSITION {} {}'.format(pos, detector)) if isinstance(pos, str): if update_isotopes: # if the pos is an isotope then update the detectors spec.update_isotopes(pos, detector) # pos is isotope pos = self.get_mass(pos) mag._mass = pos else: #get nearst isotope self.debug('rounding mass {} to {}'.format( pos, ' {:n}'.format(round(pos)))) spec.update_isotopes(' {:n}'.format(round(pos)), detector) # pos is mass i.e 39.962 dac = mag.map_mass_to_dac(pos, det.name) if det: dac = spec.correct_dac(det, dac) self.info('positioning {} ({}) on {}'.format(pos, dac, detector)) mag.set_dac(dac) def get_center_dac(self, det, iso): spec = self.spectrometer det = spec.get_detector(det) molweights = spec.molecular_weights mass = molweights[iso] dac = spec.magnet.map_mass_to_dac(mass, det.name) # correct for deflection return spec.correct_dac(det, dac) def do_peak_center(self, save=True, confirm_save=False, warn=False, new_thread=True): self.debug('doing pc') self.canceled = False self.alive = True args = (save, confirm_save, warn) if new_thread: t = Thread(name='ion_optics.peak_center', target=self._peak_center, args=args) t.start() self._thread = t return t else: self._peak_center(*args) def setup_peak_center(self, detector=None, isotope=None, integration_time=1.04, directions='Increase', center_dac=None, plot_panel=None): self._ointegration_time = self.spectrometer.integration_time if detector is None or isotope is None: pcc = self.peak_center_config pcc.dac = self.spectrometer.magnet.dac info = pcc.edit_traits() if not info.result: return else: detector = pcc.detector.name isotope = pcc.isotope directions = pcc.directions integration_time = pcc.integration_time if not pcc.use_current_dac: center_dac = pcc.dac self.spectrometer.set_integration_time(integration_time) period = int(integration_time * 1000 * 0.9) if isinstance(detector, (tuple, list)): ref = detector[0] detectors = detector else: ref = detector detectors = (ref, ) if center_dac is None: center_dac = self.get_center_dac(ref, isotope) self._setup_peak_center(detectors, isotope, period, center_dac, directions, plot_panel) return self.peak_center def _setup_peak_center(self, detectors, isotope, period, center_dac, directions, plot_panel): spec = self.spectrometer ref = detectors[0] self.reference_detector = ref self.reference_isotope = isotope if len(detectors) > 1: ad = detectors[1:] else: ad = [] pc = self.peak_center if not pc: pc = PeakCenter() pc.trait_set(center_dac=center_dac, period=period, directions=directions, reference_detector=ref, additional_detectors=ad, reference_isotope=isotope, spectrometer=spec) self.peak_center = pc graph = pc.graph if plot_panel: # plot_panel.peak_center_graph = graph plot_panel.set_peak_center_graph(graph) else: # bind to the graphs close_func # self.close is called when graph window is closed # use so we can stop the timer graph.close_func = self.close # set graph window attributes graph.window_title = 'Peak Center {}({}) @ {:0.3f}'.format( ref, isotope, center_dac) graph.window_width = 300 graph.window_height = 250 self.open_view(graph) def _peak_center(self, save, confirm_save, warn): pc = self.peak_center spec = self.spectrometer ref = self.reference_detector isotope = self.reference_isotope dac_d = pc.get_peak_center() self.peak_center_result = dac_d if dac_d: args = ref, isotope, dac_d self.info('new center pos {} ({}) @ {}'.format(*args)) det = spec.get_detector(ref) ## correct for hv #dac_d /= spec.get_hv_correction(current=True) # ## correct for deflection #dac_d = dac_d - det.get_deflection_correction(current=True) # ## convert dac to axial units #dac_a = dac_d / det.relative_position dac_a = spec.uncorrect_dac(det, dac_d) self.info('converted to axial units {}'.format(dac_a)) if save: save = True if confirm_save: msg = 'Update Magnet Field Table with new peak center- {} ({}) @ RefDetUnits= {}'.format( *args) save = self.confirmation_dialog(msg) if save: spec.magnet.update_field_table(det, isotope, dac_a) spec.magnet.set_dac(self.peak_center_result) elif not self.canceled: msg = 'centering failed' if warn: self.warning_dialog(msg) self.warning(msg) # needs to be called on the main thread to properly update # the menubar actions. alive=False enables IonOptics>Peak Center # d = lambda:self.trait_set(alive=False) # still necessary with qt? and tasks self.trait_set(alive=False) if self._ointegration_time: self.spectrometer.set_integration_time(self._ointegration_time) def close(self): self.cancel_peak_center() def cancel_peak_center(self): self.alive = False self.canceled = True self.peak_center.canceled = True self.peak_center.stop() self.info('peak center canceled') #=============================================================================== # handler #=============================================================================== def _peak_center_config_default(self): config = None p = os.path.join(paths.hidden_dir, 'peak_center_config') if os.path.isfile(p): try: with open(p) as fp: config = pickle.load(fp) config.detectors = dets = self.spectrometer.detectors config.detector = next( (di for di in dets if di.name == config.detector_name), None) except Exception, e: print 'peak center config', e if config is None: config = PeakCenterConfig() config.detectors = self.spectrometer.detectors config.detector = config.detectors[0] keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) return config
def isotope_keys(self): keys = self.isotopes.keys() return sort_isotopes(keys)
try: with open(p) as rfile: config = pickle.load(rfile) config.detectors = dets = self.spectrometer.detectors config.detector = next((di for di in dets if di.name == config.detector_name), None) except Exception, e: print 'peak center config', e if config is None: config = PeakCenterConfig() config.detectors = self.spectrometer.detectors config.detector = config.detectors[0] keys = self.spectrometer.molecular_weights.keys() config.isotopes = sort_isotopes(keys) return config if __name__ == '__main__': io = IonOpticsManager() io.configure_traits() # ============= EOF ============================================= # def _graph_factory(self): # g = Graph( # container_dict=dict(padding=5, bgcolor='gray')) # g.new_plot() # return g #