def string_to_tuple(s): q = s.split(",") if is_number(q[0]): q = np.array([float(t) for t in q]) q_type = "TUPLE_FLOAT" return q, q_type if q[0] == "T" or q[0] == "F": q = np.array([bool(t == "T") for t in q]) q_type = "TUPLE_BOOL" return q, q_type if type(q[0]) == type("string"): q = [t.replace('"', "").replace("'", "") for t in q] q_type = "TUPLE_STRING" return q, q_type print("! ERROR: Could not parse string " + s + " into a tuple!") print( "! DEBUG_BREAKPOINT AKTIVATED - check out the following variables: string s, tuple q, first entry in tuple q[0]" ) debug_breakpoint() return None, None
def string_to_tuple(s): q = s.split(',') if is_number(q[0]): q = np.array([float(t) for t in q]) q_type = 'TUPLE_FLOAT' return q, q_type if q[0] == 'T' or q[0] == 'F': q = np.array([bool(t == 'T') for t in q]) q_type = 'TUPLE_BOOL' return q, q_type if type(q[0]) == type('string'): q = [t.replace('"', '').replace("'", '') for t in q] q_type = 'TUPLE_STRING' return q, q_type print('! ERROR: Could not parse string ' + s + ' into a tuple!') print( '! DEBUG_BREAKPOINT AKTIVATED - check out the following variables: string s, tuple q, first entry in tuple q[0]' ) debug_breakpoint() return None, None
def copy(self, path_root='.', name=False, start_optionals=False, optionals=True, quiet=True, rename_submit_script=False, OVERWRITE=False): """ This method does a copy of the simulation object by creating a new directory 'name' in 'path_root' and copy all simulation components and optiona) ls to its directory. This method neither links/compiles the simulation. If start_optionals it creates data dir. It does not overwrite anything, unless OVERWRITE is True. Submit Script Rename: Name in submit scripts will be renamed if possible! Submit scripts will be identified by submit* plus appearenace of old simulation name inside, latter will be renamed! Args: path_root: Path to new sim.-folder(sim.-name). This folder will be created if not existing! Relative paths are thought to be relative to the python current workdir name: Name of new simulation, will be used as folder name. Rename will also happen in submit script if found. Simulation folders is not allowed to preexist!! optionals: Add list of further files to be copied. Wildcasts allowed according to glob module! Set True to use self.optionals. start optionals: Add list of further files to be copied. Wildcasts allowed according to glob module! Set True to use self.optionals. quiet: Set True to suppress output. rename_submit_script: Set False if no renames shall be performed in submit* files OVERWRITE: Set True to overwrite no matter what happens! """ from glob import glob from numpy import size from os import listdir, symlink from shutil import copyfile from pencil import get_sim from pencil.io import mkdir, get_systemid, rename_in_submit_script, debug_breakpoint from pencil import is_sim_dir # set up paths if path_root == False or type(path_root) != type('string'): print('! ERROR: No path_root specified to copy the simulation to.') return False path_root = abspath(path_root) # simulation root dir # name and folder of new simulation but keep name of old if sim with old # name is NOT existing in NEW directory if name == False: name = self.name if exists(join(path_root, name)) and OVERWRITE == False: name = name + '_copy' if exists(join(path_root, name)): name = name + str( size([f for f in listdir(path_root) if f.startswith(name)])) print( '? Warning: No name specified and simulation with that name ' + 'already found! New simulation name now ' + name) path_newsim = join(path_root, name) # simulation abspath path_newsim_src = join(path_newsim, 'src') if islink(join(path_root, self.name, 'data')): link_data = True oldtmp = os.path.realpath(join(path_root, self.name, 'data')) newtmp = join(str.strip(str.strip(oldtmp, 'data'), self.name), name, 'data') if exists(newtmp) and OVERWRITE == False: raise ValueError( 'Data directory {0} already exists'.format(newtmp)) else: path_newsim_data = newtmp path_newsim_data_link = join(path_newsim, 'data') else: link_data = False path_newsim_data = join(path_newsim, 'data') path_initial_condition = join(self.path, 'initial_condition') if exists(path_initial_condition): has_initial_condition_dir = True path_newsim_initcond = join(path_newsim, 'initial_condition') else: has_initial_condition_dir = False if type(optionals) == type(['list']): optionals = self.optionals + optionals # optional files to be copied if optionals == True: optionals = self.optionals if type(optionals) == type('string'): optionals = [optionals] if type(optionals) != type(['list']): print('! ERROR: optionals must be of type list!') tmp = [] for opt in optionals: files = glob(join(self.path, opt)) for f in files: tmp.append(basename(f)) optionals = tmp # optional files to be copied if type(start_optionals) == type(['list']): start_optionals = self.start_optionals + start_optionals if start_optionals == False: start_optionals = self.start_optionals if type(start_optionals) == type('string'): start_optionals = [start_optionals] if type(start_optionals) != type(['list']): print('! ERROR: start_optionals must be of type list!') tmp = [] for opt in start_optionals: files = glob(join(self.datadir, opt)) for f in files: tmp.append(basename(f)) start_optionals = tmp ## check if the copy was already created if is_sim_dir(path_newsim) and OVERWRITE == False: if not quiet: print('? WARNING: Simulation already exists.' + ' Returning with existing simulation.') return get_sim(path_newsim, quiet=quiet) ## expand list of optionals wildcasts # check existence of path_root+name, a reason to stop and not overwrite if OVERWRITE == False and exists(path_newsim): print( '! ERROR: Folder to copy simulation to already exists!\n! -> ' + path_newsim) return False # check existance of self.components for comp in self.components: if not exists(join(self.path, comp)): print('! ERROR: Couldnt find component ' + comp + ' from simulation ' + self.name + ' at location ' + join(self.path, comp)) return False # check existance of optionals for opt in optionals: if not exists(join(self.path, opt)): print('! ERROR: Couldnt find optional component ' + opt + ' from simulation ' + self.name + ' at location ' + join(self.path, opt)) return False # check existance of self.start_components for comp in self.start_components: if not exists(join(self.datadir, comp)): print('! ERROR: Couldnt find component ' + comp + ' from simulation ' + self.name + ' at location ' + join(self.path, comp)) return False # check existance of start_optionals for opt in start_optionals: if not exists(join(self.datadir, opt)): print('! ERROR: Couldnt find optional component ' + opt + ' from simulation ' + self.name + ' at location ' + join(self.datadir, opt)) return False # create folders if mkdir(path_newsim) == False and OVERWRITE == False: print('! ERROR: Couldnt create new simulation directory ' + path_newsim + ' !!') return False if mkdir(path_newsim_src) == False and OVERWRITE == False: print('! ERROR: Couldnt create new simulation src directory ' + path_newsim_src + ' !!') return False if mkdir(path_newsim_data) == False and OVERWRITE == False: print('! ERROR: Couldnt create new simulation data directory ' + path_newsim_data + ' !!') return False if link_data: symlink(path_newsim_data, path_newsim_data_link) # copy files files_to_be_copied = [] for f in self.components + optionals: f_path = abspath(join(self.path, f)) copy_to = abspath(join(path_newsim, f)) if f_path == copy_to: print('!! ERROR: file path f_path equal to destination ' + 'copy_to. Debug this line manually!') debug_breakpoint() copyfile(f_path, copy_to) files_to_be_copied = [] for f in self.start_components + start_optionals: f_path = abspath(join(self.datadir, f)) copy_to = abspath(join(path_newsim_data, f)) if f_path == copy_to: print('!! ERROR: file path f_path equal to destination ' + 'copy_to. Debug this line manually!') debug_breakpoint() copyfile(f_path, copy_to) # Organizes any personalized initial conditions if has_initial_condition_dir: if mkdir(path_newsim_initcond) == False and OVERWRITE == False: print( '! ERROR: Couldnt create new simulation initial_condition' + ' directory ' + path_newsim_initcond + ' !!') return False for f in listdir(path_initial_condition): f_path = abspath(join(path_initial_condition, f)) copy_to = abspath(join(path_newsim_initcond, f)) if f_path == copy_to: print('!! ERROR: file path f_path equal to destination ' + 'copy_to. Debug this line manually!') debug_breakpoint() copyfile(f_path, copy_to) # modify name in submit script files if rename_submit_script != False: if type(rename_submit_script) == type('STRING'): rename_in_submit_script(new_name=rename_submit_script, sim=get_sim(path_newsim)) else: print('!! ERROR: Could not understand rename_submit_script=' + str(rename_submit_script)) # done return get_sim(path_newsim)
def get_value_from_file( filename, quantity, change_quantity_to=None, sim=False, filepath=False, DEBUG=False, silent=False, ): """Use to read in a quantity from - *.in - *.local - submit*, i.e. submit.sh, submit.csh, files, only works if computer is readily specified in pc.io.get_systemid Please add further functionallity by yourself! Args: filename: can be "run.in", "start.in", "cparam.local", path to that file is extraced from filepath or sim object quantity: variable to read in from file sim: put simulation object here, file will be found by filename automatically filepath: normally not needed, specify here where to find the file with filename, can be a list of paths if unshure DEBUG: make dry run, tell me what you would do but dont change anything! silent: suppress certain output by setting True Return: Returns None if not successful """ import os import numpy as np from os.path import join, abspath, exists, split, isfile from pencil import get_sim from pencil.math import is_number, is_float, is_int from pencil.io import timestamp, debug_breakpoint, mkdir import re import copy def string_to_tuple(s): q = s.split(",") if is_number(q[0]): q = np.array([float(t) for t in q]) q_type = "TUPLE_FLOAT" return q, q_type if q[0] == "T" or q[0] == "F": q = np.array([bool(t == "T") for t in q]) q_type = "TUPLE_BOOL" return q, q_type if type(q[0]) == type("string"): q = [t.replace('"', "").replace("'", "") for t in q] q_type = "TUPLE_STRING" return q, q_type print("! ERROR: Could not parse string " + s + " into a tuple!") print( "! DEBUG_BREAKPOINT AKTIVATED - check out the following variables: string s, tuple q, first entry in tuple q[0]" ) debug_breakpoint() return None, None def tuple_to_string(t, q_type): return ",".join([str(a) for a in t]) ######## prepare filename and quantity filename = filename.strip() # get rid of whitespaces quantity = quantity.strip() q_type = False # q_type will store the type of the quantity value once found and identified split_filename = split(filename) if sim == False and split_filename[0] != "" and filepath == False: filepath = split_filename[0] filename = split_filename[1] ######## find correct file # prepare search_path list to search filename in if filepath == False: if sim == False: sim = get_sim() else: filepath = sim.path search_paths = [ sim.path, join(sim.path, "src"), ] # add other search paths here!! elif type(filepath) == type("string"): if filepath.endswith(filename): filepath = filepath[:-len( filename )] # clean filepath if filename occures to be in there at the end search_paths = [abspath(filepath.strip())] # correct path format elif type(filepath) == type(["list"]): search_paths = filepath else: print("! ERROR: Filename " + str(filename) + " could not be interprated or found!") return None absolute_filepath = None for search_path in search_paths: tmp_path = join(search_path, filename) if os.path.isfile(tmp_path): absolute_filepath = tmp_path break # Traps the case of not being able to find the file if absolute_filepath is None: if DEBUG: print("~ DEBUG: File {0} not found in {1}!".format( filename, search_paths)) return None ######## open file # now having absolute filepath to file, lets check that file and find quantity inside! if DEBUG: print("~ DEBUG: Found file {0} in {1}".format(filename, filepath)) with open(absolute_filepath, "r") as f: data_raw = f.readlines() ######## find line in file which quantity in line_matches = [] # scan through file for differently for different files if filename.endswith( ".in") or "cparam.local" or "Makefile.local" in filename: FILE_IS = "IN_LOCAL" SYM_COMMENT = "!" SYM_ASSIGN = "=" SYM_SEPARATOR = "," for ii, line in enumerate(data_raw): if line.strip().startswith("&"): continue # filter out lines with &something, e.g. &density_run_pars quantity_match_tmp = re.search( "[^0-9a-zA-Z_]*{0}[^0-9a-zA-Z_]".format(quantity), line.split(SYM_COMMENT)[0], ) # Check if this substring occurs as a string. if quantity_match_tmp: quantity_match = quantity_match_tmp if (str.count(line[0:quantity_match.start()], "'") % 2 == 0 and str.count(line[0:quantity_match.start()], '"') % 2 == 0): if ("run" in filename or "start" in filename or ".local" in filename or "print" in filename): if ("=" in quantity_match_tmp. string[quantity_match_tmp.start() + 2:quantity_match_tmp.end()]): if line_matches: line_matches[0] = ii else: line_matches.append(ii) quantity_match = quantity_match_tmp elif filename.startswith("submit") and filename.split(".")[-1] in [ "csh", "sh" ]: FILE_IS = "SUBMIT" SYM_COMMENT = False SYM_ASSIGN = "=" SYM_SEPARATOR = "," for ii, line in enumerate(data_raw): if line.replace(" ", "").startswith("#@") and quantity in line: quantity_match_tmp = re.search( "[^0-9a-zA-Z_]*{0}[^0-9a-zA-Z_]".format(quantity), line.split(SYM_COMMENT)[0], ) if quantity_match_tmp: quantity_match = quantity_match_tmp if line_matches: line_matches[0] = ii else: line_matches.append(ii) else: print( "! ERROR: Filename unknown! No parsing possible! Please enhance this function to work with " + filename) if len(line_matches) > 1: print('! ERROR: Found more than one line with keyword "' + quantity + '" inside!') return None if len(line_matches) == 0: if silent == False: print('! ERROR: Found no line with keyword "' + quantity + '" inside ' + join(filepath, filename) + "!") return None filename = os.path.basename(filename) ######## get line with quantity inside line = data_raw[line_matches[0]] ######## do separation of quantity from rest of line, i.e. get rid of comments and other quantities defined in this line comment = "" if SYM_COMMENT: tmp = line.partition(SYM_COMMENT) # strip away comment line = tmp[0] if tmp[-1] != "": comment = SYM_COMMENT + tmp[-1] # and store for later # line = line.replace(' ','').replace('\n', '') # do cleanup in this line # Find the position where the quantity is stored. pos_equal_sign_left = quantity_match.end() + str.find( line[quantity_match.end() - 1:], "=") # pos_equal_sign_right = pos_equal_sign_left + str.find(line[pos_equal_sign_left:], ', *[0-9a-zA-Z][0-9a-zA-Z]* *= *[0-9a-zA-Z][0-9a-zA-Z]*') pos_equal_sign_right = pos_equal_sign_left + str.find( line[pos_equal_sign_left:], "=") if pos_equal_sign_right < pos_equal_sign_left: pos_equal_sign_right = -1 pos_right_comma = -1 else: pos_right_comma = str.rfind(line[:pos_equal_sign_right], ",") # Change the quantity in the line string. q = copy.copy(line[pos_equal_sign_left:pos_right_comma]) # qs = line.partition(quantity+SYM_ASSIGN) # if SYM_ASSIGN in qs[-1]: # qs = qs[:2]+qs[-1].partition(SYM_ASSIGN) # #qs = qs[:2]+qs[-1].partition(SYM_ASSIGN) # qs = qs[:2]+qs[2].rpartition(',')+qs[3:] # # qs = list(qs) # q = qs[2] while q.endswith("\t"): q = q[:-1] comment = "\t" + comment # take care of trailing tabulator while q.endswith(","): q = q[:-1] # remove trailing , ######## do a cleanup of quantity value q and convert into string, float, int or array, also remember data type of q if q.startswith("'") and q.endswith( "'"): # quantity q is string in form of 'STRING' q = q[1:-1] q_type = "STRING" elif q.startswith('"') and q.endswith( '"'): # quantity q is string in form of "STRING" q = q[1:-1] q_type = "STRING" elif not is_number( q[0]): # quantity q is string in form of not beeing a number q = q.strip().replace('"', "").replace("'", "") q_type = "STRING" try: float(q) q_type = "FLOAT" if is_int(q): q = int(q) q_type = "INT" except: if type(q) == type("string") and "," in q: q, q_type = string_to_tuple(q) # q is a TULPE_something print("q = {0}, q_type = {1}".format(q, q_type)) if type(q) == type("string") and q in ["F", "f"]: # q is BOOL q = False q_type = "BOOL" if type(q) == type("string") and q in ["T", "t"]: q = True q_type = "BOOL" if type(q) == type("string"): if is_number(q[0]): q_type = "STRING" if q_type == False: # catch if type of q was not recognized print( "! ERROR: Couldnt identify the data type of the quantity value: " + str(q)) DEBUG = True debug_breakpoint() elif DEBUG: print("~ DEBUG: q_type = " + q_type) if q_type == "FLOAT": q = float(q) elif q_type == "INT": q = int(q) ######## if value of quantity has to be changed do: if change_quantity_to != None: ####### prepare change_quantity_to for string injection if q_type == "STRING": if not FILE_IS == "SUBMIT": if type(change_quantity_to) == list: tmp = "" for a in change_quantity_to: tmp += "'" + a + "'," change_quantity_to = tmp[:-1] elif type(change_quantity_to) == int: change_quantity_to = str(change_quantity_to) else: change_quantity_to = "'" + change_quantity_to + "'" elif q_type == "BOOL": change_quantity_to = bool(change_quantity_to in ["T", "t", True]) if change_quantity_to == True: change_quantity_to = "T" elif change_quantity_to == False: change_quantity_to = "F" else: print("! ERROR: There is something deeply wrong here!" + " change_quantity_to should be bool...") debug_breakpoint() return None elif q_type == "FLOAT": if type(change_quantity_to) == str: change_quantity_to = float(change_quantity_to) change_quantity_to = "%e" % change_quantity_to elif q_type == "INT": if type(change_quantity_to) == str: change_quantity_to = int(change_quantity_to) change_quantity_to = "%i" % change_quantity_to elif q_type.startswith("TUPLE"): if q_type.endswith("BOOL"): if type(change_quantity_to) == type( ["list", "of", "bool", "or", "strings"]): for ii, val in enumerate(change_quantity_to): if val in ["T", "t", True]: change_quantity_to[ii] = "T" elif val in ["F", "f", False]: change_quantity_to[ii] = "F" else: print( "! ERROR: There is something deeply wrong here! change_quantity_to[" + str(ii) + "] should be bool or string representation, but it is " + str(change_quantity_to[ii])) debug_breakpoint() return None change_quantity_to = ",".join( [str(t) for t in change_quantity_to]) if q_type.endswith("FLOAT"): change_quantity_to = str(list(change_quantity_to))[1:-1] if q_type.endswith("STRING"): change_quantity_to = str(list(change_quantity_to))[1:-1] if DEBUG: print("~ DEBUG: Would change quantity " + quantity + " from " + str(q) + " to " + str(change_quantity_to)) q = str(change_quantity_to) ######## further formatting new_line = (line[:pos_equal_sign_left] + q + line[pos_right_comma:] + "\t" + comment ) # create new line and add comment stripped away before # new_line = ''.join(qs).replace(SYM_SEPARATOR, SYM_SEPARATOR+' ')+'\t'+comment # create new line and add comment stripped away before new_line = (new_line.rstrip() ) # clean empty spaces on the right, no one needs that... if new_line[-1] != "\n": new_line = new_line + "\n" if FILE_IS == "SUBMIT": new_line = new_line.replace("#@", "#@ ").replace( "=", " = ") # optimizing format of submit script if DEBUG: print("~ DEBUG: old line: " + str(data_raw[line_matches[0]])[:-1]) print("~ DEBUG: new line: " + str(new_line)[:-1]) if not DEBUG: ####### do backup of file before changing it if sim: from shutil import copyfile target = join(sim.path, "pc/backups/" + timestamp()) mkdir(target) target = join(target, filename) copyfile(absolute_filepath, target) # replace line in raw data data_raw[line_matches[0]] = new_line # save on drive f.close() with open(absolute_filepath, "w") as f: for l in data_raw: f.write(l) ######## DONE! return q
def gas_alpha(sim=False, t_range=[0, -1], OVERWRITE=False): """ This calculates the global alpha-value from ts object via alphah=(2./3.)*(ts3.uxuym)/(ts3.rhom*ts3.csm**2) for the lastNentries of the time series. Input: t_range use this time range of the timeseries OVERWRITE overwrite alpha file in sim.pc_datadir/alpha_<lastNentries> return: alpha dictionary """ from pencil import get_sim from pencil.sim import sim from pencil import io from os.path import exists, join import numpy as np def empirical_std_deviation(x): """ (Geschaetzte) Streuung der Messwerte x um den (unbekannten) wahren Wert (estimated) stray of the measurments x around the (unknown) true value s(x) = SQRT( 1./(M-1) * SUM( (x-<x>)**2 ) )""" import numpy as np x = np.array(x) M = np.size(x) xm = np.mean(x) #return np.sqrt(1./(M-1.)*np.sum((x-xm)**2)) return np.sqrt(M / (M - 1.) * ((1. / M * np.sum(x**2)) - xm**2)) def std_deviation_of_mean_value(x): """ Messunsicherheit des Mittelwertes <x> Empirical standarddeviation of the arithmetical mean value s(<x>) = s(x)/SQRT( M ) = SQRT( 1./(M-1) * SUM( (x-<x>)**2 ) ) / SQRT( M )""" import numpy as np x = np.array(x) M = np.size(x) if M == 1: return 0 return empirical_std_deviation(x) / np.sqrt(M) if type(sim) == sim.__Simulation__: SIM = sim else: SIM = get_sim() filename = 'alpha_' + str(t_range[0]) + '_' + str(t_range[1]) ## skip if nothing is new if not OVERWRITE and io.exists(name=filename, sim=SIM): print('~ Alpha for "' + SIM.name + '" already exists. Loading file...') return io.load(name=filename, sim=SIM) print('~ Calculating alpha for "' + SIM.name + '" in "' + SIM.path + '"') ## import time series object try: print('~ reading time series..') ts = SIM.get_ts() except: print('! ERROR: Couldnt read time series!') return False ## correct if csm quantity is not correctly exported try: csm = ts.csm if csm[0] == 0: csm = 1. except: print( '? WARNING: Couldnt find >csm< in time series, set it to csm = 1. This may be incorrect!' ) csm = 1. if t_range[1] == -1: t_range[1] = ts.t[-1] id_min = np.argmin(np.abs(ts.t - t_range[0])) id_max = np.argmin(np.abs(ts.t - t_range[1])) alpha_dict = {} ## calculate alpha print('~ calculating alpha, its mean value and standard deviation for ' + str(t_range)) alpha_dict['alpha'] = -(2. / 3.) * (ts.uxuym) / (ts.rhom * csm**2) alpha_dict['alpha_mean'] = np.mean(alpha_dict['alpha'][id_min:id_max]) alpha_dict['alpha_stddev'] = std_deviation_of_mean_value( alpha_dict['alpha'][id_min:id_max]) print('~ alpha_mean = ' + str(alpha_dict['alpha_mean']) + ' and alpha_stddev = ' + str(alpha_dict['alpha_stddev'])) ## calculate alpha minus mean_flux print( '~ calculating alpha minus mean_flux (alpha_mmf), its mean value and standard deviation' ) alpha_dict['alpha_mmf'] = -(2. / 3.) * (ts.uxuym - ts.uxm * ts.uym) / ( ts.rhom * csm**2) alpha_dict['alpha_mmf_mean'] = np.mean( alpha_dict['alpha_mmf'][id_min:id_max]) alpha_dict['alpha_mmf_stddev'] = std_deviation_of_mean_value( alpha_dict['alpha_mmf'][id_min:id_max]) print('~ alpha_mmf_mean = ' + str(alpha_dict['alpha_mmf_mean']) + ' and alpha_mmf_stddev = ' + str(alpha_dict['alpha_mmf_stddev'])) import math for v in alpha_dict.values(): if type(v) == type(1.1) and math.isnan(v): io.debug_breakpoint() ## save alpha in plk print('~ saving alpha values in ' + SIM.pc_datadir + '/' + filename) io.save(alpha_dict, filename, folder=SIM.pc_datadir) return alpha_dict
def preparePlot(x_datasets, y_datasets, x_errors=False, y_errors=False, xmin=False, xmax=False, ymin=False, ymax=False, xlog=False, ylog=False, fig=False, ax=False, PROFILE=False): import numpy as np import matplotlib import matplotlib.pyplot as plt plt.ioff() from pencil import io from pencil.visu.internal import calc_lims from pencil.visu.internal import MinorSymLogLocator ## ESTIMATE LIMITS if np.any(x_errors) and np.shape(x_errors) == np.shape(x_datasets): xlim_min = calc_lims(val_min=np.min([ np.min(array) for array in np.array(x_datasets) - np.array(x_errors) ])) xlim_max = calc_lims(val_max=np.max([ np.max(array) for array in np.array(x_datasets) + np.array(x_errors) ])) else: xlim_min = calc_lims( val_min=np.min([np.min(array) for array in x_datasets])) xlim_max = calc_lims( val_max=np.max([np.max(array) for array in x_datasets])) if np.any(y_errors) and np.shape(y_errors) == np.shape(y_datasets): ylim_min = calc_lims(val_min=np.min([ np.min(array) for array in np.array(y_datasets) - np.array(y_errors) ])) ylim_max = calc_lims(val_max=np.max([ np.max(array) for array in np.array(y_datasets) + np.array(y_errors) ])) else: ylim_min = calc_lims( val_min=np.min([np.min(array) for array in y_datasets])) ylim_max = calc_lims( val_max=np.max([np.max(array) for array in y_datasets])) if ax: xlim_max = np.max([np.max(ax.get_xlim()), xlim_max]) xlim_min = np.min([np.min(ax.get_xlim()), xlim_min]) ylim_max = np.max([np.max(ax.get_ylim()), ylim_max]) ylim_min = np.min([np.min(ax.get_ylim()), ylim_min]) #pencil.io.debug_breakpoint() if not xmin: xmin = xlim_min if not xmax: xmax = xlim_max if not ymin: ymin = ylim_min if not ymax: ymax = ylim_max ## IF LOG: ENSHURE YOU ARE COVERING AT LEAST ONE ORDER OF MAGNITUDE #pencil.io.debug_breakpoint() while ylog and ymin > 0 and np.abs( np.int(np.floor(np.log10(ymin))) - np.int(np.floor(np.log10(ymax))) ) < 1. and ymax > ymin and ymax * xmax != 0: ymin = ymin - ymin * 0.01 ymax = ymax + ymax * 0.01 ## SWAP AXIS DIRECTION IF PURE NEGATIVE VALUE PLOT if xmin < 0 and xmax < 0 and xmin < xmax: tmp = xmax xmax = xmin xmin = tmp if ymin < 0 and ymax < 0 and ymin < ymax: tmp = ymax ymax = ymin ymin = tmp ## CREATE FIG AND AX IF NEEDED if (not fig) and ( not ax): # if no fig/axis object is handed over, produce your own fig = plt.figure(figsize=PROFILE['fig_size'], facecolor=PROFILE['fig_background'] ) # produce new figure if no axis is handed over ## SHOW PLOT? if matplotlib.get_backend().startswith('Tk'): print('## Showing plot..') plt.ion() plt.show() # Remove the plot frame lines. They are unnecessary chartjunk. ax = fig.add_subplot(111) ## prepare plot: ## remove axes lines if demanded ax.spines["top"].set_visible(PROFILE['ax_lines_top']) ax.spines["bottom"].set_visible(PROFILE['ax_lines_bottom']) ax.spines["right"].set_visible(PROFILE['ax_lines_right']) ax.spines["left"].set_visible(PROFILE['ax_lines_left']) if PROFILE['ax_ticks_top']: ax.get_xaxis().tick_top() if PROFILE['ax_ticks_bottom']: ax.get_xaxis().tick_bottom() if PROFILE['ax_ticks_left']: ax.get_yaxis().tick_left() if PROFILE['ax_ticks_right']: ax.get_yaxis().tick_right() ## set axes scales if xlog and ylog: # Set x- and y-axis to log ax.set_xscale("log") ax.set_yscale("symlog", linthreshy=np.min([ ymin, np.abs(ylim_min), np.abs(ylim_max), np.min(np.abs(y_datasets)) ]) / 10.) elif (not xlog) and ylog: ax.set_yscale("symlog", linthreshy=np.min([ xmni, np.abs(ylim_min), np.abs(ylim_max), np.min(np.abs(y_datasets)) ]) / 10.) elif xlog and (not ylog): ax.set_xscale("log") else: print('!! ERROR: only log setting not defined so far! xlog=' + str(xlog) + ' and ylog=' + str(ylog)) # nothing else implemented yet! ## set fontsize for ticks plt.setp(ax.get_xticklabels(), fontsize=PROFILE['ax_tick_fontsize']) plt.setp(ax.get_yticklabels(), fontsize=PROFILE['ax_tick_fontsize']) ## set ticks for symlog if ylog: yaxis = fig.gca().yaxis yaxis.set_minor_locator(MinorSymLogLocator(1e-1)) ## ESTABLISH CALCULATED LIMITS FOR PLOT #pencil.io.debug_breakpoint() ax.set_xlim(left=xmin) ax.set_xlim(right=xmax) ax.set_ylim(bottom=ymin) ax.set_ylim(top=ymax) if ax == False: print( "!! ERROR: Created axis object is False! Starting debug_breakpoint" ) io.debug_breakpoint() return (fig, ax)