def delete_template_clicked(self, template_index): template_to_delete = self._templates[template_index] alignments = db.get_alignments() template_in_use = False for alignment in alignments: for library, template in alignment.library_templates.items(): if template == template_to_delete.id: template_in_use = True break if template_to_delete.reverse_complement_template_id != None: reverse_complement_template = db.get_template_by_id(\ template_to_delete.reverse_complement_template_id) for alignment in alignments: for library, template in alignment.library_templates.items(): if template == reverse_complement_template.id: template_in_use = True break if template_in_use: messagebox.showinfo("Error", "Template in use, cannot delete") else: db.delete_template(template_to_delete) self.load_templates()
def add_update_clicked(self, template): try: if template == None: template_name = self._template_edit_name.get() template_sequence = self._template_edit_sequence.get() reverse_complement_name = self._selected_reverse_complement.get() if reverse_complement_name == "(None)": reverse_complement_template_id = None else: reverse_complement_template = db.get_template_by_name(reverse_complement_name) reverse_complement_template_id = reverse_complement_template.id new_template = Template(template_sequence, template_name, \ reverse_complement_template_id = reverse_complement_template_id) else: template.name = self._template_edit_name.get() template.sequence = self._template_edit_sequence.get() reverse_complement_name = self._selected_reverse_complement.get() if reverse_complement_name == "(None)": reverse_complement_template_id = None else: reverse_complement_template = db.get_template_by_name(reverse_complement_name) reverse_complement_template_id = reverse_complement_template.id template.reverse_complement_template_id = reverse_complement_template_id except Exception as exception: messagebox.showinfo("Error", str(exception)) self._new_template_frame.destroy() self.load_templates()
def load_samples(self): if self._samples_frame != None: self._samples_frame.destroy() self._samples_frame = Frame(self._left_frame) self._samples_frame.pack() Label(self._samples_frame, text='Existing Samples')\ .pack(side=TOP) self._samples_scroll_area = self.scroll_area( self._samples_frame, height=self.winfo_toplevel().winfo_height()) self._samples = db.get_samples() self._templates = db.get_templates() self._template_options = ["(None)"] self._template_options.extend(\ [template.name for template in self._templates]) sample_header = Label(self._samples_scroll_area, text="Sample", \ bg="white", relief="solid", bd="1") sample_header.grid(row=0, column=0, sticky="news") template_header = Label(self._samples_scroll_area, text="Template", \ bg="white", relief="solid", bd="1") template_header.grid(row=0, column=1, sticky="news") for sample_index, sample in enumerate(self._samples): label = Label(self._samples_scroll_area, text=sample.name, \ bg="white", relief="solid", bd=1) label.grid(row=sample_index + 1, column=0, sticky="news") label.bind("<Button-4>", self.scroll) label.bind("<Button-5>", self.scroll) associated_template_var = StringVar() associated_template_var.set(self._template_options[0]) template_selected_command = partial(self.template_selected, \ sample_index) dropdown_frame = Frame(self._samples_scroll_area, bg="white", \ relief="solid", bd=1) dropdown_frame.grid(row = sample_index + 1, column = 1, \ sticky = "news") dropdown_frame.bind("<Button-4>", self.scroll) dropdown_frame.bind("<Button-5>", self.scroll) template_dropdown = OptionMenu(dropdown_frame, \ associated_template_var, *self._template_options, \ command=template_selected_command) template_dropdown.pack() template_dropdown.bind("<Button-4>", self.scroll) template_dropdown.bind("<Button-5>", self.scroll)
def delete_sample_clicked(self, sample_index): db.delete_sample(self._samples[sample_index]) for dropdown in self._sample_dropdowns: dropdown["menu"].delete(sample_index + 1) self._sample_labels[sample_index].destroy() self._sample_rename_buttons[sample_index].destroy() self._sample_delete_buttons[sample_index].destroy() del self._sample_labels[sample_index]
def update_lists(self): self.library_lines = [] self.alignment_lines = [] self.methods = [alignment.name for alignment in db.get_alignments()] for child in self.library_wrapper.winfo_children(): child.destroy() for child in self.alignment_wrapper.winfo_children(): child.destroy() i = 0 for library in db.get_libraries(): line = Frame(self.library_wrapper) line.id = library.id line.name = library.name line.var = StringVar() line.var.set('0') line.ch_btn = Checkbutton(line, text=line.name, variable=line.var) line.ch_btn.pack(side=LEFT, fill=BOTH) line.ch_btn['command'] = lambda index=i: \ self.add_library_to_comparison(index) btn = Button(line, text='Files') btn.bind("<Button-1>", self.view_files) btn.pack(side=RIGHT, pady=2, padx=2) line.pack(side=TOP, fill=BOTH) self.library_lines.append(line) line.bind("<Button-4>", self.scroll) line.bind("<Button-5>", self.scroll) line.ch_btn.bind("<Button-4>", self.scroll) line.ch_btn.bind("<Button-5>", self.scroll) btn.bind("<Button-4>", self.scroll) btn.bind("<Button-5>", self.scroll) i += 1 i = 0 for alignment in db.get_alignments(): line = Frame(self.alignment_wrapper) line.id = alignment.id line.name = alignment.name line.var = StringVar() line.var.set('0') line.ch_btn = Checkbutton(line, text=line.name, variable=line.var) line.ch_btn.pack(side=LEFT, fill=BOTH) line.ch_btn['command'] = \ lambda index=i: self.add_alignment_to_comparison(index) btn = Button(line, text='Parameters') btn.bind("<Button-1>", lambda e: self.view_parameters(e)) btn.pack(side=RIGHT, pady=2, padx=2) line.pack(side=TOP, fill=BOTH) self.alignment_lines.append(line) i += 1
def view_parameters(self, event): parent = event.widget.master grid_kwargs = { 'padx': 1, 'pady': 1, 'sticky': 'news', 'ipadx': 5, 'ipady': 5 } if hasattr(self, 'parameter_viewer'): self.parameter_viewer.destroy() self.parameter_viewer = Toplevel(padx=10, pady=10) self.parameter_viewer.title('Parameters for ' + parent.name) Label(self.parameter_viewer, text = 'Parameter', bg = 'white')\ .grid(row=0, column=0, **grid_kwargs) Label(self.parameter_viewer, text = 'Value', bg = 'white')\ .grid(row=0, column=1, **grid_kwargs) i = 1 for parameter, value in db.get_alignment_by_id(str(parent.id))\ .parameters.items(): Label(self.parameter_viewer, text = parameter, bg = 'white', anchor='e')\ .grid(row=i, column=0, **grid_kwargs) Label(self.parameter_viewer, text = value, bg = 'white')\ .grid(row=i, column=1, **grid_kwargs) i += 1
def sample_selected(self, FASTQ_file_index, selected_value): FASTQ_file = self._FASTQ_files[FASTQ_file_index] current_sample = db.get_associated_library(FASTQ_file.name) if current_sample != None: if current_sample.name == selected_value: return else: current_sample.remove_file(FASTQ_file.name) if selected_value == self._sample_options[0]: return new_sample = db.get_library(selected_value) new_sample.add_file(FASTQ_file.name)
def load_templates(self): self._templates = db.get_templates() if self._existing_templates_table != None: self._existing_templates_table.destroy() self._existing_templates_table = Frame(self._existing_templates_frame) self._existing_templates_table.pack() Label(self._existing_templates_table, text="Name")\ .grid(row = 0, column = 0) Label(self._existing_templates_table, text="Sequence")\ .grid(row = 0, column = 1) Label(self._existing_templates_table, text="Reverse complement")\ .grid(row = 0, column = 2) i = 1 for template in self._templates: Label(self._existing_templates_table, text=template.name, bd=1, \ relief="solid")\ .grid(row = i, column=0, sticky="news") Label(self._existing_templates_table, text=template.sequence, bd=1,\ relief="solid")\ .grid(row = i, column=1, sticky="news") if template.reverse_complement_template_id != None: reverse_complement_name = db.get_template_by_id(\ template.reverse_complement_template_id).name else: reverse_complement_name = "" Label(self._existing_templates_table, text=reverse_complement_name,\ bd=1, relief="solid")\ .grid(row = i, column=2, sticky="news") Button(self._existing_templates_table, text="Edit", \ command=lambda index=i-1: self.edit_template_clicked(index))\ .grid(row = i, column=3, sticky="news") Button(self._existing_templates_table, text="Delete", \ command=lambda index=i-1: self.delete_template_clicked(index))\ .grid(row = i, column=4, sticky="news") i += 1
def view_files(self, event): parent = event.widget.master grid_kwargs = {'padx': 1, 'pady': 1, 'sticky': 'news', 'column': 0} if hasattr(self, 'file_viewer'): self.file_viewer.destroy() self.file_viewer = Toplevel(padx=10, pady=10) self.file_viewer.title('Files in ' + str(parent.id)) Label(self.file_viewer, text = 'FASTQ file', bg='white')\ .grid(**grid_kwargs) i = 1 files = db.get_library_by_id(str(parent.id)).fastq_files for file in files: Label(self.file_viewer, text=str(file), bg='white')\ .grid(row=i, **grid_kwargs) i += 1
def load_samples(self): self._samples = db.get_samples() if self._sample_list_frame != None: self._sample_list_frame.destroy() self._sample_list_frame = Frame(self._existing_samples_frame) self._sample_list_frame.pack() self._sample_scroll_area = self.scroll_area(self._sample_list_frame, \ height=self.winfo_toplevel().winfo_height() - 200) sample_index = 0 self._sample_labels = [] self._sample_rename_buttons = [] self._sample_delete_buttons = [] for sample in self._samples: label = Label(self._sample_scroll_area, text=sample.name) label.grid(row=sample_index, column=0) rename_button = Button(self._sample_scroll_area, text="Rename", \ command=lambda index=sample_index: \ self.rename_sample_clicked(index)) rename_button.grid(row=sample_index, column=1, sticky="news") delete_button = Button(self._sample_scroll_area, text="Delete", \ command=lambda index=sample_index: \ self.delete_sample_clicked(index)) delete_button.grid(row=sample_index, column=2, sticky="news") self._sample_labels.append(label) self._sample_rename_buttons.append(rename_button) self._sample_delete_buttons.append(delete_button) sample_index += 1
def load_FASTQ_files(self): self._FASTQ_files = db.get_FASTQ_files() if self._FASTQ_list_frame != None: self._FASTQ_list_frame.destroy() self._FASTQ_list_frame = Frame(self._FASTQ_frame) self._FASTQ_list_frame.pack(fill=BOTH) self._FASTQ_scroll_area = self.scroll_area(self._FASTQ_list_frame, \ height=self.winfo_toplevel().winfo_height()) FASTQ_file_index = 0 self._sample_options = ["(None)"] self._sample_options.extend([sample.name for sample in self._samples]) self._sample_dropdowns = [] self._is_complement_vars = [] FASTQ_file_header = Label(self._FASTQ_scroll_area, text="FASTQ File", \ bg="white", relief="solid", bd="1") FASTQ_file_header.grid(row=0, column=0, sticky="news") sample_header = Label(self._FASTQ_scroll_area, text="Sample", \ bg="white", relief="solid", bd="1") sample_header.grid(row=0, column=1, sticky="news") reverse_complement_header = Label(self._FASTQ_scroll_area, \ text="Is Reverse Complement", bg="white", relief="solid", bd="1") reverse_complement_header.grid(row=0, column=2, sticky="news") for FASTQ_file_index, FASTQ_file in enumerate(self._FASTQ_files): label = Label(self._FASTQ_scroll_area, text=FASTQ_file.name, \ bg="white", relief="solid", bd="1") label.grid(row=FASTQ_file_index + 1, column=0, sticky="news") label.bind("<Button-4>", self.scroll) label.bind("<Button-5>", self.scroll) associated_sample_var = StringVar() associated_sample = db.get_associated_library(FASTQ_file.name) if associated_sample == None: associated_sample_var.set(self._sample_options[0]) else: associated_sample_var.set(associated_sample.name) sample_selected_command = partial(self.sample_selected, \ FASTQ_file_index) dropdown_frame = Frame(self._FASTQ_scroll_area, bg="white", \ relief="solid", bd="1") dropdown_frame.grid(row = FASTQ_file_index + 1, column = 1, \ sticky="news") dropdown_frame.bind("<Button-4>", self.scroll) dropdown_frame.bind("<Button-5>", self.scroll) sample_dropdown = OptionMenu(dropdown_frame, \ associated_sample_var, command=sample_selected_command, \ *self._sample_options) sample_dropdown.pack() sample_dropdown.bind("<Button-4>", self.scroll) sample_dropdown.bind("<Button-5>", self.scroll) self._sample_dropdowns.append(sample_dropdown) is_complement_var = IntVar() if FASTQ_file.is_reverse_complement: is_complement_var.set(1) else: is_complement_var.set(0) complement_checkbox_command = partial(self.complement_selected, \ FASTQ_file_index) is_complement_checkbox = Checkbutton(self._FASTQ_scroll_area, \ variable = is_complement_var, bg="white", relief="solid", \ bd="1", command=complement_checkbox_command) is_complement_checkbox.grid(row = FASTQ_file_index + 1, \ column = 2, sticky="news") is_complement_checkbox.bind("<Button-4>", self.scroll) is_complement_checkbox.bind("<Button-5>", self.scroll) self._is_complement_vars.append(is_complement_var)
def add_edit_template(self, template = None): if self._new_template_frame != None: self._new_template_frame.destroy() self._editing_template = template self._new_template_frame = Frame(self._templates_frame) self._new_template_frame.pack(side=TOP) new_template_fields_frame = Frame(self._new_template_frame) new_template_fields_frame.pack(side=TOP) Label(new_template_fields_frame, text="Name")\ .grid(row=0, column=0, sticky="e") Label(new_template_fields_frame, text="Sequence")\ .grid(row=1, column=0, sticky="e") Label(new_template_fields_frame, text="Reverse Complement Sequence")\ .grid(row=2, column=0, sticky="e") self._template_edit_name = StringVar() Entry(new_template_fields_frame, textvariable=self._template_edit_name)\ .grid(row=0, column=1, sticky="w") if template != None: self._template_edit_name.set(template.name) self._template_edit_sequence = StringVar() Entry(new_template_fields_frame, width=150, \ textvariable=self._template_edit_sequence)\ .grid(row=1, column=1, sticky="w") if template != None: self._template_edit_sequence.set(template.sequence) templates = db.get_templates() self._selected_reverse_complement = StringVar() template_names = ["(None)"] if template != None and template.reverse_complement_template_id != None: self._selected_reverse_complement.set(db.get_template_by_id(\ template.reverse_complement_template_id).name) else: self._selected_reverse_complement.set(template_names[0]) template_names.extend([template.name for template in templates]) reverse_complement_dropdown = OptionMenu(new_template_fields_frame,\ self._selected_reverse_complement, *template_names) reverse_complement_dropdown.grid(row=2, column=1, sticky="w") if template != None: done_button_text = "Update" else: done_button_text = "Add" done_close_frame = Frame(self._new_template_frame) done_close_frame.pack(side=TOP) Button(done_close_frame, text=done_button_text, command=lambda template=template: self.add_update_clicked(template))\ .grid(row=0,column=0) Button(done_close_frame, text="Cancel", command=self._new_template_frame.destroy)\ .grid(row=0,column=1)
def display_table(self): for child in self.table_frame.winfo_children(): child.destroy() libraries = self.selected_libraries[:] aligns = self.selected_alignments[:] self.columns = [] h1_font = font.Font(weight=font.BOLD) # If table is to be sorted by alignment if self.by_alignment: # Loop through alignments to create labels for i, alignment in enumerate(aligns): align_name = alignment.name index = i * (len(libraries)) + i + 1 method_label = Label(self.table_frame, text=align_name, padx=1, pady=1, bg='white', font=h1_font) method_label.grid(column=0, row=index, sticky='news', columnspan=2, pady=2, padx=2) alignment_id = alignment.id getcontext().prec = 4 # Loop through libraries for data rows in table for j, library in enumerate(libraries): name = library.name offset = index + j + 1 Label(self.table_frame, text=name, padx=1, pady=1, bg='white').grid(column=1, row=offset, sticky='news', pady=2, padx=2) library_id = library.id try: stats = db.get_alignment_by_id(alignment_id).statistics stats = stats[library_id] # Loop through statistics for to put in table for stat, value in stats.items(): # If stat has not yet been displayed, add a column if stat not in self.columns: self.columns.append(stat) col_num = len(self.columns) - 1 + 2 Label(self.table_frame, text = stat, bg='white')\ .grid(row = 0, column = col_num, sticky ='news', pady = 2, padx = 2) Grid.columnconfigure(self.table_frame, col_num, weight=1) if (int(value) != float(value) and float(value) != 0.0): value = \ str(Decimal(float(value))/Decimal(0.01)) \ + '%' k = self.columns.index(stat) label = Label(self.table_frame, text=str(value), bg='white') label.grid(row=offset, column=k + 2, pady=2, padx=2, sticky='news') label.bind('<Button-4>', lambda e: self.scroll(e)) label.bind('<Button-5>', lambda e: self.scroll(e)) except: pass # If the table is to be sorted by library else: for i, library in enumerate(libraries): lib_name = library.name index = i * (len(aligns)) + i + 1 lib_label = Label(self.table_frame, text=lib_name, padx=1, pady=1, bg='white', font=h1_font) lib_label.grid(column=0, row=index, sticky='news', columnspan=2, padx=2, pady=2) library_id = library.id for j, alignment in enumerate(aligns): name = alignment.name offset = index + j + 1 Label(self.table_frame, text=name, padx=1, pady=1, bg='white').grid(column=1, row=offset, sticky='news', pady=2, padx=2) alignment_id = alignment.id try: stats = db.get_alignment_by_id(alignment_id).statistics stats = stats[library_id] for stat, value in stats.items(): if stat not in self.columns: self.columns.append(stat) col_num = len(self.columns) - 1 + 2 Label(self.table_frame, text = stat, bg='white')\ .grid(row = 0, column = col_num, sticky ='news', pady = 2, padx = 2) Grid.columnconfigure(self.table_frame, col_num, weight=1) if (int(value) != float(value) and float(value) != 0.0): value = \ str(Decimal(float(value))/Decimal(0.01)) \ + '%' k = self.columns.index(stat) label = Label(self.table_frame, text=value, bg='white') label.grid(row=offset, column=k + 2, pady=2, padx=2, sticky='news') label.bind('<Button-4>', lambda e: self.scroll(e)) label.bind('<Button-5>', lambda e: self.scroll(e)) except: pass
def method_selected(self, selected_method_name): alignment = db.get_alignment(selected_method_name) ws.set_active_alignment(alignment)