def on_er_data(self, event): if self.data_model_num == 2: if not os.path.isfile(os.path.join(self.WD, 'magic_measurements.txt')): print('-W- {} is missing'.format(os.path.join(self.WD, 'magic_measurements.txt'))) pw.simple_warning("Your working directory must have a magic_measurements.txt file to run this step. Make sure you have fully completed step 1 (import magnetometer file), by combining all imported magnetometer files into one magic_measurements file.") return False #self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder(self.WD, self, self.ErMagic_data)#,self.Data,self.Data_hierarchy) wait = wx.BusyInfo('Compiling required data, please wait...') wx.Yield() self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder(self.WD, self, self.er_magic)#,self.Data,self.Data_hierarchy) elif self.data_model_num == 3: if not os.path.isfile(os.path.join(self.WD, 'measurements.txt')): pw.simple_warning("Your working directory must have a 3.0. format measurements.txt file to run this step. Make sure you have fully completed step 1 (import magnetometer file) and ALSO converted to 3.0., if necessary), then try again.") return False wait = wx.BusyInfo('Compiling required data, please wait...') wx.Yield() self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder3(self.WD, self, self.contribution) self.ErMagic_frame.Show() self.ErMagic_frame.Center() size = wx.DisplaySize() size = (size[0] - 0.3 * size[0], size[1] - 0.3 * size[1]) # gets total available screen space - 10% self.ErMagic_frame.Raise() del wait
def make_grid_frame(self, event): """ Create a GridFrame for data type of the button that was clicked """ if self.grid_frame: print '-I- You already have a grid frame open' pw.simple_warning("You already have a grid open") return try: grid_type = event.GetButtonObj().Name[:-4] # remove '_btn' except AttributeError: grid_type = self.FindWindowById(event.Id).Name[:-4] # remove ('_btn') wait = wx.BusyInfo('Making {} grid, please wait...'.format(grid_type)) wx.Yield() # hide mainframe self.on_open_grid_frame() # make grid frame self.grid_frame = grid_frame.GridFrame(self.contribution, self.WD, grid_type, grid_type, self.panel) row_string = "" # paint validations if appropriate if self.validation_mode: if grid_type in self.validation_mode: self.grid_frame.toggle_help(None, "open") row_problems = self.failing_items[grid_type]["rows"] missing_columns = self.failing_items[grid_type]["missing_columns"] missing_groups = self.failing_items[grid_type]["missing_groups"] #all_cols = row_problems.columns #col_nums = range(len(all_cols)) #col_pos = dict(zip(all_cols, col_nums)) if len(row_problems): row_string = """Columns and rows with problem data have been highlighted in blue. Cells with problem data are highlighted according to the type of problem. Red: incorrect data For full error messages, see {}.""".format(grid_type + "_errors.txt") for row in row_problems['num']: self.grid_frame.grid.paint_invalid_row(row) mask = row_problems["num"] == row items = row_problems[mask] cols = items.dropna(how="all", axis=1).drop(["num", "issues"], axis=1) for col in cols: pre, col_name = val_up3.extract_col_name(col) col_ind = self.grid_frame.grid.col_labels.index(col_name) self.grid_frame.grid.paint_invalid_cell(row, col_ind) current_label = self.grid_frame.msg_text.GetLabel() if len(missing_columns): col_string = "You are missing the following required columns: {}\n\n".format(", ".join(missing_columns)) else: col_string = "" if len(missing_groups): group_string = "You must have at least one column from each of the following groups: {}\n\n".format(", ".join(missing_groups)) else: group_string = "" # add_text = """{}{}{}""".format(col_string, group_string, row_string) self.grid_frame.msg_text.SetLabel(add_text) #self.on_finish_change_dir(self.change_dir_dialog) self.grid_frame.do_fit(None) del wait
def __init__(self, WD=None, dmodel=None): """ Input working directory, and data model object (optional). """ wx.Frame.__init__(self, None, wx.ID_ANY, self.title, name='pmag_gui mainframe') #set icon self.icon = wx.Icon() icon_path = os.path.join(PMAGPY_DIRECTORY, 'programs', 'images', 'PmagPy.ico') if os.path.isfile(icon_path): self.icon.CopyFromBitmap(wx.Bitmap(icon_path, wx.BITMAP_TYPE_ANY)) self.SetIcon(self.icon) else: print("-I- PmagPy icon file not found -- skipping") self.data_model = dmodel self.FIRST_RUN = True self.panel = wx.Panel(self, name='pmag_gui main panel') self.InitUI() # if not specified on the command line, # make the user choose their working directory if WD: self.WD = WD else: self.get_dir() self.get_wd_data() # use realpath self.WD = os.path.realpath(self.WD) # set data model and read in data self.dir_path.SetValue(self.WD) # for use as module: self.resource_dir = os.getcwd() # set some things self.HtmlIsOpen = False self.Bind(wx.EVT_CLOSE, self.on_menu_exit) # if specified directory doesn't exist, try to make it try: if not os.path.exists(self.WD): os.mkdir(self.WD) pw.simple_warning("New directory: {}\nwill be created".format(self.WD)) except FileNotFoundError: pw.simple_warning("You have provided a directory that does not exist and cannot be created.\n Please pick a different directory.") print("-W- You have provided a directory that does not exist and cannot be created.\n Please pick a different directory.") # do menubar menubar = pmag_gui_menu.MagICMenu(self) self.SetMenuBar(menubar) self.menubar = menubar
def check_for_meas_file(self): """ Check the working directory for a measurement file. If not found, show a warning and return False. Otherwise return True. """ meas_file_name = "measurements.txt" dm = "3.0" if not os.path.isfile(os.path.join(self.WD, meas_file_name)): pw.simple_warning("Your working directory must have a {} format {} file to run this step. Make sure you have fully completed step 1 (import magnetometer file) and ALSO converted to 3.0., if necessary), then try again.\n\nIf you are trying to look at data downloaded from MagIC, you must unpack the txt file first. Some contributions do not contain measurement data, in which case you won't be able to use this function.".format(dm, meas_file_name)) return False return True
def on_add_cols(self, event): """ Show simple dialog that allows user to add a new column name """ col_labels = self.grid.col_labels dia = pw.ChooseOne(self, yes="Add single columns", no="Add groups") result1 = dia.ShowModal() if result1 == wx.ID_CANCEL: return elif result1 == wx.ID_YES: items = [col_name for col_name in self.dm.index if col_name not in col_labels] dia = pw.HeaderDialog(self, 'columns to add', items1=list(items), groups=[]) dia.Centre() result2 = dia.ShowModal() else: groups = self.dm['group'].unique() dia = pw.HeaderDialog(self, 'groups to add', items1=list(groups), groups=True) dia.Centre() result2 = dia.ShowModal() new_headers = [] if result2 == 5100: new_headers = dia.text_list # if there is nothing to add, quit if not new_headers: return if result1 == wx.ID_YES: # add individual headers errors = self.add_new_grid_headers(new_headers) else: # add header groups errors = self.add_new_header_groups(new_headers) if errors: errors_str = ', '.join(errors) pw.simple_warning('You are already using the following headers: {}\nSo they will not be added'.format(errors_str)) # problem: if widgets above the grid are too wide, # the grid does not re-size when adding columns # awkward solution (causes flashing): if self.grid.GetWindowStyle() != wx.DOUBLE_BORDER: self.grid.SetWindowStyle(wx.DOUBLE_BORDER) self.main_sizer.Fit(self) self.grid.SetWindowStyle(wx.NO_BORDER) self.Centre() self.main_sizer.Fit(self) # self.grid.changes = set(range(self.grid.GetNumberRows())) dia.Destroy()
def check_for_meas_file(self): """ Check the working directory for a measurement file. If not found, show a warning and return False. Otherwise return True. """ if self.data_model_num == 2: meas_file_name = "magic_measurements.txt" dm = "2.5" else: meas_file_name = "measurements.txt" dm = "3.0" if not os.path.isfile(os.path.join(self.WD, meas_file_name)): pw.simple_warning("Your working directory must have a {} format {} file to run this step. Make sure you have fully completed step 1 (import magnetometer file) and ALSO converted to 3.0., if necessary), then try again.\n\nIf you are trying to look at data downloaded from MagIC, you must unpack the txt file first. Some contributions do not contain measurement data, in which case you won't be able to use this function.".format(dm, meas_file_name)) return False return True
def on_er_data(self, event): if not os.path.isfile(os.path.join(self.WD, 'magic_measurements.txt')): import dialogs.pmag_widgets as pw pw.simple_warning("Your working directory must have a magic_measurements.txt file to run this step. Make sure you have fully completed step 1 (import magnetometer file), by combining all imported magnetometer files into one magic_measurements file.") return False #self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder(self.WD, self, self.ErMagic_data)#,self.Data,self.Data_hierarchy) wait = wx.BusyInfo('Compiling required data, please wait...') wx.Yield() self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder(self.WD, self, self.er_magic)#,self.Data,self.Data_hierarchy) self.ErMagic_frame.Show() self.ErMagic_frame.Center() size = wx.DisplaySize() size = (size[0] - 0.3 * size[0], size[1] - 0.3 * size[1]) # gets total available screen space - 10% self.ErMagic_frame.Raise() del wait
def make_grid_frame(self, event): """ Create a GridFrame for data type of the button that was clicked """ if self.grid_frame: print '-I- You already have a grid frame open' pw.simple_warning("You already have a grid open") return try: grid_type = event.GetButtonObj().Name[:-4] # remove '_btn' except AttributeError: grid_type = self.FindWindowById( event.Id).Name[:-4] # remove ('_btn') wait = wx.BusyInfo('Making {} grid, please wait...'.format(grid_type)) wx.Yield() # hide mainframe self.on_open_grid_frame() self.grid_frame = grid_frame.GridFrame(self.er_magic, self.WD, grid_type, grid_type, self.panel) if self.validation_mode: if grid_type in self.validation_mode: self.grid_frame.grid.paint_invalid_cells( self.warn_dict[grid_type]) #self.grid_frame.msg_boxsizer current_label = self.grid_frame.msg_text.GetLabel() add_text = """\n\nColumns and rows with problem data have been highlighted in blue. Cells with problem data are highlighted with different colors according to the type of problem. Red: missing required data Green: missing or invalid parent Blue: non-numeric data provided in a numeric field Gray: unrecognized column Purple: invalid result child Yellow: Out-of-range latitude (should be -90 - 90) or longitude (should be 0-360) Light gray: Unrecognized term in controlled vocabulary Note: It is possible to have a row highlighted that has no highlighted column. This means that you are missing information higher up in the data. For example: a specimen could be missing a site name. However, you need to fix this in the sample grid, not the specimen grid. Once each item in the data has its proper parent, validations will be correct. """ self.grid_frame.msg_text.SetLabel(add_text) #self.on_finish_change_dir(self.change_dir_dialog) del wait
def check_for_meas_file(self): """ Check the working directory for a measurement file. If not found, show a warning and return False. Otherwise return True. """ if self.data_model_num == 2: meas_file_name = "magic_measurements.txt" dm = "2.5" else: meas_file_name = "measurements.txt" dm = "3.0" if not os.path.isfile(os.path.join(self.WD, meas_file_name)): pw.simple_warning( "Your working directory must have a {} format {} file to run this step. Make sure you have fully completed step 1 (import magnetometer file) and ALSO converted to 3.0., if necessary), then try again." .format(dm, meas_file_name)) return False return True
def make_grid_frame(self, event): """ Create a GridFrame for data type of the button that was clicked """ if self.grid_frame: print('-I- You already have a grid frame open') pw.simple_warning("You already have a grid open") return try: grid_type = event.GetButtonObj().Name[:-4] # remove '_btn' except AttributeError: grid_type = self.FindWindowById(event.Id).Name[:-4] # remove ('_btn') wait = wx.BusyInfo('Making {} grid, please wait...'.format(grid_type)) wx.SafeYield() # hide mainframe self.on_open_grid_frame() self.grid_frame = grid_frame.GridFrame(self.er_magic, self.WD, grid_type, grid_type, self.panel) if self.validation_mode: if grid_type in self.validation_mode: self.grid_frame.grid.paint_invalid_cells(self.warn_dict[grid_type]) #self.grid_frame.msg_boxsizer current_label = self.grid_frame.msg_text.GetLabel() add_text = """\n\nColumns and rows with problem data have been highlighted in blue. Cells with problem data are highlighted with different colors according to the type of problem. Red: missing required data Green: missing or invalid parent Blue: non-numeric data provided in a numeric field Gray: unrecognized column Purple: invalid result child Yellow: Out-of-range latitude (should be -90 - 90) or longitude (should be 0-360) Light gray: Unrecognized term in controlled vocabulary Note: It is possible to have a row highlighted that has no highlighted column. This means that you are missing information higher up in the data. For example: a specimen could be missing a site name. However, you need to fix this in the sample grid, not the specimen grid. Once each item in the data has its proper parent, validations will be correct. """ self.grid_frame.msg_text.SetLabel(add_text) #self.on_finish_change_dir(self.change_dir_dialog) del wait
def get_dm_num(self): """ Show dialog to get user input for which data model to use, 2 or 3. Set self.data_model_num, and create 3.0 contribution or 2.5 ErMagicBuilder as needed. """ ui_dialog = demag_dialogs.user_input(self,['data_model'], parse_funcs=[float], heading="Please input prefered data model (2.5,3.0). Note: 2.5 is for legacy projects only, if you have new data OR if you want to upgrade your old data, please use 3.0.", values=[3]) # figure out where to put this res = ui_dialog.ShowModal() vals = ui_dialog.get_values() self.data_model_num = int(vals[1]['data_model']) # if self.data_model_num not in (2, 3): pw.simple_warning("Input data model not recognized, defaulting to 3") self.data_model_num = 3 self.set_dm(self.data_model_num)
def remove_col_label(self, event): """ check to see if column is required if it is not, delete it from grid """ col = event.GetCol() label = self.grid.GetColLabelValue(col) if '**' in label: label = label.strip('**') elif '^^' in label: label = label.strip('^^') if label in self.reqd_headers: pw.simple_warning("That header is required, and cannot be removed") return False else: print('That header is not required:', label) self.grid.remove_col(col) del self.contribution.tables[self.grid_type].df[label] # causes resize on each column header delete # can leave this out if we want..... self.main_sizer.Fit(self)
def on_er_data(self, event): if not os.path.isfile(os.path.join(self.WD, 'magic_measurements.txt')): import dialogs.pmag_widgets as pw pw.simple_warning( "Your working directory must have a magic_measurements.txt file to run this step. Make sure you have fully completed step 1 (import magnetometer file), by combining all imported magnetometer files into one magic_measurements file." ) return False #self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder(self.WD, self, self.ErMagic_data)#,self.Data,self.Data_hierarchy) wait = wx.BusyInfo('Compiling required data, please wait...') wx.Yield() self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder( self.WD, self, self.er_magic) #,self.Data,self.Data_hierarchy) self.ErMagic_frame.Show() self.ErMagic_frame.Center() size = wx.DisplaySize() size = (size[0] - 0.3 * size[0], size[1] - 0.3 * size[1] ) # gets total available screen space - 10% self.ErMagic_frame.Raise() del wait
def __init__(self, WD=None, DM=None, dmodel=None): """ Input working directory, data model number (2.5 or 3), and data model (optional). """ wx.Frame.__init__(self, None, wx.ID_ANY, self.title, name='pmag_gui mainframe') #set icon self.icon = wx.Icon() icon_path = os.path.join(PMAGPY_DIRECTORY, 'programs', 'images', 'PmagPy.ico') if os.path.isfile(icon_path): self.icon.CopyFromBitmap(wx.Bitmap(icon_path, wx.BITMAP_TYPE_ANY)) self.SetIcon(self.icon) else: print("-I- PmagPy icon file not found -- skipping") # if DM was provided: if DM: self.data_model_num = int(float(DM)) else: self.data_model_num = 3 # check that self.data_model is valid, otherwise default 3 if self.data_model_num not in [2, 3]: pw.simple_warning("Input data model number {} not recognized, defaulting to 3".format(str(self.data_model_num))) self.data_model_num = 3 self.data_model = dmodel self.FIRST_RUN = True self.panel = wx.Panel(self, name='pmag_gui main panel') self.InitUI() # if not specified on the command line, # make the user choose their working directory if WD: self.WD = WD else: self.get_dir() # use realpath self.WD = os.path.realpath(self.WD) # set data model and read in data self.set_dm(self.data_model_num) self.dir_path.SetValue(self.WD) # for use as module: self.resource_dir = os.getcwd() # set some things self.HtmlIsOpen = False self.Bind(wx.EVT_CLOSE, self.on_menu_exit) # if specified directory doesn't exist, try to make it try: if not os.path.exists(self.WD): os.mkdir(self.WD) pw.simple_warning("New directory: {}\nwill be created".format(self.WD)) except FileNotFoundError: pw.simple_warning("You have provided a directory that does not exist and cannot be created.\n Please pick a different directory.") print("-W- You have provided a directory that does not exist and cannot be created.\n Please pick a different directory.")
def on_btn_upload(self, event): """ Try to run upload_magic. Open validation mode if the upload file has problems. """ if not self.check_for_uncombined_files(): return outstring = "upload_magic.py" print("-I- running python script:\n %s" % (outstring)) wait = wx.BusyInfo("Please wait, working...") wx.SafeYield() success_responses = ['200', 200, '201', 201, True] if 'measurements' in self.contribution.tables: self.contribution.tables['measurements'].add_measurement_names() upload_file, val_response, dummy1, dummy2 = ipmag.upload_magic( concat=False, input_dir_path=self.WD, dir_path=self.WD) del wait if val_response == "no 3.0 files found, upload file not created": pw.simple_warning( "No 3.0 files were found in your directory, so no upload could be created!" ) return status = val_response['status'] if not status: pw.simple_warning( "Oops, something went wrong with validating on the server.\n{}\nTry again later or submit a bug report." .format(val_response['warnings'])) return validation_errors = val_response['validation'] if (not validation_errors['warnings']) and ( not validation_errors['errors']): text = "You are ready to upload!\n{} was generated in {}".format( os.path.split(upload_file)[1], self.WD) dlg = pw.ChooseOne(self, "Go to MagIC for uploading", "Not ready yet", text, "Saved") dlg.Centre() result = dlg.ShowModal() if result == wx.ID_OK: dlg.Destroy() if result == wx.ID_YES: pw.on_database_upload(None) return # there were problems, so display validation text = "There were some problems with the creation of your upload file.\nSee Terminal/message window for details" dlg = wx.MessageDialog(self, caption="Error", message=text, style=wx.OK) dlg.Centre() result = dlg.ShowModal() # TODO: get the error-y business formatted into a dict of lists of dicts from programs import magic_gui self.Disable() self.Hide() self.magic_gui_frame = magic_gui.MainFrame( self.WD, dmodel=self.data_model, title="Validations", contribution=self.contribution, errors=validation_errors['errors']) self.magic_gui_frame.Centre() self.magic_gui_frame.Show() self.magic_gui_frame.highlight_problems() # bind that button to quitting magic gui and re-enabling Pmag GUI self.magic_gui_frame.Bind(wx.EVT_BUTTON, self.on_end_validation, self.magic_gui_frame.return_btn) # do binding so that closing/quitting re-opens the main frame self.magic_gui_frame.Bind(wx.EVT_CLOSE, self.on_end_validation) # this makes it work with only the validation window open self.magic_gui_frame.Bind( wx.EVT_MENU, lambda event: self.menubar.on_quit(event, self.magic_gui_frame), self.magic_gui_frame.menubar.file_quit) # this makes it work if an additional grid is open self.Bind( wx.EVT_MENU, lambda event: self.menubar.on_quit(event, self.magic_gui_frame), self.magic_gui_frame.menubar.file_quit)
def on_okButton(self, event): meas_files = [] spec_files = [] samp_files = [] site_files = [] loc_files = [] for i in range(self.max_files): # read directory path dirpath = self.dir_paths[i].GetValue() if dirpath != "": dir_name = os.path.realpath(dirpath) #dir_name = str(dirpath.split("/")[-1]) else: continue # get location location_name = self.file_locations[i].GetValue() # get sample-specimen naming convention samp_con = str(self.naming_con_boxes[i].GetValue()) samp_chars = str(self.naming_con_char[i].GetValue()) samp_chars = samp_chars.strip('"').strip("'") if samp_con == "character delimited" and not samp_chars: pw.simple_warning( "To delimit samples by character, you must provide the delimiter, (eg. \"-\" or \"_\")!" ) return # get site-sample naming convention site_con = str(self.site_name_conventions[i].GetValue()) site_chars = str(self.site_name_chars[i].GetValue()) site_chars = site_chars.strip('"').strip("'") if site_con == "character delimited" and not site_chars: pw.simple_warning( "To delimit sites by character, you must provide the delimiter, (eg. \"-\" or \"_\")!" ) return # name output files if self.data_model_num == 2: meas_out = "magic_measurements_{}.txt".format(i) spec_out = "er_specimens_{}.txt".format(i) samp_out = "er_samples_{}.txt".format(i) site_out = "er_sites_{}.txt".format(i) loc_out = "er_locations_{}.txt".format(i) else: meas_out = "measurements_{}.txt".format(i) spec_out = "specimens_{}.txt".format(i) samp_out = "samples_{}.txt".format(i) site_out = "sites_{}.txt".format(i) loc_out = "locations_{}.txt".format(i) # do conversion convert.livdb(dir_name, self.WD, meas_out, spec_out, samp_out, site_out, loc_out, samp_con, samp_chars, site_con, site_chars, location_name) meas_files.append(meas_out) spec_files.append(spec_out) samp_files.append(samp_out) site_files.append(site_out) loc_files.append(loc_out) if self.data_model_num == 2: res = ipmag.combine_magic(meas_files, "magic_measurements.txt", 2) ipmag.combine_magic(spec_files, "er_specimens.txt", 2) else: res = ipmag.combine_magic(meas_files, "measurements.txt", 3) ipmag.combine_magic(spec_files, "specimens.txt", 3) ipmag.combine_magic(samp_files, "samples.txt", 3) ipmag.combine_magic(site_files, "sites.txt", 3) ipmag.combine_magic(loc_files, "locations.txt", 3) pmag.remove_files(meas_files) pmag.remove_files(spec_files) pmag.remove_files(samp_files) pmag.remove_files(site_files) pmag.remove_files(loc_files) if res: self.after_convert_dia() else: pw.simple_warning( "Something when wrong with one or more of your files.\nSee Terminal/Command Prompt output for more details" )
def onImport(self, event): """ Import a MagIC-format file """ if self.grid.changes: print("-W- Your changes will be overwritten...") wind = pw.ChooseOne(self, "Import file anyway", "Save grid first", "-W- Your grid has unsaved changes which will be overwritten if you import a file now...") wind.Centre() res = wind.ShowModal() # save grid first: if res == wx.ID_NO: self.onSave(None, alert=True, destroy=False) # reset self.changes self.grid.changes = set() openFileDialog = wx.FileDialog(self, "Open MagIC-format file", self.WD, "", "MagIC file|*.*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) result = openFileDialog.ShowModal() if result == wx.ID_OK: # get filename filename = openFileDialog.GetPath() # make sure the dtype is correct f = open(filename) line = f.readline() if line.startswith("tab"): delim, dtype = line.split("\t") else: delim, dtype = line.split("") f.close() dtype = dtype.strip() if (dtype != self.grid_type) and (dtype + "s" != self.grid_type): text = "You are currently editing the {} grid, but you are trying to import a {} file.\nPlease open the {} grid and then re-try this import.".format(self.grid_type, dtype, dtype) pw.simple_warning(text) return # grab old data for concatenation if self.grid_type in self.contribution.tables: old_df_container = self.contribution.tables[self.grid_type] else: old_df_container = None old_col_names = self.grid.col_labels # read in new file and update contribution df_container = nb.MagicDataFrame(filename, dmodel=self.dm, columns=old_col_names) # concatenate if possible if not isinstance(old_df_container, type(None)): df_container.df = pd.concat([old_df_container.df, df_container.df], axis=0) self.contribution.tables[df_container.dtype] = df_container self.grid_builder = GridBuilder(self.contribution, self.grid_type, self.panel, parent_type=self.parent_type, reqd_headers=self.reqd_headers) # delete old grid self.grid_box.Hide(0) self.grid_box.Remove(0) # create new, updated grid self.grid = self.grid_builder.make_grid() self.grid.InitUI() # add data to new grid self.grid_builder.add_data_to_grid(self.grid, self.grid_type) # add new grid to sizer and fit everything self.grid_box.Add(self.grid, flag=wx.ALL, border=5) self.main_sizer.Fit(self) self.Centre() # add any needed drop-down-menus self.drop_down_menu = drop_down_menus.Menus(self.grid_type, self.contribution, self.grid) # done! return
def __init__(self, WD=None, DM=None, dmodel=None): """ Input working directory, data model number (2.5 or 3), and data model (optional). """ wx.Frame.__init__(self, None, wx.ID_ANY, self.title, name='pmag_gui mainframe') #set icon self.icon = wx.Icon() icon_path = os.path.join(PMAGPY_DIRECTORY, 'programs', 'images', 'PmagPy.ico') if os.path.isfile(icon_path): self.icon.CopyFromBitmap(wx.Bitmap(icon_path, wx.BITMAP_TYPE_ANY)) self.SetIcon(self.icon) else: print("-I- PmagPy icon file not found -- skipping") # if DM was provided: if DM: self.data_model_num = int(float(DM)) # try to get DM from command line args if not DM: self.data_model_num = int(float(pmag.get_named_arg("-DM", 0))) DM = self.data_model_num # if WD was provided: if WD: self.WD = WD else: WD = pmag.get_named_arg("-WD", '') self.WD = WD self.WD = os.path.realpath(self.WD) self.data_model = dmodel self.FIRST_RUN = True self.panel = wx.Panel(self, name='pmag_gui main panel') self.InitUI() if WD and DM: self.set_dm(self.data_model_num) if WD: self.dir_path.SetValue(self.WD) # for use as module: self.resource_dir = os.getcwd() # set some things self.HtmlIsOpen = False self.Bind(wx.EVT_CLOSE, self.on_menu_exit) # if not specified on the command line, # make the user choose data model num (2 or 3) # and working directory wx.CallAfter(self.get_dm_and_wd, DM, WD) # if specified directory doesn't exist, try to make it try: if not os.path.exists(self.WD): os.mkdir(self.WD) pw.simple_warning("New directory: {}\nwill be created".format( self.WD)) except FileNotFoundError: pw.simple_warning( "You have provided a directory that does not exist and cannot be created.\n Please pick a different directory." ) print( "-W- You have provided a directory that does not exist and cannot be created.\n Please pick a different directory." )
def main(): """ NAME core_depthplot.py DESCRIPTION plots various measurements versus core_depth or age. plots data flagged as 'FS-SS-C' as discrete samples. SYNTAX core_depthplot.py [command line optins] OPTIONS -h prints help message and quits -f FILE: specify input magic_measurments format file from magi -fsum FILE: specify input LIMS database (IODP) core summary csv file -fwig FILE: specify input depth,wiggle to plot, in magic format with sample_core_depth key for depth -fsa FILE: specify input er_samples format file from magic for depth -fa FILE: specify input er_ages format file from magic for age NB: must have either -fsa OR -fa (not both) -fsp FILE sym size: specify input zeq_specimen format file from magic, sym and size NB: PCAs will have specified color, while fisher means will be white with specified color as the edgecolor -fres FILE specify input pmag_results file from magic, sym and size -LP [AF,T,ARM,IRM, X] step [in mT,C,mT,mT, mass/vol] to plot -S do not plot blanket treatment data (if this is set, you don't need the -LP) -sym SYM SIZE, symbol, size for continuous points (e.g., ro 5, bs 10, g^ 10 for red dot, blue square, green triangle), default is blue dot at 5 pt -D do not plot declination -M do not plot magnetization -log plot magnetization on a log scale -L do not connect dots with a line -I do not plot inclination -d min max [in m] depth range to plot -n normalize by weight in er_specimen table -Iex: plot the expected inc at lat - only available for results with lat info in file -ts TS amin amax: plot the GPTS for the time interval between amin and amax (numbers in Ma) TS: [ck95, gts04, gts12] -ds [mbsf,mcd] specify depth scale, mbsf default -fmt [svg, eps, pdf, png] specify output format for plot (default: svg) -sav save plot silently DEFAULTS: Measurements file: magic_measurements.txt Samples file: er_samples.txt NRM step Summary file: none """ args = sys.argv if '-h' in args: print(main.__doc__) sys.exit() dataframe = extractor.command_line_dataframe([ ['f', False, 'magic_measurements.txt'], ['fsum', False, ''], ['fwig', False, ''], ['fsa', False, ''], ['fa', False, ''], ['fsp', False, ''], ['fres', False, '' ], ['fmt', False, 'svg'], ['LP', False, ''], ['n', False, False], ['d', False, '-1 -1'], ['ts', False, ''], ['WD', False, '.'], ['L', False, True], ['S', False, True], ['D', False, True], ['I', False, True], ['M', False, True], ['log', False, 0], ['ds', False, 'sample_core_depth'], ['sym', False, 'bo 5'], ['ID', False, '.'], ['sav', False, False]]) checked_args = extractor.extract_and_check_args(args, dataframe) meas_file, sum_file, wig_file, samp_file, age_file, spc_file, res_file, fmt, meth, norm, depth, timescale, dir_path, pltLine, pltSus, pltDec, pltInc, pltMag, logit, depth_scale, symbol, input_dir, save = extractor.get_vars(['f', 'fsum', 'fwig', 'fsa', 'fa', 'fsp', 'fres', 'fmt', 'LP', 'n', 'd', 'ts', 'WD', 'L', 'S', 'D', 'I', 'M', 'log', 'ds', 'sym', 'ID', 'sav'], checked_args) # format some variables # format symbol/size try: sym, size = symbol.split() size = int(size) except: print('you should provide -sym in this format: ro 5') print('using defaults instead') sym, size = 'ro', 5 # format result file, symbol, size if res_file: try: res_file, res_sym, res_size = res_file.split() except: print('you must provide -fres in this format: -fres filename symbol size') print('could not parse {}, defaulting to using no result file'.format(res_file)) res_file, res_sym, res_size = '', '', 0 else: res_file, res_sym, res_size = '', '', 0 # format specimen file, symbol, size if spc_file: try: spc_file, spc_sym, spc_size = spc_file.split() except: print('you must provide -fsp in this format: -fsp filename symbol size') print('could not parse {}, defaulting to using no specimen file'.format(spc_file)) spc_file, spc_sym, spc_size = '', '', 0 else: spc_file, spc_sym, spc_size = '', '', 0 # format min/max depth try: dmin, dmax = depth.split() except: print('you must provide -d in this format: -d dmin dmax') print('could not parse {}, defaulting to plotting all depths'.format(depth)) dmin, dmax = -1, -1 # format timescale, min/max time if timescale: try: timescale, amin, amax = timescale.split() pltTime = True except: print('you must provide -ts in this format: -ts timescale minimum_age maximum_age') print('could not parse {}, defaulting to using no timescale'.format(timescale)) timescale, amin, amax = None, -1, -1 pltTime = False else: timescale, amin, amax = None, -1, -1 pltTime = False # format norm and wt_file if norm and not isinstance(norm, bool): wt_file = norm norm = True else: norm = False wt_file = '' # format list of protcols and step try: method, step = meth.split() except: print('To use the -LP flag you must provide both the protocol and the step in this format:\n-LP [AF,T,ARM,IRM, X] step [in mT,C,mT,mT, mass/vol] to plot') print('Defaulting to using no protocol') method, step = 'LT-NO', 0 # list of varnames #['f', 'fsum', 'fwig', 'fsa', 'fa', 'fsp', 'fres', 'fmt', 'LP', 'n', 'd', 'ts', 'WD', 'L', 'S', 'D', 'I', 'M', 'log', 'ds', 'sym' ] #meas_file, sum_file, wig_file, samp_file, age_file, spc_file, res_file, fmt, meth, norm, depth, timescale, dir_path, pltLine, pltSus, pltDec, pltInc, pltMag, logit, depth_scale, symbol fig, figname = ipmag.core_depthplot(input_dir, meas_file, spc_file, samp_file, age_file, sum_file, wt_file, depth_scale, dmin, dmax, sym, size, spc_sym, spc_size, method, step, fmt, pltDec, pltInc, pltMag, pltLine, pltSus, logit, pltTime, timescale, amin, amax, norm) if not pmagplotlib.isServer: figname = figname.replace(':', '_') if fig and save: plt.savefig(figname) return app = wx.App(redirect=False) if not fig: pw.simple_warning('No plot was able to be created with the data you provided.\nMake sure you have given all the required information and try again') return False dpi = fig.get_dpi() pixel_width = dpi * fig.get_figwidth() pixel_height = dpi * fig.get_figheight() figname = os.path.join(dir_path, figname) plot_frame = pmag_menu_dialogs.PlotFrame((int(pixel_width), int(pixel_height + 50)), fig, figname, standalone=True) app.MainLoop()
def main(): """ NAME ani_depthplot.py DESCRIPTION plots tau, V3_inc, V1_dec, P and chi versus core_depth SYNTAX ani_depthplot.py [command line optins] # or, for Anaconda users: ani_depthplot_anaconda [command line options] OPTIONS -h prints help message and quits -f FILE: specify input rmag_anisotropy format file from magic (MagIC 2 only) -fb FILE: specify input measurements format file from magic -fsa FILE: specify input sample format file from magic -fsp FILE: specify input specimen file (MagIC 3 only) -fsum FILE : specify input LIMS database (IODP) core summary csv file to print the core names, set lab to 1 -fa FILE: specify input ages format file from magic -d min max [in m] depth range to plot -ds [mcd,mbsf], specify depth scale, default is mbsf (core depth) -sav save plot without review -fmt specfiy format for figures - default is svg DEFAULTS: Anisotropy file: rmag_anisotropy.txt Bulk susceptibility file: magic_measurements.txt Samples file: er_samples.txt """ args = sys.argv if '-h' in args: print(main.__doc__) sys.exit() dataframe = extractor.command_line_dataframe( [['f', False, 'rmag_anisotropy.txt'], ['fb', False, 'magic_measurements.txt'], ['fsa', False, 'er_samples.txt'], ['fa', False, None], ['fsum', False, None], ['fmt', False, 'svg'], ['ds', False, 'mbsf'], ['d', False, '-1 -1'], ['sav', False, False], ['WD', False, '.'], ['DM', False, 3], ['fsp', False, 'specimens.txt']]) #args = sys.argv checked_args = extractor.extract_and_check_args(args, dataframe) ani_file, meas_file, samp_file, age_file, sum_file, fmt, depth_scale, depth, save_quietly, dir_path, data_model, spec_file = extractor.get_vars( [ 'f', 'fb', 'fsa', 'fa', 'fsum', 'fmt', 'ds', 'd', 'sav', 'WD', 'DM', 'fsp' ], checked_args) # format min/max depth try: dmin, dmax = depth.split() dmin, dmax = float(dmin), float(dmax) except: print('you must provide depth in this format: -d dmin dmax') print('could not parse "{}", defaulting to plotting all depths'.format( '-d ' + str(depth))) dmin, dmax = -1, -1 if depth_scale: if depth_scale not in ['age', 'mbsf', 'mcd']: print( '-W- Unrecognized option "{}" provided for depth scale.\n Options for depth scale are mbsf (meters below sea floor) or mcd (meters composite depth).\n Alternatively, if you provide an age file the depth scale will be automatically set to plot by age instead.\n Using default "mbsf"' .format(depth_scale)) depth_scale = 'sample_core_depth' if age_file: depth_scale = 'age' elif 'mbsf' in depth_scale: depth_scale = 'sample_core_depth' elif 'mcd' in depth_scale: depth_scale = 'sample_composite_depth' data_model = int(float(data_model)) # MagIC 2 if data_model == 2: fig, figname = ipmag.ani_depthplot2(ani_file, meas_file, samp_file, age_file, sum_file, fmt, dmin, dmax, depth_scale, dir_path) # MagIC 3 else: if meas_file == "magic_measurements.txt": meas_file = 'measurements.txt' if samp_file in ['er_samples.txt', 'pmag_samples.txt']: samp_file = "samples.txt" site_file = 'sites.txt' fig, figname = ipmag.ani_depthplot(spec_file, samp_file, meas_file, site_file, age_file, sum_file, fmt, dmin, dmax, depth_scale, dir_path) if save_quietly: if dir_path == '.': dir_path = os.getcwd() plt.savefig(figname) plt.clf() print('Saved file: {}'.format(figname)) return False app = wx.App(redirect=False) if not fig: pw.simple_warning( 'No plot was able to be created with the data you provided.\nMake sure you have given all the required information and try again' ) return False dpi = fig.get_dpi() pixel_width = dpi * fig.get_figwidth() pixel_height = dpi * fig.get_figheight() figname = os.path.join(dir_path, figname) plot_frame = pmag_menu_dialogs.PlotFrame( (int(pixel_width), int(pixel_height + 50)), fig, figname, standalone=True) app.MainLoop()
def make_grid_frame(self, event): """ Create a GridFrame for data type of the button that was clicked """ if self.grid_frame: print('-I- You already have a grid frame open') pw.simple_warning("You already have a grid open") return try: grid_type = event.GetButtonObj().Name[:-4] # remove '_btn' except AttributeError: grid_type = self.FindWindowById(event.Id).Name[:-4] # remove ('_btn') wait = wx.BusyInfo('Making {} grid, please wait...'.format(grid_type)) wx.Yield() # propagate site lat/lon info into locations if necessary if grid_type == 'locations' and 'sites' in self.contribution.tables: self.contribution.get_min_max_lat_lon() self.contribution.propagate_cols_up(['lithologies', 'geologic_classes'], 'locations', 'sites') # propagate lithologies/type/class information from sites to samples/specimens if grid_type in ['specimens', 'samples']: self.contribution.propagate_lithology_cols() # propagate average lat/lon info from samples table if # available in samples and missing in sites if grid_type == 'sites': self.contribution.propagate_average_up(cols=['lat', 'lon', 'height'], target_df_name='sites', source_df_name='samples') self.contribution.propagate_lithology_cols() # hide mainframe self.on_open_grid_frame() # choose appropriate size for grid if grid_type == 'measurements': huge = True else: huge = False # make grid frame self.grid_frame = grid_frame.GridFrame(self.contribution, self.WD, grid_type, grid_type, self.panel, huge=huge) row_string = "" # paint validations if appropriate if self.validation_mode: if grid_type in self.validation_mode: if grid_type == 'measurements': skip_cell_render = True else: skip_cell_render = False self.grid_frame.toggle_help(None, "open") row_problems = self.failing_items[grid_type]["rows"] missing_columns = self.failing_items[grid_type]["missing_columns"] missing_groups = self.failing_items[grid_type]["missing_groups"] #all_cols = row_problems.columns #col_nums = range(len(all_cols)) #col_pos = dict(zip(all_cols, col_nums)) if len(row_problems): row_string = "Columns and rows with problem data have been highlighted in blue.\n" if not skip_cell_render: row_string += "Cells with problem data are highlighted according to the type of problem.\nRed: incorrect data\n" row_string += "For full error messages, see {}.".format(grid_type + "_errors.txt") for row in row_problems['num']: self.grid_frame.grid.paint_invalid_row(row) mask = row_problems["num"] == row items = row_problems[mask] cols = items.dropna(how="all", axis=1).drop(["num", "issues"], axis=1) for col in cols: pre, col_name = val_up3.extract_col_name(col) col_ind = self.grid_frame.grid.col_labels.index(col_name) self.grid_frame.grid.paint_invalid_cell(row, col_ind, skip_cell=skip_cell_render) current_label = self.grid_frame.msg_text.GetLabel() if len(missing_columns): col_string = "You are missing the following required columns: {}\n\n".format(", ".join(missing_columns)) else: col_string = "" if len(missing_groups): group_string = "You must have at least one column from each of the following groups: {}\n\n".format(", ".join(missing_groups)) else: group_string = "" # add_text = """{}{}{}""".format(col_string, group_string, row_string) self.grid_frame.msg_text.SetLabel(add_text) #self.on_finish_change_dir(self.change_dir_dialog) self.grid_frame.do_fit(None) del wait
def main(): """ NAME core_depthplot.py DESCRIPTION plots various measurements versus core_depth or age. plots data flagged as 'FS-SS-C' as discrete samples. SYNTAX core_depthplot.py [command line options] # or, for Anaconda users: core_depthplot_anaconda [command line options] OPTIONS -h prints help message and quits -f FILE: specify input magic_measurments format file from magi -fsum FILE: specify input LIMS database (IODP) core summary csv file -fwig FILE: specify input depth,wiggle to plot, in magic format with sample_core_depth key for depth -fsa FILE: specify input er_samples format file from magic for depth -fa FILE: specify input er_ages format file from magic for age NB: must have either -fsa OR -fa (not both) -fsp FILE sym size: specify input zeq_specimen format file from magic, sym and size NB: PCAs will have specified color, while fisher means will be white with specified color as the edgecolor -fres FILE specify input pmag_results file from magic, sym and size -LP [AF,T,ARM,IRM, X] step [in mT,C,mT,mT, mass/vol] to plot -S do not plot blanket treatment data (if this is set, you don't need the -LP) -sym SYM SIZE, symbol, size for continuous points (e.g., ro 5, bs 10, g^ 10 for red dot, blue square, green triangle), default is blue dot at 5 pt -D do not plot declination -M do not plot magnetization -log plot magnetization on a log scale -L do not connect dots with a line -I do not plot inclination -d min max [in m] depth range to plot -n normalize by weight in er_specimen table -Iex: plot the expected inc at lat - only available for results with lat info in file -ts TS amin amax: plot the GPTS for the time interval between amin and amax (numbers in Ma) TS: [ck95, gts04, gts12] -ds [mbsf,mcd] specify depth scale, mbsf default -fmt [svg, eps, pdf, png] specify output format for plot (default: svg) -sav save plot silently DEFAULTS: Measurements file: magic_measurements.txt Samples file: er_samples.txt NRM step Summary file: none """ args = sys.argv if '-h' in args: print(main.__doc__) sys.exit() dataframe = extractor.command_line_dataframe([ ['f', False, 'magic_measurements.txt'], ['fsum', False, ''], ['fwig', False, ''], ['fsa', False, ''], ['fa', False, ''], ['fsp', False, ''], ['fres', False, '' ], ['fmt', False, 'svg'], ['LP', False, ''], ['n', False, False], ['d', False, '-1 -1'], ['ts', False, ''], ['WD', False, '.'], ['L', False, True], ['S', False, True], ['D', False, True], ['I', False, True], ['M', False, True], ['log', False, 0], ['ds', False, 'sample_core_depth'], ['sym', False, 'bo 5'], ['ID', False, '.'], ['sav', False, False], ['DM', False, 3]]) checked_args = extractor.extract_and_check_args(args, dataframe) meas_file, sum_file, wig_file, samp_file, age_file, spc_file, res_file, fmt, meth, norm, depth, timescale, dir_path, pltLine, pltSus, pltDec, pltInc, pltMag, logit, depth_scale, symbol, input_dir, save, data_model_num = extractor.get_vars( ['f', 'fsum', 'fwig', 'fsa', 'fa', 'fsp', 'fres', 'fmt', 'LP', 'n', 'd', 'ts', 'WD', 'L', 'S', 'D', 'I', 'M', 'log', 'ds', 'sym', 'ID', 'sav', 'DM'], checked_args) # format some variables # format symbol/size try: sym, size = symbol.split() size = int(size) except: print('you should provide -sym in this format: ro 5') print('using defaults instead') sym, size = 'ro', 5 # format result file, symbol, size if res_file: try: res_file, res_sym, res_size = res_file.split() except: print('you must provide -fres in this format: -fres filename symbol size') print( 'could not parse {}, defaulting to using no result file'.format(res_file)) res_file, res_sym, res_size = '', '', 0 else: res_file, res_sym, res_size = '', '', 0 # format specimen file, symbol, size if spc_file: try: spc_file, spc_sym, spc_size = spc_file.split() except: print('you must provide -fsp in this format: -fsp filename symbol size') print( 'could not parse {}, defaulting to using no specimen file'.format(spc_file)) spc_file, spc_sym, spc_size = '', '', 0 else: spc_file, spc_sym, spc_size = '', '', 0 # format min/max depth try: dmin, dmax = depth.split() except: print('you must provide -d in this format: -d dmin dmax') print('could not parse {}, defaulting to plotting all depths'.format(depth)) dmin, dmax = -1, -1 # format timescale, min/max time if timescale: try: timescale, amin, amax = timescale.split() pltTime = True except: print( 'you must provide -ts in this format: -ts timescale minimum_age maximum_age') print( 'could not parse {}, defaulting to using no timescale'.format(timescale)) timescale, amin, amax = None, -1, -1 pltTime = False else: timescale, amin, amax = None, -1, -1 pltTime = False # format norm and wt_file if norm and not isinstance(norm, bool): wt_file = norm norm = True else: norm = False wt_file = '' # format list of protcols and step try: method, step = meth.split() except: print( 'To use the -LP flag you must provide both the protocol and the step in this format:\n-LP [AF,T,ARM,IRM, X] step [in mT,C,mT,mT, mass/vol] to plot') print('Defaulting to using no protocol') method, step = 'LT-NO', 0 # list of varnames #['f', 'fsum', 'fwig', 'fsa', 'fa', 'fsp', 'fres', 'fmt', 'LP', 'n', 'd', 'ts', 'WD', 'L', 'S', 'D', 'I', 'M', 'log', 'ds', 'sym' ] #meas_file, sum_file, wig_file, samp_file, age_file, spc_file, res_file, fmt, meth, norm, depth, timescale, dir_path, pltLine, pltSus, pltDec, pltInc, pltMag, logit, depth_scale, symbol fig, figname = ipmag.core_depthplot(input_dir, meas_file, spc_file, samp_file, age_file, sum_file, wt_file, depth_scale, dmin, dmax, sym, size, spc_sym, spc_size, method, step, fmt, pltDec, pltInc, pltMag, pltLine, pltSus, logit, pltTime, timescale, amin, amax, norm, data_model_num) if not pmagplotlib.isServer: figname = figname.replace(':', '_') if fig and save: print('-I- Created plot: {}'.format(figname)) plt.savefig(figname) return app = wx.App(redirect=False) if not fig: pw.simple_warning( 'No plot was able to be created with the data you provided.\nMake sure you have given all the required information and try again') return False dpi = fig.get_dpi() pixel_width = dpi * fig.get_figwidth() pixel_height = dpi * fig.get_figheight() figname = os.path.join(dir_path, figname) plot_frame = pmag_menu_dialogs.PlotFrame((int(pixel_width), int(pixel_height + 50)), fig, figname, standalone=True) app.MainLoop()
def main(): """ NAME ani_depthplot.py DESCRIPTION plots tau, V3_inc, V1_dec, P and chi versus core_depth SYNTAX ani_depthplot.py [command line optins] # or, for Anaconda users: ani_depthplot_anaconda [command line options] OPTIONS -h prints help message and quits -f FILE: specify input rmag_anisotropy format file from magic (MagIC 2 only) -fb FILE: specify input measurements format file from magic -fsa FILE: specify input sample format file from magic -fsp FILE: specify input specimen file (MagIC 3 only) -fsum FILE : specify input LIMS database (IODP) core summary csv file to print the core names, set lab to 1 -fa FILE: specify input ages format file from magic -d min max [in m] depth range to plot -ds [mcd,mbsf], specify depth scale, default is mbsf (core depth) -sav save plot without review -fmt specfiy format for figures - default is svg DEFAULTS: Anisotropy file: specimens.txt Bulk susceptibility file: measurements.txt Samples file: samples.txt """ args = sys.argv if '-h' in args: print(main.__doc__) sys.exit() dataframe = extractor.command_line_dataframe([['f', False, 'rmag_anisotropy.txt'], ['fb', False, 'magic_measurements.txt'], ['fsa', False, 'er_samples.txt'], ['fa', False, None], ['fsum', False, None], ['fmt', False, 'svg'], ['ds', False, 'mbsf'], ['d', False, '-1 -1'], ['sav', False, False], ['WD', False, '.' ], ['DM', False, 3], ['fsp', False, 'specimens.txt']]) #args = sys.argv checked_args = extractor.extract_and_check_args(args, dataframe) ani_file, meas_file, samp_file, age_file, sum_file, fmt, depth_scale, depth, save_quietly, dir_path, data_model, spec_file = extractor.get_vars(['f', 'fb', 'fsa', 'fa', 'fsum', 'fmt', 'ds', 'd', 'sav', 'WD', 'DM', 'fsp'], checked_args) # format min/max depth try: dmin, dmax = depth.split() dmin, dmax = float(dmin), float(dmax) except: print('you must provide depth in this format: -d dmin dmax') print('could not parse "{}", defaulting to plotting all depths'.format('-d ' + str(depth))) dmin, dmax = -1, -1 if depth_scale: if depth_scale not in ['age', 'mbsf', 'mcd']: print('-W- Unrecognized option "{}" provided for depth scale.\n Options for depth scale are mbsf (meters below sea floor) or mcd (meters composite depth).\n Alternatively, if you provide an age file the depth scale will be automatically set to plot by age instead.\n Using default "mbsf"'.format(depth_scale)) depth_scale = 'sample_core_depth' if age_file: depth_scale = 'age' elif 'mbsf' in depth_scale: depth_scale = 'sample_core_depth' elif 'mcd' in depth_scale: depth_scale = 'sample_composite_depth' data_model = int(float(data_model)) # MagIC 2 if data_model == 2: fig, figname = ipmag.ani_depthplot2(ani_file, meas_file, samp_file, age_file, sum_file, fmt, dmin, dmax, depth_scale, dir_path) # MagIC 3 else: if meas_file == "magic_measurements.txt": meas_file = 'measurements.txt' if samp_file in ['er_samples.txt', 'pmag_samples.txt']: samp_file = "samples.txt" site_file = 'sites.txt' fig, fignames = ipmag.ani_depthplot(spec_file, samp_file, meas_file, site_file, age_file, sum_file, fmt, dmin, dmax, depth_scale, dir_path) figname = fignames[0] if save_quietly: if dir_path == '.': dir_path = os.getcwd() plt.savefig(figname) plt.clf() print('Saved file: {}'.format(figname)) return False app = wx.App(redirect=False) if not fig: pw.simple_warning('No plot was able to be created with the data you provided.\nMake sure you have given all the required information and try again') return False dpi = fig.get_dpi() pixel_width = dpi * fig.get_figwidth() pixel_height = dpi * fig.get_figheight() figname = os.path.join(dir_path, figname) plot_frame = pmag_menu_dialogs.PlotFrame((int(pixel_width), int(pixel_height + 50)), fig, figname, standalone=True) app.MainLoop()
def make_grid_frame(self, event): """ Create a GridFrame for data type of the button that was clicked """ if self.grid_frame: print('-I- You already have a grid frame open') pw.simple_warning("You already have a grid open") return try: grid_type = event.GetButtonObj().Name[:-4] # remove '_btn' except AttributeError: grid_type = self.FindWindowById( event.Id).Name[:-4] # remove ('_btn') wait = wx.BusyInfo('Making {} grid, please wait...'.format(grid_type)) wx.Yield() # propagate site lat/lon info into locations if necessary if grid_type == 'locations' and 'sites' in self.contribution.tables: self.contribution.get_min_max_lat_lon() self.contribution.propagate_cols_up( ['lithologies', 'geologic_classes'], 'locations', 'sites') # propagate lithologies/type/class information from sites to samples/specimens if grid_type in ['specimens', 'samples']: self.contribution.propagate_lithology_cols() # propagate average lat/lon info from samples table if # available in samples and missing in sites if grid_type == 'sites': self.contribution.propagate_average_up( cols=['lat', 'lon', 'height'], target_df_name='sites', source_df_name='samples') self.contribution.propagate_lithology_cols() # hide mainframe self.on_open_grid_frame() # choose appropriate size for grid if grid_type == 'measurements': huge = True else: huge = False # make grid frame self.grid_frame = grid_frame.GridFrame(self.contribution, self.WD, grid_type, grid_type, self.panel, huge=huge) row_string = "" # paint validations if appropriate if self.validation_mode: if grid_type in self.validation_mode: if grid_type == 'measurements': skip_cell_render = True else: skip_cell_render = False self.grid_frame.toggle_help(None, "open") row_problems = self.failing_items[grid_type]["rows"] missing_columns = self.failing_items[grid_type][ "missing_columns"] missing_groups = self.failing_items[grid_type][ "missing_groups"] #all_cols = row_problems.columns #col_nums = range(len(all_cols)) #col_pos = dict(zip(all_cols, col_nums)) if len(row_problems): row_string = "Columns and rows with problem data have been highlighted in blue.\n" if not skip_cell_render: row_string += "Cells with problem data are highlighted according to the type of problem.\nRed: incorrect data\n" row_string += "For full error messages, see {}.".format( grid_type + "_errors.txt") for row in row_problems['num']: self.grid_frame.grid.paint_invalid_row(row) mask = row_problems["num"] == row items = row_problems[mask] cols = items.dropna(how="all", axis=1).drop(["num", "issues"], axis=1) for col in cols: pre, col_name = val_up3.extract_col_name(col) col_ind = self.grid_frame.grid.col_labels.index( col_name) self.grid_frame.grid.paint_invalid_cell( row, col_ind, skip_cell=skip_cell_render) current_label = self.grid_frame.msg_text.GetLabel() if len(missing_columns): col_string = "You are missing the following required columns: {}\n\n".format( ", ".join(missing_columns)) else: col_string = "" if len(missing_groups): group_string = "You must have at least one column from each of the following groups: {}\n\n".format( ", ".join(missing_groups)) else: group_string = "" # add_text = """{}{}{}""".format(col_string, group_string, row_string) self.grid_frame.msg_text.SetLabel(add_text) #self.on_finish_change_dir(self.change_dir_dialog) self.grid_frame.do_fit(None) del wait
def on_okButton(self, event): meas_files = [] spec_files = [] samp_files = [] site_files = [] loc_files = [] for i in range(self.max_files): # read directory path dirpath = self.dir_paths[i].GetValue() if dirpath != "": dir_name = os.path.realpath(dirpath) #dir_name = str(dirpath.split("/")[-1]) else: continue # get location location_name = self.file_locations[i].GetValue() # get sample-specimen naming convention samp_con = str(self.naming_con_boxes[i].GetValue()) samp_chars = str(self.naming_con_char[i].GetValue()) samp_chars = samp_chars.strip('"').strip("'") if samp_con == "character delimited" and not samp_chars: pw.simple_warning("To delimit samples by character, you must provide the delimiter, (eg. \"-\" or \"_\")!") return # get site-sample naming convention site_con = str(self.site_name_conventions[i].GetValue()) site_chars = str(self.site_name_chars[i].GetValue()) site_chars = site_chars.strip('"').strip("'") if site_con == "character delimited" and not site_chars: pw.simple_warning("To delimit sites by character, you must provide the delimiter, (eg. \"-\" or \"_\")!") return # name output files if self.data_model_num == 2: meas_out = "magic_measurements_{}.txt".format(i) spec_out = "er_specimens_{}.txt".format(i) samp_out = "er_samples_{}.txt".format(i) site_out = "er_sites_{}.txt".format(i) loc_out = "er_locations_{}.txt".format(i) else: meas_out = "measurements_{}.txt".format(i) spec_out = "specimens_{}.txt".format(i) samp_out = "samples_{}.txt".format(i) site_out = "sites_{}.txt".format(i) loc_out = "locations_{}.txt".format(i) # do conversion convert.livdb(dir_name, self.WD, meas_out, spec_out, samp_out, site_out, loc_out, samp_con, samp_chars, site_con, site_chars, location_name) meas_files.append(meas_out) spec_files.append(spec_out) samp_files.append(samp_out) site_files.append(site_out) loc_files.append(loc_out) if self.data_model_num == 2: res = ipmag.combine_magic(meas_files, "magic_measurements.txt", 2) ipmag.combine_magic(spec_files, "er_specimens.txt", 2) else: res = ipmag.combine_magic(meas_files, "measurements.txt", 3) ipmag.combine_magic(spec_files, "specimens.txt", 3) ipmag.combine_magic(samp_files, "samples.txt", 3) ipmag.combine_magic(site_files, "sites.txt", 3) ipmag.combine_magic(loc_files, "locations.txt", 3) pmag.remove_files(meas_files) pmag.remove_files(spec_files) pmag.remove_files(samp_files) pmag.remove_files(site_files) pmag.remove_files(loc_files) if res: self.after_convert_dia() else: pw.simple_warning("Something when wrong with one or more of your files.\nSee Terminal/Command Prompt output for more details")