def set_energy(self): energy = self.hhm.energy.read()['hhm_energy']['value'] dlg = SetEnergy.SetEnergy(round(energy), parent=self) if dlg.exec_(): try: new_energy=float(dlg.getValues()) print(new_energy) if (new_energy > 4700) and (new_energy < 32000): self.RE(bps.mv(self.hhm.energy, new_energy)) else: raise ValueError except Exception as exc: message_box('Incorrect energy','Energy should be within 4700-32000 eV range')
def _check_entry(el, edge, energy, name, row): info = f'Proposal: {name}, row: {row+1}, element: {el}, edge: {edge}, energy: {energy}' if el in element_dict.keys(): if edge in element_dict[el].keys(): if abs( energy - float(element_dict[el][edge]) ) < 10: # provided energy must be within 10 eV from the xray DB if (energy > 4900) and (energy < 32000): return True else: message_box('Energy outside of feasible range', ( 'Warning\nAn entry with energy outside of feasible range found!\n' + 'This measurement will be skipped.\n' + info)) else: message_box( 'Invalid energy', ('Warning\nAn entry with invalid energy was found!\n' + 'This measurement will be skipped.\n' + info)) else: message_box('Edge not found', ('Warning\nAn entry with invalid edge was found!\n' + 'This measurement will be skipped.\n' + info)) else: message_box('Element not found', ('Warning\nAn entry with invalid element was found!\n' + 'This measurement will be skipped.\n' + info)) return False
def send_results(self): dlg = GetEmailAddress.GetEmailAddress('', parent=self) if dlg.exec_(): email_address = dlg.getValue() regex = '^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$' if re.search(regex, email_address): #print(f'email {email_address}') pass else: message_box('Error', 'Invaild email') return 0 year = self.RE.md['year'] cycle = self.RE.md['cycle'] proposal = self.RE.md['PROPOSAL'] PI = self.RE.md['PI'] working_directory = f'/nsls2/xf08id/users/{year}/{cycle}/{proposal}' zip_file = f'{working_directory}/{proposal}.zip' id = str(uuid.uuid4())[0:5] zip_id_file = f'{proposal}-{id}.zip' if os.path.exists(zip_file): os.remove(zip_file) os.system(f'zip {zip_file} {working_directory}/*.dat ') dropbox_service = get_dropbox_service() with open(zip_file, "rb") as f: file_id = dropbox_service.files_upload( f.read(), f'/{year}/{cycle}/{zip_id_file}') file_link = dropbox_service.sharing_create_shared_link( f'/{year}/{cycle}/{zip_id_file}') link_url = file_link.url print('Upload succesful') gmail_service = get_gmail_service() message = create_html_message( '*****@*****.**', email_address, f'ISS beamline results Proposal {proposal}', f' <p> Dear {PI},</p> <p>You can download the result of your experiment at ISS under proposal {proposal} here,</p> <p> {link_url} </p> <p> Sincerely, </p> <p> ISS Staff </p>' ) draft = upload_draft(gmail_service, message) sent = send_draft(gmail_service, draft) print('Email sent')
def plot_xas_data(self): selected_items = (self.list_data.selectedItems()) update_figure([self.figure_data.ax], self.toolbar, self.canvas) if self.comboBox_data_numerator.currentText() == -1 or self.comboBox_data_denominator.currentText() == -1: message_box('Warning','Please select numerator and denominator') return self.last_numerator = self.comboBox_data_numerator.currentText() self.last_denominator = self.comboBox_data_denominator.currentText() energy_key = 'energy' handles = [] for i in selected_items: path = f'{self.working_folder}/{i.text()}' print(path) df, header = load_binned_df_from_file(path) numer = np.array(df[self.comboBox_data_numerator.currentText()]) denom = np.array(df[self.comboBox_data_denominator.currentText()]) if self.checkBox_ratio.checkState(): y_label = (f'{self.comboBox_data_numerator.currentText()} / ' f'{self.comboBox_data_denominator.currentText()}') spectrum = numer/denom else: y_label = (f'{self.comboBox_data_numerator.currentText()}') spectrum = numer if self.checkBox_log_bin.checkState(): spectrum = np.log(spectrum) y_label = f'ln ({y_label})' if self.checkBox_inv_bin.checkState(): spectrum = -spectrum y_label = f'- {y_label}' self.figure_data.ax.plot(df[energy_key], spectrum) self.parent.set_figure(self.figure_data.ax,self.canvas,label_x='Energy (eV)', label_y=y_label) self.figure_data.ax.set_xlabel('Energy (eV)') self.figure_data.ax.set_ylabel(y_label) last_trace = self.figure_data.ax.get_lines()[len(self.figure_data.ax.get_lines()) - 1] patch = mpatches.Patch(color=last_trace.get_color(), label=i.text()) handles.append(patch) self.figure_data.ax.legend(handles=handles) self.figure_data.tight_layout() self.canvas.draw_idle()
def set_energy(self): energy = self.hhm.energy.read()['hhm_energy']['value'] dlg = SetEnergy.SetEnergy(round(energy), parent=self) if dlg.exec_(): try: new_energy = float(dlg.getValues()) print(new_energy) except Exception as exc: message_box('Incorrect energy', 'Energy should be numerical') if (new_energy > 4700) and (new_energy < 32000): self.plan_processor.add_plan_and_run_if_idle( 'move_mono_energy', {'energy': new_energy}) # self.plan_processor.add_execute_pause_plan_at_head('move_mono_energy', {'energy': new_energy}) # self.RE(bps.mv(self.hhm.energy, new_energy)) else: message_box('Incorrect energy', 'Energy should be within 4700-32000 eV range')
def set_emission_energy(self): energy = np.round(self.motor_emission.energy.position, 2) limits = self.motor_emission.energy.limits dlg = SetEnergy.SetEnergy(energy, parent=self) if dlg.exec_(): try: new_energy = float(dlg.getValues()) print(new_energy) except Exception as exc: message_box('Incorrect energy', 'Energy should be numerical') if (new_energy > 4700) and (new_energy < 32000): self.plan_processor.add_plan_and_run_if_idle( 'move_johann_spectrometer_energy', {'energy': new_energy}) # self.plan_processor.add_execute_pause_plan_at_head('move_johann_spectrometer_energy', {'energy': new_energy}) # self.RE(bps.mv(self.hhm.energy, new_energy)) else: message_box( 'Incorrect energy', f'Energy should be within {limits[0]}-{limits[1]} eV range' )
def add_data_to_project(self): if self.comboBox_data_numerator.currentText( ) != -1 and self.comboBox_data_denominator.currentText() != -1: for item in self.list_data.selectedItems(): filepath = str(Path(self.working_folder) / Path(item.text())) name = Path(filepath).resolve().stem df, header = load_binned_df_from_file(filepath) uid = header[header.find('UID:') + 5:header.find('\n', header.find('UID:'))] try: md = self.db[uid]['start'] except: print('Metadata not found') md = {} df = df.sort_values('energy') num_key = self.comboBox_data_numerator.currentText() den_key = self.comboBox_data_denominator.currentText() mu = df[num_key] / df[den_key] if self.checkBox_log_bin.checkState(): mu = np.log(mu) if self.checkBox_inv_bin.checkState(): mu = -mu mu = np.array(mu) ds = XASDataSet(name=name, md=md, energy=df['energy'], mu=mu, filename=filepath, datatype='experiment') ds.header = header self.parent.project.append(ds) self.parent.statusBar().showMessage( 'Scans added to the project successfully') else: message_box('Error', 'Select numerator and denominator columns')
def calibrate_offset(self): ret = question_message_box( self, 'Confirmation', 'Are you sure you would like to calibrate it?') if not ret: print('[E0 Calibration] Aborted!') return False new_value = str( self.hhm.angle_offset.value - (xray.energy2encoder(float(self.edit_E0.text( )), self.hhm.pulses_per_deg) - xray.energy2encoder( float(self.edit_ECal.text()), self.hhm.pulses_per_deg)) / self.hhm.pulses_per_deg) if self.set_new_angle_offset(new_value): return print('[E0 Calibration] New value: {}\n[E0 Calibration] Completed!'. format(new_value)) message_box( 'Reload trajectory', 'Switch to Trajectory tab and re-load and re-initialize the trajectory' )
def update_offset(self): offset = float(self.label_angle_offset.text()) energy = float(self.widget_energy_selector.edit_E0.text()) dlg = UpdateAngleOffset.UpdateAngleOffset(offset, energy, parent=self) if dlg.exec_(): try: values = dlg.getValues() if len(values) == 1: offset = values[0] self.hhm.angle_offset.put(float(offset)) self.update_angle_offset_label(value=float(dlg.getValues())) elif len(values) == 2: old_energy_str, new_energy_str = values # self.hhm.calibrate(float(old_energy_str), float(new_energy_str)) self.hhm.calibrate(float(new_energy_str), float(old_energy_str)) self.update_angle_offset_label(value=self.hhm.angle_offset.get()) message_box('Warning', 'The new calibration will be applied only to new scans.\nIf you want new calibration to apply to old scans, you will have to redefine/recreate them.') except Exception as exc: if type(exc) == ophyd_utils.errors.LimitError: print('[New offset] {}. No reason to be desperate, though.'.format(exc)) else: print('[New offset] Something went wrong, not the limit: {}'.format(exc))
def create_new_sample(self): if self.lineEdit_sample_name.text(): x = self.spinBox_sample_x.value() y = self.spinBox_sample_y.value() name = self.lineEdit_sample_name.text() comment = self.lineEdit_sample_comment.text() item = QtGui.QStandardItem(f'{name} at X {x} Y {y}') item.setDropEnabled(False) item.item_type = 'sample' item.setCheckable(True) item.setEditable(False) item.x = x item.y = y item.name = name item.comment = comment item.setIcon(icon_sample) parent = self.model_samples.invisibleRootItem() parent.appendRow(item) self.listView_samples.setModel(self.model_samples) else: message_box('Warning', 'Sample name is empty')
def create_map(self): if self.treeView_batch.model().rowCount( ) and self.treeView_batch.selectedIndexes(): parent = self.model_batch.itemFromIndex( self.treeView_batch.selectedIndexes()[0]) if (parent.item_type == 'experiment') and (self.listView_scans.model() is not None): for index in range(self.listView_scans.model().rowCount()): item_scan = self.listView_scans.model().item(index) if item_scan.checkState(): new_item_scan = self.clone_scan_item(item_scan) #calculate_map if self.radioButton_sample_map_1D.isChecked(): x_coord = np.linspace( self.spinBox_sample_x_map_start.value(), self.spinBox_sample_x_map_end.value(), self.spinBox_sample_x_map_steps.value()) y_coord = np.linspace( self.spinBox_sample_y_map_start.value(), self.spinBox_sample_y_map_end.value(), self.spinBox_sample_x_map_steps.value()) xy_coord = np.column_stack((x_coord, y_coord)) elif self.radioButton_sample_map_2D.isChecked(): x_coord = np.ndarray(0) y_coord = np.ndarray(0) y_points = np.linspace( self.spinBox_sample_y_map_start.value(), self.spinBox_sample_y_map_end.value(), self.spinBox_sample_y_map_steps.value()) if int(self.spinBox_sample_y_map_steps.value() ) == 0: message_box('Warning', 'Select nonzero number of steps ') return for i in range( int(self.spinBox_sample_y_map_steps.value( ))): x_line = np.linspace( self.spinBox_sample_x_map_start.value(), self.spinBox_sample_x_map_end.value(), self.spinBox_sample_x_map_steps.value()) y_line = np.ones(len(x_line)) * (y_points[i]) x_coord = np.append(x_coord, x_line) y_coord = np.append(y_coord, y_line) xy_coord = np.column_stack((x_coord, y_coord)) print(xy_coord) if self.lineEdit_map_name.text(): for index in range(len(xy_coord)): x = xy_coord[index, 0] y = xy_coord[index, 1] name = f'{self.lineEdit_map_name.text()} at {x:.3f} {y:.3}' item = QtGui.QStandardItem(name) new_item_scan.appendRow(item) item.setDropEnabled(False) item.item_type = 'sample' item.setEditable(False) item.x = x item.y = y item.name = name item.comment = self.lineEdit_map_comment.text() item.setIcon(icon_sample) else: message_box('Warning', 'Select nonzero number of steps ') parent.appendRow(new_item_scan) new_item_scan.setCheckable(False) new_item_scan.setEditable(False) self.treeView_batch.expand( self.model_batch.indexFromItem(parent)) for index in range(parent.rowCount()): self.treeView_batch.expand( self.model_batch.indexFromItem(parent.child(index))) self.treeView_batch.setModel(self.model_batch) else: message_box('Warning', 'Select experiment before adding map')
def create_measurement(self): if self.treeView_batch.model().rowCount(): if self.treeView_batch.selectedIndexes(): selected_index = self.treeView_batch.selectedIndexes()[0] parent = self.model_batch.itemFromIndex(selected_index) if parent.item_type == 'experiment': if self.radioButton_priority_sample.isChecked(): if self.listView_samples.model() is not None: for index in range( self.listView_samples.model().rowCount()): item_sample = self.listView_samples.model( ).item(index) if item_sample.checkState(): new_item_sample = self.clone_sample_item( item_sample) if self.listView_scans.model() is not None: scans_selected = 0 for index in range(self.listView_scans. model().rowCount()): item_scan = self.listView_scans.model( ).item(index) if item_scan.checkState(): scans_selected = 1 new_item_scan = self.clone_scan_item( item_scan) new_item_sample.appendRow( new_item_scan) new_item_scan.setCheckable( False) new_item_scan.setEditable( False) new_item_scan.setIcon( icon_scan) if scans_selected: parent.appendRow(new_item_sample) new_item_sample.setCheckable(False) new_item_sample.setEditable(False) else: if self.listView_scans.model() is not None: for index in range( self.listView_scans.model().rowCount()): item_scan = self.listView_scans.model().item( index) if item_scan.checkState(): new_item_scan = self.clone_scan_item( item_scan) print(f' Repeat {new_item_scan.repeat}') if self.listView_samples.model( ) is not None: samples_selected = 0 for index in range( self.listView_samples.model( ).rowCount()): item_sample = self.listView_samples.model( ).item(index) if item_sample.checkState(): samples_selected = 1 new_item_sample = self.clone_sample_item( item_sample) new_item_scan.appendRow( new_item_sample) new_item_scan.setCheckable( False) new_item_scan.setEditable( False) new_item_scan.setIcon( icon_scan) if samples_selected: parent.appendRow(new_item_scan) new_item_scan.setCheckable(False) new_item_scan.setEditable(False) self.treeView_batch.expand( self.model_batch.indexFromItem(parent)) for index in range(parent.rowCount()): self.treeView_batch.expand( self.model_batch.indexFromItem( parent.child(index))) self.treeView_batch.setModel(self.model_batch) else: message_box( 'Warning', 'Select experiment before adding measurements')
def run_scan(self): ignore_shutter = False energy_grid = [] time_grid = [] for shutter in [ self.shutter_dictionary[shutter] for shutter in self.shutter_dictionary if self.shutter_dictionary[shutter].shutter_type != 'SP' ]: if shutter.state.value: ret = question_message_box( self, 'Shutter closed', 'Would you like to run the scan with the shutter closed?') if not ret: print('Aborted!') return False ignore_shutter = True break # Send sampling time to the pizzaboxes: value = int( round( float(self.analog_samp_time) / self.adc_list[0].sample_rate.get() * 100000)) for adc in self.adc_list: adc.averaging_points.put(str(value)) for enc in self.enc_list: enc.filter_dt.put(float(self.enc_samp_time) * 100000) # not needed at QAS this is a detector if self.xia is not None: if self.xia.input_trigger is not None: self.xia.input_trigger.unit_sel.put(1) # ms, not us self.xia.input_trigger.period_sp.put(int(self.xia_samp_time)) name_provided = self.parameter_values[0].text() if name_provided: timenow = datetime.datetime.now() print('\nStarting scan at {}'.format(timenow.strftime("%H:%M:%S"), flush='true')) start_scan_timer = timer() # Get parameters from the widgets and organize them in a dictionary (run_params) run_parameters = return_parameters_from_widget( self.parameter_descriptions, self.parameter_values, self.parameter_types) # Run the scan using the dict created before self.run_mode_uids = [] self.parent_gui.run_mode = 'run' plan_key = self.comboBox_scan_type.currentText() if plan_key == 'Step scan': update_figure( [self.figure.ax2, self.figure.ax1, self.figure.ax3], self.toolbar, self.canvas) energy_grid, time_grid = generate_energy_grid( float(self.e0), float(self.edit_preedge_start.text()), float(self.edit_xanes_start.text()), float(self.edit_xanes_end.text()), float(self.edit_exafs_end.text()), float(self.edit_preedge_spacing.text()), float(self.edit_xanes_spacing.text()), float(self.edit_exafs_spacing.text()), float(self.edit_preedge_dwell.text()), float(self.edit_xanes_dwell.text()), float(self.edit_exafs_dwell.text()), int(self.comboBox_exafs_dwell_kpower.currentText())) #print(energy_grid) plan_func = self.plan_funcs[plan_key] LivePlots = [ XASPlot(self.apb.ch1_mean.name, self.apb.ch2_mean.name, 'Transmission', self.hhm[0].energy.name, log=True, ax=self.figure.ax1, color='b'), XASPlot(self.apb.ch2_mean.name, self.apb.ch3_mean.name, 'Reference', self.hhm[0].energy.name, log=True, ax=self.figure.ax1, color='r'), XASPlot(self.apb.ch4_mean.name, self.apb.ch1_mean.name, 'Fluorescence', self.hhm[0].energy.name, log=False, ax=self.figure.ax1, color='g'), ] print(f'Edge at execution {self.edge}') RE_args = [ plan_func(**run_parameters, ignore_shutter=ignore_shutter, energy_grid=energy_grid, time_grid=time_grid, element=self.element, e0=self.e0, edge=self.edge, ax=self.figure.ax1, stdout=self.parent_gui.emitstream_out) ] if plan_key.lower() == 'step scan': RE_args.append(LivePlots) self.run_mode_uids = self.RE(*RE_args) timenow = datetime.datetime.now() print('Scan complete at {}'.format(timenow.strftime("%H:%M:%S"))) stop_scan_timer = timer() print('Scan duration {} s'.format(stop_scan_timer - start_scan_timer)) if self.rr_token is not None: self.RE.unsubscribe(self.rr_token) else: message_box('Error', 'Please provide the name for the scan')