def adjust_to_unit (quant, unit=None): """ calculates value and error of quantity according to specified unit Args: - quant: Quantity object to use - unit: Unit object to adjust values to. If not specified, prefer_unit of quantity will be used. If prefer_unit is None, Unit will be found automatically. Returns: tuple of adjusted value, error and unit """ if unit is None: unit = quant.prefer_unit factor, unit = convert_to_unit(quant.dim, unit) factor = np.float_(factor) value = None if quant.value is None else quant.value / factor error = None if quant.error is None else quant.error / factor return (value, error, unit)
def plot(expr_pairs, config, save=None, xunit=None, yunit=None, xrange=None, yrange=None, ignore_dim=False): # TODO it should be possible to e.g. plot the function [t,2*r] if r depends on t # one or multiple things to plot if len(expr_pairs) > 1: single_plot = False else: single_plot = True x_dim = None y_dim = None data_sets = [] functions = [] if ignore_dim: xunit = S.One yunit = S.One for expr_pair in expr_pairs: x = expr_pair[0] y = expr_pair[1] if not ignore_dim: # check dimensions if x_dim is None: x_dim = get_dimension(x) else: if not x_dim == get_dimension(x): raise RuntimeError("dimension mismatch\n%s != %s" % (x_dim, get_dimension(x))) if y_dim is None: y_dim = get_dimension(y) else: if not y_dim == get_dimension(y): raise RuntimeError("dimension mismatch\n%s != %s" % (y_dim, get_dimension(y))) # if y contains x, it must be a function dummy = Quantity() rep_y = y.subs(x,dummy) if rep_y.has(dummy): # get titles if isinstance(x, Quantity): x_title = ((x.longname + " ") if x.longname else "") + str(x) else: x_title = str(x) y_title = str(y) # check if x not only quantity but more complicated expression if not isinstance(x,Quantity): # replace by Dummy y = rep_y x = dummy if not ignore_dim: # get factors x_factor, xunit = convert_to_unit(x_dim, outputUnit=xunit) y_factor, yunit = convert_to_unit(y_dim, outputUnit=yunit) # scale function to units y = y.subs(x,x*x_factor) / y_factor # if only one thing on plot, write labels to x-axis and y-axis if single_plot: title = None x_label = x_title + ("" if xunit == S.One else " [" + str(xunit) + "]") y_label = y_title + ("" if yunit == S.One else " [" + str(yunit) + "]") # if more than one thing, use legend for title else: title = y_title functions.append({"x":x,"term":y,"title":title}) # if y doesn't contain x, it must be a data set else: # calculate expressions first if necessary if isinstance(expr_pair[0], Quantity): x = expr_pair[0] x_title = ((x.longname + " ") if x.longname else "") + str(x) else: # dummy quantity for calculation x = Quantity() x.value = get_value(expr_pair[0]) x.error = get_error(expr_pair[0])[0] x.dim = x_dim x_title = str(expr_pair[0]) if isinstance(expr_pair[1], Quantity): y = expr_pair[1] y_title = ((y.longname + " ") if y.longname else "") + str(y) else: # dummy quantity for calculation y = Quantity() y.value = get_value(expr_pair[1]) y.error = get_error(expr_pair[1])[0] y.dim = y_dim y_title = str(expr_pair[1]) if ignore_dim: x_values = x.value x_errors = x.error y_values = y.value y_errors = y.error else: # get values and errors all in one unit x_values, x_errors, xunit = adjust_to_unit(x, unit = xunit) y_values, y_errors, yunit = adjust_to_unit(y, unit = yunit) # if only one thing on plot, write labels to x-axis and y-axis if single_plot: title = None x_label = x_title + ("" if xunit == S.One else " [" + str(xunit) + "]") y_label = y_title + ("" if yunit == S.One else " [" + str(yunit) + "]") # if more than one thing, use legend for title else: title = y_title data_sets.append({"x_values": x_values, "y_values": y_values, "x_errors": x_errors, "y_errors":y_errors, "title": title}) # if more than one thing on plot, write only units to axes if not single_plot: x_label = ("" if xunit == S.One else "[" + str(xunit) + "]") y_label = ("" if yunit == S.One else "[" + str(yunit) + "]") # plot if config["plot_module"] == "matplotlib": from errorpro import plot_mat return plot_mat.plot(data_sets, functions, save=save, xrange=xrange, yrange=yrange, x_label=x_label, y_label=y_label) elif config["plot_module"] == "gnuplot": from errorpro import plot_gnu return plot_gnu.plot(data_sets, functions, save=save, xrange=xrange, yrange=yrange, x_label=x_label, y_label=y_label) else: raise ValueError("There is not plot module called '%s'" % config["plot_module"])
def test_convert_to_unit_with_output_unit(self): dim = Dimension(mass=1, length=1, time=-2) factor, unit = units.convert_to_unit(dim, output_unit="g*m/s**2") self.assertEqual(factor, 1e-3) self.assertEqual(str(unit), "g*m/s**2")
def test_convert_to_unit_with_only_base(self): dim = Dimension(mass=1, length=1, time=-2) factor, unit = units.convert_to_unit(dim, only_base=True) self.assertEqual(factor, 1) self.assertEqual(str(unit), "kg*m/s**2")
def test_convert_to_unit(self): dim = Dimension(mass=1, length=1, time=-2) factor, unit = units.convert_to_unit(dim) self.assertEqual(factor, 1) self.assertEqual(str(unit), "N")
def test_convert_to_unit_with_output_unit(self): dim=Dimension(mass=1,length=1,time=-2) factor, unit = units.convert_to_unit(dim,output_unit="g*m/s**2") self.assertEqual(factor,1e-3) self.assertEqual(str(unit),"g*m/s**2")
def test_convert_to_unit_with_only_base(self): dim=Dimension(mass=1,length=1,time=-2) factor, unit = units.convert_to_unit(dim,only_base=True) self.assertEqual(factor,1) self.assertEqual(str(unit),"kg*m/s**2")
def test_convert_to_unit(self): dim=Dimension(mass=1,length=1,time=-2) factor, unit = units.convert_to_unit(dim) self.assertEqual(factor,1) self.assertEqual(str(unit),"N")
def plot(expr_pairs, config, save=None, xunit=None, yunit=None, xrange=None, yrange=None, ignore_dim=False): # TODO it should be possible to e.g. plot the function [t,2*r] if r depends on t # one or multiple things to plot if len(expr_pairs) > 1: single_plot = False else: single_plot = True x_dim = None y_dim = None data_sets = [] functions = [] if ignore_dim: xunit = S.One yunit = S.One for expr_pair in expr_pairs: x = expr_pair[0] y = expr_pair[1] if not ignore_dim: # check dimensions if x_dim is None: x_dim = get_dimension(x) else: if not x_dim == get_dimension(x): raise RuntimeError("dimension mismatch\n%s != %s" % (x_dim, get_dimension(x))) if y_dim is None: y_dim = get_dimension(y) else: if not y_dim == get_dimension(y): raise RuntimeError("dimension mismatch\n%s != %s" % (y_dim, get_dimension(y))) # if y contains x, it must be a function dummy = Quantity() rep_y = y.subs(x, dummy) if rep_y.has(dummy): # get titles if isinstance(x, Quantity): x_title = ((x.longname + " ") if x.longname else "") + str(x) else: x_title = str(x) y_title = str(y) # check if x not only quantity but more complicated expression if not isinstance(x, Quantity): # replace by Dummy y = rep_y x = dummy if not ignore_dim: # get factors x_factor, xunit = convert_to_unit(x_dim, outputUnit=xunit) y_factor, yunit = convert_to_unit(y_dim, outputUnit=yunit) # scale function to units y = y.subs(x, x * x_factor) / y_factor # if only one thing on plot, write labels to x-axis and y-axis if single_plot: title = None x_label = x_title + ("" if xunit == S.One else " [" + str(xunit) + "]") y_label = y_title + ("" if yunit == S.One else " [" + str(yunit) + "]") # if more than one thing, use legend for title else: title = y_title functions.append({"x": x, "term": y, "title": title}) # if y doesn't contain x, it must be a data set else: # calculate expressions first if necessary if isinstance(expr_pair[0], Quantity): x = expr_pair[0] x_title = ((x.longname + " ") if x.longname else "") + str(x) else: # dummy quantity for calculation x = Quantity() x.value = get_value(expr_pair[0]) x.error = get_error(expr_pair[0])[0] x.dim = x_dim x_title = str(expr_pair[0]) if isinstance(expr_pair[1], Quantity): y = expr_pair[1] y_title = ((y.longname + " ") if y.longname else "") + str(y) else: # dummy quantity for calculation y = Quantity() y.value = get_value(expr_pair[1]) y.error = get_error(expr_pair[1])[0] y.dim = y_dim y_title = str(expr_pair[1]) if ignore_dim: x_values = x.value x_errors = x.error y_values = y.value y_errors = y.error else: # get values and errors all in one unit x_values, x_errors, xunit = adjust_to_unit(x, unit=xunit) y_values, y_errors, yunit = adjust_to_unit(y, unit=yunit) # if only one thing on plot, write labels to x-axis and y-axis if single_plot: title = None x_label = x_title + ("" if xunit == S.One else " [" + str(xunit) + "]") y_label = y_title + ("" if yunit == S.One else " [" + str(yunit) + "]") # if more than one thing, use legend for title else: title = y_title data_sets.append({ "x_values": x_values, "y_values": y_values, "x_errors": x_errors, "y_errors": y_errors, "title": title }) # if more than one thing on plot, write only units to axes if not single_plot: x_label = ("" if xunit == S.One else "[" + str(xunit) + "]") y_label = ("" if yunit == S.One else "[" + str(yunit) + "]") # plot if config["plot_module"] == "matplotlib": from errorpro import plot_mat return plot_mat.plot(data_sets, functions, save=save, xrange=xrange, yrange=yrange, x_label=x_label, y_label=y_label) elif config["plot_module"] == "gnuplot": from errorpro import plot_gnu return plot_gnu.plot(data_sets, functions, save=save, xrange=xrange, yrange=yrange, x_label=x_label, y_label=y_label) else: raise ValueError("There is not plot module called '%s'" % config["plot_module"])