File indexing completed on 2024-05-19 04:32:49

0001 import sys
0002 #import math
0003 #import ctypes
0004 import atexit
0005 import os
0006 import tempfile
0007 import time
0008 import subprocess
0009 import getpass
0010 from ast import literal_eval
0011 
0012 import numpy as np
0013 
0014 try:
0015     from PySide import QtNetwork, QtGui
0016 except ImportError as err1:
0017     try:
0018         from PyQt4 import QtNetwork, QtGui
0019     except ImportError as err2:
0020         raise ImportError("{} and {}. One of the two is required.".format(err1, err2))
0021 
0022 QtGui.QApplication([""])
0023 
0024 
0025 def clean_tmp_file(tmp_file):
0026     os.remove(tmp_file.name)
0027 
0028 def b2str(val):
0029     if isinstance(val, bool):
0030         return "True" if val else "False"
0031     return str(val)
0032 
0033 
0034 class Client(object):
0035     """ An interface to a running kst session.
0036 
0037     A client provides a connection to a running kst session.
0038 
0039     The constructor creates a connection to either a running
0040     kst session with name <server_name>, or if none exists, a new one.
0041 
0042     If <server_name> is not specified (the default), it creates a connection with an
0043     unnamed kst session, or if none exists, a new unnamed session.
0044 
0045     The Client provides functions which effect the entire kst session,
0046     provides convenience functions to create objects within kst (eg,
0047     ``client.new_generated_vector(0, 1, 6)``), and provides
0048     convenience functions to access objects already within kst (eg,
0049     ``client.vector("V2")``.  This is the suggested method.
0050 
0051     Alternatively, the constructor for every class inside pykst accepts
0052     an instance of Client which it uses to interact with a kst session.
0053 
0054     To connect to a kst session named ``kstSession`` (starting kst if necessary)::
0055 
0056         import pykst as kst
0057         client = kst.Client("kstSession")
0058 
0059     """
0060 
0061     def __init__(self, server_name=""):
0062 
0063         user_name = getpass.getuser()
0064 
0065         if server_name:
0066             self.server_name = server_name + "--" + user_name
0067         else:
0068             self.server_name = user_name
0069 
0070         self.local_socket = QtNetwork.QLocalSocket()
0071         self.local_socket.connectToServer(self.server_name)
0072         self.local_socket.waitForConnected(300)
0073 
0074         if self.local_socket.state() == QtNetwork.QLocalSocket.UnconnectedState:
0075             subprocess.Popen(["kst2", "--serverName="+str(self.server_name)])
0076             time.sleep(.5)
0077 
0078             while self.local_socket.state() == QtNetwork.QLocalSocket.UnconnectedState:
0079                 self.local_socket.connectToServer(self.server_name)
0080                 self.local_socket.waitForConnected(300)
0081 
0082     def send(self, command):
0083         """ Sends a command to kst and returns a response.
0084 
0085         You should never use
0086         this directly, as there is no guarantee that the internal command
0087         list kst uses won't change. Instead use the convenience classes
0088         included with pykst.
0089         """
0090         self.local_socket.write(command)
0091         self.local_socket.flush()
0092         self.local_socket.waitForReadyRead(300000)
0093         return_message = self.local_socket.readAll()
0094         return return_message
0095 
0096     def send_si(self, handle, command):
0097         self.send(b2str("beginEdit("+handle+")"))
0098         return_message = self.send(command)
0099         self.send(b2str("endEdit()"))
0100         return return_message
0101 
0102     def test_command(self):
0103         self.send("testCommand()")
0104 
0105     def clear(self):
0106         """ Clears all objects from kst.
0107 
0108         Equivalent to file->close from the menubar inside kst.
0109         """
0110         self.send("clear()")
0111 
0112     def open_kst_file(self, filename):
0113         """ open a .kst file in kst. """
0114         self.send("fileOpen("+b2str(filename)+")")
0115 
0116     def save_kst_file(self, filename):
0117         """ save a .kst file in kst. """
0118         self.send("fileSave("+b2str(filename)+")")
0119 
0120     def export_graphics_file(self, filename, graphics_format=None, width=1280, height=1024,
0121                              display=2, all_tabs=False, autosave_period=0):
0122         """
0123         export the kst session as a set of graphics files.
0124 
0125         :param filename: the name of the file to be saved
0126         :param graphics_format: the format to be used.  if None, the format is determined from
0127                                 the filename extension.
0128         :param width: width of the plot, in pixels, if required by the display setting.
0129         :param height: the height of the plot, in pixels, if required by the display setting.
0130         :param display: how the dimensions are interpreted.
0131         :param all_tabs: if True, all tabs are exported as <filename>_<tabname>.<ext>
0132         :param autosave_period: save the image every <autosave_period> seconds.
0133                                 If 0, only save once.
0134 
0135         *display* determines the shape of the plot.  Values are ::
0136 
0137             0   Width set by user, maintain aspect ratio
0138             1   Height set by user, maintain aspect ratio
0139             2   Width and Height set by user.
0140             3   a Width x Width square plot.
0141 
0142         """
0143 
0144         if graphics_format is None:
0145             graphics_format = os.path.splitext(filename)[1][1:].strip().lower()
0146 
0147         self.send("exportGraphics("+str(filename)+","+str(graphics_format)+","+str(width)+","+
0148                   str(height)+","+str(display)+","+str(all_tabs)+","+str(autosave_period) + ")")
0149 
0150 
0151     def screen_back(self):
0152         """ Equivalent to "Range>Back One Screen" from the menubar inside kst. """
0153         self.send("screenBack()")
0154 
0155     def screen_forward(self):
0156         """ Equivalent to "Range>Forward One Screen" from the menubar inside kst. """
0157         self.send("screenForward()")
0158 
0159     def count_from_end(self):
0160         """ Equivalent to "Range>Count From End" from the menubar inside kst. """
0161         self.send("countFromEnd()")
0162 
0163     def read_to_end(self):
0164         """ Equivalent to "Range>Read To End" from the menubar inside kst. """
0165         self.send("readToEnd()")
0166 
0167     def set_paused(self):
0168         """ Equivalent to checking "Range>Pause" from the menubar inside kst."""
0169         self.send("setPaused()")
0170 
0171     def unset_paused(self):
0172         """ Equivalent to unchecking "Range>Pause" from the menubar inside kst."""
0173         self.send("unsetPaused()")
0174 
0175     def hide_window(self):
0176         """
0177         Hide the kst window.
0178 
0179         pyKst operations which effect the display are far faster when the window is hidden.
0180 
0181         Restore with show_window() or maximize_window()."""
0182 
0183         self.send("hide()")
0184 
0185     def quit(self):
0186         """
0187         Tell the kst window to terminate
0188 
0189         After this, client will no longer be valid."""
0190 
0191         self.send("quit()")
0192 
0193     def minimize_window(self):
0194         """ Minimize the kst window. """
0195         self.send("minimize()")
0196 
0197     def maximize_window(self):
0198         """ Maximize the kst window. """
0199         self.send("maximize()")
0200 
0201     def show_window(self):
0202         """ unminimize and show the kst window. """
0203         self.send("show()")
0204 
0205     def tab_count(self):
0206         """ Get the number of tabs open in the current document. """
0207         return self.send("tabCount()")
0208 
0209     def new_tab(self):
0210         """ Create a new tab in the current document and switch to it. """
0211         return self.send("newTab()")
0212 
0213     def set_tab(self, tab):
0214         """ Set the index of the current tab.
0215 
0216         tab must be greater or equal to 0 and less than tabCount().
0217         """
0218         self.send("setTab("+b2str(tab)+")")
0219 
0220     def set_tab_text(self, new_name):
0221         """ Set the text of the current tab.
0222 
0223         """
0224         self.send("renameTab("+new_name+")")
0225 
0226     def cleanup_layout(self, columns="Auto"):
0227         """ Cleanup layout in the current tab.
0228 
0229          If columns is not set, use auto-layout.
0230 
0231         """
0232         self.send("cleanupLayout("+b2str(columns)+")")
0233 
0234     def get_scalar_list(self):
0235         """ returns the scalar names from kst """
0236 
0237         return_message = self.send("getScalarList()")
0238         name_list = return_message.data().split('|')
0239         return [Scalar(self, name=n) for n in name_list]
0240 
0241     def new_generated_string(self, string, name=""):
0242         """ Create a new generated string in kst.
0243 
0244         See :class:`GeneratedString`
0245         """
0246         return GeneratedString(self, string, name)
0247 
0248     def generated_string(self, name):
0249         """ Returns a generated string from kst given its name.
0250 
0251         See :class:`GeneratedString`
0252         """
0253         return GeneratedString(self, "", name, new=False)
0254 
0255     def new_datasource_string(self, filename, field, name=""):
0256         """ Create a New Data Source String in kst.
0257 
0258         See :class:`DataSourceString`
0259         """
0260         return DataSourceString(self, filename, field, name)
0261 
0262     def datasource_string(self, name):
0263         """ Returns a datasource string from kst given its name.
0264 
0265         See :class:`DataSourceString`
0266         """
0267         return DataSourceString(self, "", "", name, new=False)
0268 
0269     def new_generated_scalar(self, value, name=""):
0270         """ Create a New Generated Scalar in kst.
0271 
0272         See :class:`GeneratedScalar`
0273         """
0274         return GeneratedScalar(self, value, name)
0275 
0276     def generated_scalar(self, name):
0277         """ Returns a Generated Scalar from kst given its name.
0278 
0279         See :class:`GeneratedScalar`
0280         """
0281         return GeneratedScalar(self, "", name, new=False)
0282 
0283     def new_datasource_scalar(self, filename, field, name=""):
0284         """ Create a New DataSource Scalar in kst.
0285 
0286         See :class:`DataSourceScalar`
0287         """
0288         return DataSourceScalar(self, filename, field, name)
0289 
0290     def datasource_scalar(self, name):
0291         """ Returns a DataSource Scalar from kst given its name.
0292 
0293         See :class:`DataSourceScalar`
0294         """
0295         return DataSourceScalar(self, "", "", name, new=False)
0296 
0297     def new_vector_scalar(self, filename, field, frame=-1, name=""):
0298         """ Create a New VectorScalar in kst.
0299 
0300         See :class:`VectorScalar`
0301         """
0302         return VectorScalar(self, filename, field, frame, name)
0303 
0304     def vector_scalar(self, name):
0305         """ Returns a VectorScalar from kst given its name.
0306 
0307         See :class:`VectorScalar`
0308         """
0309         return VectorScalar(self, "", "", 0, name, new=False)
0310 
0311     def new_data_vector(self, filename, field, start=0, num_frames=-1,
0312                         skip=0, boxcarFirst=False, name=""):
0313         """ Create a New DataVector in kst.
0314 
0315         See :class:`DataVector`
0316         """
0317         return DataVector(self, filename, field, start, num_frames,
0318                           skip, boxcarFirst, name)
0319 
0320     def data_vector(self, name):
0321         """ Returns a DataVector from kst given its name.
0322 
0323         See :class:`DataVector`
0324         """
0325         return DataVector(self, "", "", name=name, new=False)
0326 
0327     def new_generated_vector(self, x0, x1, n, name=""):
0328         """ Create a New GeneratedVector in kst.
0329 
0330         See :class:`GeneratedVector`
0331         """
0332         return GeneratedVector(self, x0, x1, n, name)
0333 
0334     def generated_vector(self, name):
0335         """ Returns a GeneratedVector from kst given its name.
0336 
0337         See :class:`GeneratedVector`
0338         """
0339         return GeneratedVector(self, 0, 0, 0, name, new=False)
0340 
0341     def new_editable_vector(self, np_array=None, name=""):
0342         """ Create a New Editable Vector in kst.
0343 
0344         See :class:`EditableVector`
0345         """
0346         return EditableVector(self, np_array, name)
0347 
0348     def editable_vector(self, name):
0349         """ Returns an Editable Vector from kst given its name.
0350 
0351         See :class:`EditableVector`
0352         """
0353         return EditableVector(self, None, name, new=False)
0354 
0355 
0356     def get_vector_list(self):
0357         """ returns vectors from kst. """
0358 
0359         return_message = self.send("getVectorList()")
0360         name_list = return_message.data().split('|')
0361         return [VectorBase(self, name=n) for n in name_list]
0362 
0363     def get_data_vector_list(self):
0364         """ returns data vectors from kst. """
0365 
0366         return_message = self.send("getDataVectorList()")
0367         name_list = return_message.data().split('|')
0368         return [DataVector(self, "", "", name=n, new=False) for n in name_list]
0369 
0370     def get_generated_vector_list(self):
0371         """ returns generated vectors from kst. """
0372 
0373         return_message = self.send("getGeneratedVectorList()")
0374         name_list = return_message.data().split('|')
0375         return [GeneratedVector(self, name=n, new=False) for n in name_list]
0376 
0377     def get_editable_vector_list(self):
0378         """ returns editable vectors from kst. """
0379 
0380         return_message = self.send("getEditableVectorList()")
0381         name_list = return_message.data().split('|')
0382         return [EditableVector(self, name=n, new=False) for n in name_list]
0383 
0384 
0385     def new_data_matrix(self, filename, field, start_x=0, start_y=0, num_x=-1, num_y=-1,
0386                         min_x=0, min_y=0, dx=1, dy=1, name=""):
0387         """ Create a New DataMatrix in kst.
0388 
0389         See :class:`DataMatrix`
0390         """
0391         return DataMatrix(self, filename, field, start_x, start_y, num_x, num_y,
0392                           min_x, min_y, dx, dy, name)
0393 
0394     def data_matrix(self, name):
0395         """ Returns a DataMatrix from kst given its name.
0396 
0397         See :class:`DataMatrix`
0398         """
0399         return DataMatrix(self, "", "", name=name, new=False)
0400 
0401     def new_editable_matrix(self, np_array=None, name=""):
0402         """ Create a New Editable Matrix in kst.
0403 
0404         See :class:`EditableMatrix`
0405         """
0406         return EditableMatrix(self, np_array, name)
0407 
0408     def editable_matrix(self, name):
0409         """ Returns an Editable Matrix from kst given its name.
0410 
0411         See :class:`EditableMatrix`
0412         """
0413         return EditableMatrix(self, None, name, new=False)
0414 
0415     def get_matrix_list(self):
0416         """ returns matrixes from kst. """
0417 
0418         return_message = self.send("getMatrixList()")
0419         name_list = return_message.data().split('|')
0420         return [Matrix(self, name=n) for n in name_list]
0421 
0422 
0423     def new_curve(self, x_vector, y_vector, name=""):
0424         """ Create a New Curve in kst.
0425 
0426         See :class:`Curve`
0427         """
0428         return Curve(self, x_vector, y_vector, name)
0429 
0430     def curve(self, name):
0431         """ Returns a Curve from kst given its name.
0432 
0433         See :class:`Curve`
0434         """
0435         return Curve(self, "", "", name, new=False)
0436 
0437     def new_image(self, matrix, name=""):
0438         """ Create a new Image in kst.
0439 
0440         See :class:`Image`
0441         """
0442         return Image(self, matrix, name)
0443 
0444     def image(self, name):
0445         """ Returns an Image from kst given its name.
0446 
0447         See :class:`Image`
0448         """
0449         return Image(self, "", "", name, new=False)
0450 
0451     def new_equation(self, x_vector, equation, interpolate=True, name=""):
0452         """ Create a new Equation in kst.
0453 
0454         See :class:`Equation`
0455         """
0456         return Equation(self, x_vector, equation, interpolate, name)
0457 
0458 
0459     def equation(self, name):
0460         """ Returns an Equation from kst given its name.
0461 
0462         See :class:`Equation`
0463         """
0464         return Equation(self, "", "", name, new=False)
0465 
0466     def new_histogram(self, vector, bin_min=0, bin_max=1, num_bins=60,
0467                       normalization=0, auto_bin=True, name=""):
0468         """ Create a new histogram in kst.
0469 
0470         See :class:`Histogram`
0471         """
0472         return Histogram(self, vector, bin_min, bin_max, num_bins,
0473                          normalization, auto_bin, name)
0474 
0475 
0476     def histogram(self, name):
0477         """ Returns a histogram from kst given its name.
0478 
0479         See :class:`Histogram`
0480         """
0481         return Histogram(self, "", 0, 0, 0, name=name, new=False)
0482 
0483     def new_cross_spectrum(self,
0484                            V1, V2,
0485                            fft_size=10,
0486                            sample_rate=1.0,
0487                            name=""):
0488         """ Create a cross spectrum object in kst.
0489 
0490         See :class:`CrossSpectrum`
0491         """
0492         return CrossSpectrum(self, V1, V2, fft_size, sample_rate, name)
0493 
0494 
0495     def new_spectrum(self,
0496                      vector,
0497                      sample_rate=1.0,
0498                      interleaved_average=False,
0499                      fft_length=10,
0500                      apodize=True,
0501                      remove_mean=True,
0502                      vector_units="",
0503                      rate_units="Hz",
0504                      apodize_function=0,
0505                      sigma=1.0,
0506                      output_type=0,
0507                      name=""):
0508         """ Create a new Spectrum in kst.
0509 
0510         See :class:`Spectrum`
0511         """
0512         return Spectrum(self,
0513                         vector,
0514                         sample_rate,
0515                         interleaved_average,
0516                         fft_length,
0517                         apodize,
0518                         remove_mean,
0519                         vector_units,
0520                         rate_units,
0521                         apodize_function,
0522                         sigma,
0523                         output_type,
0524                         name)
0525 
0526     def spectrum(self, name):
0527         """ Returns a spectrum from kst given its name.
0528 
0529         See :class:`Spectrum`
0530         """
0531         return Spectrum(self, "", name=name, new=False)
0532 
0533     def new_linear_fit(self, x_vector, y_vector, weightvector=0, name=""):
0534         """ Create a New Linear Fit in kst.
0535 
0536         See :class:`LinearFit`
0537         """
0538         return LinearFit(self, x_vector, y_vector, weightvector, name)
0539 
0540     def linear_fit(self, name):
0541         """ Returns a linear fit from kst given its name.
0542 
0543         See :class:`LinearFit`
0544         """
0545         return LinearFit(self, "", "", 0, name, new=False)
0546 
0547 
0548     def new_polynomial_fit(self, order, x_vector, y_vector, weightvector=0, name=""):
0549         """ Create a New Polynomial Fit in kst.
0550 
0551         See :class:`PolynomialFit`
0552         """
0553         return PolynomialFit(self, order, x_vector, y_vector, weightvector, name)
0554 
0555     def polynomial_fit(self, name):
0556         """ Returns a polynomial fit from kst given its name.
0557 
0558         See :class:`PolynomialFit`
0559         """
0560         return PolynomialFit(self, 0, "", "", 0, name, new=False)
0561 
0562 
0563     def new_sum_filter(self, y_vector, step_dX, name=""):
0564         """ Create a cumulative sum filter inside kst.
0565 
0566         See :class:`SumFilter`
0567         """
0568         return SumFilter(self, y_vector, step_dX, name)
0569 
0570 
0571     def new_flag_filter(self, y_vector, flag, mask="0xffffff", valid_is_zero=True, name=""):
0572         """ Create a flag filter inside kst.
0573 
0574         See :class:`FlagFilter`
0575         """
0576         return FlagFilter(self, y_vector, flag, mask, valid_is_zero, name)
0577 
0578     def flag_filter(self, name):
0579         """ Returns a flag_filter from kst given its name.
0580 
0581         See :class:`FlagFilter`
0582         """
0583         return FlagFilter(self, "", "", name, new=False)
0584 
0585 
0586     def new_label(self, text, pos=(0.5, 0.5), rot=0, font_size=12,
0587                   bold=False, italic=False, font_color="black",
0588                   font_family="Serif", name=""):
0589         """ Create a New Label in kst.
0590 
0591         See :class:`Label`
0592         """
0593         return Label(self, text, pos, rot, font_size, bold, italic,
0594                      font_color, font_family, name)
0595 
0596     def label(self, name):
0597         """ Returns a Label from kst given its name.
0598 
0599         See :class:`Label`
0600         """
0601         return Label(self, "", name=name, new=False)
0602 
0603     def get_label_list(self):
0604         """ Get a list of all labels in kst.
0605 
0606         See :class:`Label`
0607         """
0608         return_message = self.send("getLabelList()")
0609         name_list = return_message.data()[1:-1].split("][")
0610         return [Label(self, "", name=n, new=False) for n in name_list]
0611 
0612 
0613     def new_box(self, pos=(0.1, 0.1), size=(0.1, 0.1), rot=0,
0614                 fill_color="white", fill_style=1, stroke_style=1, stroke_width=1,
0615                 stroke_brush_color="black", stroke_brush_style=1,
0616                 stroke_join_style=1, stroke_cap_style=1, fix_aspect=False, name=""):
0617         """ Create a New Box in kst.
0618 
0619         See :class:`Box`
0620         """
0621         return Box(self, pos, size, rot, fill_color, fill_style, stroke_style,
0622                    stroke_width, stroke_brush_color, stroke_brush_style,
0623                    stroke_join_style, stroke_cap_style, fix_aspect, name)
0624 
0625     def box(self, name):
0626         """ Returns a Box from kst given its name.
0627 
0628         See :class:`Box`
0629         """
0630         return Box(self, name=name, new=False)
0631 
0632     def get_box_list(self):
0633         """ Get a list of all boxes in kst.
0634 
0635         See :class:`Box`
0636         """
0637         return_message = self.send("getBoxList()")
0638         name_list = return_message.data()[1:-1].split("][")
0639         return [Box(self, name=n, new=False) for n in name_list]
0640 
0641 
0642     def new_legend(self, plot, name=""):
0643         """ Create a new Legend in a plot in kst.
0644 
0645         See :class:'Legend'
0646         """
0647         return Legend(self, plot, name)
0648 
0649     def legend(self, name):
0650         """ Returns a Legend from kst given its name.
0651 
0652         See :class:`Legend`
0653         """
0654         return Legend(self, 0, name=name, new=False)
0655 
0656     def get_legend_list(self):
0657         """ Get a list of all legends in kst.
0658 
0659         See :class:`Legend`
0660         """
0661         return_message = self.send("getLegendList()")
0662         name_list = return_message.data()[1:-1].split("][")
0663         return [Legend(self, 0, name=n, new=False) for n in name_list]
0664 
0665 
0666     def new_circle(self, pos=(0.1, 0.1), diameter=0.1,
0667                    fill_color="white", fill_style=1, stroke_style=1,
0668                    stroke_width=1, stroke_brush_color="grey", stroke_brush_style=1, name=""):
0669         """ Create a New Circle in kst.
0670 
0671         See :class:`Circle`
0672         """
0673         return Circle(self, pos, diameter, fill_color, fill_style, stroke_style,
0674                       stroke_width, stroke_brush_color, stroke_brush_style, name)
0675 
0676     def circle(self, name):
0677         """ Returns a Circle from kst given its name.
0678 
0679         See :class:`Circle`
0680         """
0681         return Circle(self, name=name, new=False)
0682 
0683     def get_circle_list(self):
0684         """ Get a list of all ciircles in kst.
0685 
0686         See :class:`Circle`
0687         """
0688         return_message = self.send("getCircleList()")
0689         name_list = return_message.data()[1:-1].split("][")
0690         return [Circle(self, name=n, new=False) for n in name_list]
0691 
0692     def new_ellipse(self, pos=(0.1, 0.1), size=(0.1, 0.1),
0693                     rot=0, fill_color="white", fill_style=1, stroke_style=1,
0694                     stroke_width=1, stroke_brush_color="black", stroke_brush_style=1,
0695                     fix_aspect=False, name=""):
0696         """ Create a New Ellipse in kst.
0697 
0698         See :class:`Ellipse`
0699         """
0700         return Ellipse(self, pos, size, rot, fill_color, fill_style, stroke_style,
0701                        stroke_width, stroke_brush_color, stroke_brush_style,
0702                        fix_aspect, name)
0703 
0704     def ellipse(self, name):
0705         """ Returns an ellipse from kst given its name.
0706 
0707         See :class:`Ellipse`
0708         """
0709         return Ellipse(self, name=name, new=False)
0710 
0711     def get_ellipse_list(self):
0712         """ Get a list of all ellipse in kst.
0713 
0714         See :class:`Ellipse`
0715         """
0716         return_message = self.send("getEllipseList()")
0717         name_list = return_message.data()[1:-1].split("][")
0718         return [Ellipse(self, name=n, new=False) for n in name_list]
0719 
0720     def new_line(self, start=(0, 0), end=(1, 1),
0721                  stroke_style=1, stroke_width=1, stroke_brush_color="black",
0722                  stroke_brush_style=1, stroke_cap_style=1, name=""):
0723         """ Create a New Line in kst.
0724 
0725         See :class:`Line`
0726         """
0727         return Line(self, start, end, stroke_style, stroke_width,
0728                     stroke_brush_color, stroke_brush_style, stroke_cap_style, name)
0729 
0730     def line(self, name):
0731         """ Returns a Line from kst given its name.
0732 
0733         See :class:`Line`
0734         """
0735         return Line(self, name=name, new=False)
0736 
0737     def get_line_list(self):
0738         """ Get a list of all lines in kst.
0739 
0740         See :class:`Line`
0741         """
0742         return_message = self.send("getLineList()")
0743         name_list = return_message.data()[1:-1].split("][")
0744         return [Line(self, name=n, new=False) for n in name_list]
0745 
0746 
0747     def new_arrow(self, start=(0, 0), end=(1, 1),
0748                   arror_at_start=False, arrow_at_end=True, arrow_size=12.0,
0749                   stroke_style=1, stroke_width=1, stroke_brush_color="black",
0750                   stroke_brush_style=1, stroke_cap_style=1, name=""):
0751         """ Create a New Arrow in kst.
0752 
0753         See :class:`Arrow`
0754         """
0755         return Arrow(self, start, end, arror_at_start, arrow_at_end, arrow_size,
0756                      stroke_style, stroke_width, stroke_brush_color, stroke_brush_style,
0757                      stroke_cap_style, name)
0758 
0759     def arrow(self, name):
0760         """ Returns an Arrow from kst given its name.
0761 
0762         See :class:`Arrow`
0763         """
0764         return Arrow(self, name=name, new=False)
0765 
0766     def get_arrow_list(self):
0767         """ Get a list of all arrows in kst.
0768 
0769         See :class:`Arrow`
0770         """
0771         return_message = self.send("getArrowList()")
0772         name_list = return_message.data()[1:-1].split("][")
0773         return [Arrow(self, name=n, new=False) for n in name_list]
0774 
0775     def new_picture(self, filename, pos=(0.1, 0.1), width=0.1, rot=0, name=""):
0776         """ Create a New Picture in kst.
0777 
0778         See :class:`Picture`
0779         """
0780         return Picture(self, filename, pos, width, rot, name)
0781 
0782     def picture(self, name):
0783         """ Returns a Picture from kst given its name.
0784 
0785         See :class:`Picture`
0786         """
0787         return Picture(self, "", name=name, new=False)
0788 
0789     def get_picture_list(self):
0790         """ Get a list of all pictures in kst.
0791 
0792         See :class:`Picture`
0793         """
0794         return_message = self.send("getPictureList()")
0795         name_list = return_message.data()[1:-1].split("][")
0796         return [Picture(self, "", name=n, new=False) for n in name_list]
0797 
0798     def new_SVG(self, filename, pos=(0.1, 0.1), width=0.1, rot=0, name=""):
0799         """ Create a New SVG in kst.
0800 
0801         See :class:`SVG`
0802         """
0803         return SVG(self, filename, pos, width, rot, name)
0804 
0805     def SVG(self, name):
0806         """ Returns a SVG from kst given its name.
0807 
0808         See :class:`SVG`
0809         """
0810         return SVG(self, "", name=name, new=False)
0811 
0812     def get_SVG_list(self):
0813         """ Get a list of all SVGs in kst.
0814 
0815         See :class:`SVG`
0816         """
0817         return_message = self.send("getSVGList()")
0818         name_list = return_message.data()[1:-1].split("][")
0819         return [SVG(self, "", name=n, new=False) for n in name_list]
0820 
0821     def new_plot(self, pos=(0.1, 0.1), size=(0, 0), rot=0, font_size=0, columns=0,
0822                  fill_color="white", fill_style=1, stroke_style=1, stroke_width=1,
0823                  stroke_brush_color="black", stroke_brush_style=1,
0824                  stroke_join_style=1, stroke_cap_style=1, fix_aspect=False,
0825                  auto_position=True, name=""):
0826         """ Create a New Plot in kst.
0827 
0828         See :class:`Plot`
0829         """
0830         return Plot(self, pos, size, rot, font_size, columns, fill_color, fill_style, stroke_style,
0831                     stroke_width, stroke_brush_color, stroke_brush_style,
0832                     stroke_join_style, stroke_cap_style, fix_aspect, auto_position, name)
0833 
0834     def plot(self, name):
0835         """ Returns a Plot from kst given its name.
0836 
0837         See :class:`Plot`
0838         """
0839         return Plot(self, name=name, new=False)
0840 
0841     def get_plot_list(self):
0842         """ Get a list of all plots in kst.
0843 
0844         See :class:`Plot`
0845         """
0846         return_message = self.send("getPlotList()")
0847         name_list = return_message.data()[1:-1].split("][")
0848         return [Plot(self, name=n, new=False) for n in name_list]
0849 
0850     def set_datasource_option(self, option, value, filename, data_source="Ascii File"):
0851         """ Sets the value of a data source configuration option.
0852 
0853         :param option: the name of the option - eg ""Data Start"
0854         :param value: True or False
0855         :param filename: the name of the file or 0 to set global default
0856         :param data_source: the type of data source
0857 
0858         Examples:
0859 
0860         Tell kst that trial1.csv is a file with the field names in row 1 and units in row 2::
0861 
0862             import pykst as kst
0863             client = kst.Client()
0864             client.set_datasource_option("Column Delimiter", ",", "trial1.csv")
0865             client.set_datasource_option("Column Type", 2, "trial1.csv")
0866             client.set_datasource_option("Data Start", 3-1, "trial1.csv")
0867             client.set_datasource_option("Fields Line", 1-1, "trial1.csv")
0868             client.set_datasource_option("Read Fields", True, "trial1.csv")
0869             client.set_datasource_option("Units Line", 2-1, "trial1.csv")
0870             client.set_datasource_option("Read Units", True, "trial1.csv")
0871 
0872         Configuration options supported by the ASCII data source (default) are::
0873 
0874             "ASCII Time format"
0875             "Column Delimiter"
0876             "Column Type"
0877             "Column Width"
0878             "Column Width is const"
0879             "Comment Delimiters"
0880             "Data Rate for index"
0881             "Data Start"
0882             "Default INDEX Interpretation"
0883             "Fields Line"
0884             "Filename Pattern"
0885             "Index"
0886             "Limit file buffer size"
0887             "NaN value"
0888             "Read Fields"
0889             "Read Units"
0890             "Size of limited file buffer"
0891             "Units Line"
0892             "Use Dot"
0893             "Use threads when parsing Ascii data"
0894             "date/time offset"
0895             "relative offset"
0896             "updateType"
0897             "use an explicit date/time offset"
0898             "use file time/date as offset"
0899             "use relative file time offset"
0900 
0901 
0902         """
0903 
0904         if filename == 0:
0905             filename = "$DEFAULT"
0906 
0907         if isinstance(value, bool):
0908             self.send("setDatasourceBoolConfig("+data_source+","+filename+","+option+","+
0909                       b2str(value)+")")
0910         elif isinstance(value, int):
0911             self.send("setDatasourceIntConfig("+data_source+","+filename+","+option+","+
0912                       str(value)+")")
0913         else:
0914             v = value
0915             v.replace(',', '`')
0916             self.send("setDatasourceStringConfig("+data_source+","+filename+","+option+","+
0917                       str(v)+")")
0918 
0919 
0920 
0921 class NamedObject(object):
0922     """ Convenience class. You should not use it directly."""
0923     def __init__(self, client):
0924         self.client = client
0925         self.handle = ""
0926 
0927     def set_name(self, name):
0928         """ Set the name of the object inside kst. """
0929         self.client.send_si(self.handle, b2str("setName("+b2str(name)+")"))
0930 
0931     def name(self):
0932         """ Returns the name of the object from inside kst. """
0933         return self.client.send_si(self.handle, "name()")
0934 
0935     def description_tip(self):
0936         """  Returns a string describing the object """
0937         return self.client.send_si(self.handle, "descriptionTip()")
0938 
0939     def test_command(self):
0940         return self.client.send_si(self.handle, "testCommand()")
0941 
0942 
0943 class Object(NamedObject):
0944     """ Convenience class. You should not use it directly."""
0945     def __init__(self, client):
0946         NamedObject.__init__(self, client)
0947 
0948     def type_str(self):
0949         """ Returns the type of the object from inside kst. """
0950         return self.client.send_si(self.handle, "type()")
0951 
0952 
0953 class String(Object):
0954     """ Convenience class. You should not use it directly."""
0955     def __init__(self, client):
0956         Object.__init__(self, client)
0957 
0958     def value(self):
0959         """ Returns the string. """
0960         return self.client.send_si(self.handle, "value()")
0961 
0962 class GeneratedString(String):
0963     """ A string constant inside kst.
0964 
0965     This class represents a string you would create via
0966     "Create>String>Generated" from the menubar inside kst.
0967 
0968     :param string: The value of the string.
0969 
0970     To import the string "Hello World" into kst::
0971 
0972       import pykst as kst
0973       client = kst.Client()
0974       s = client.new_generatedString("Hello World")
0975 
0976     """
0977     def __init__(self, client, string, name="", new=True):
0978         String.__init__(self, client)
0979 
0980         if new:
0981             self.client.send("newGeneratedString()")
0982             self.handle = self.client.send("endEdit()")
0983             self.handle.remove(0, self.handle.indexOf("ing ")+4)
0984 
0985             self.set_value(string)
0986             self.set_name(name)
0987         else:
0988             self.handle = name
0989 
0990     def set_value(self, val):
0991         """ set the value of the string inside kst. """
0992         self.client.send_si(self.handle, b2str("setValue("+b2str(val)+")"))
0993 
0994 class DataSourceString(String):
0995     """ A string read from a data source inside kst.
0996 
0997     This class represents a string you would create via
0998     "Create>String>Read from Data Source" from the menubar inside kst.
0999 
1000     :param filename: The name of the file/data source to read the string from.
1001     :param field: the name of the field in the data source.
1002 
1003     To read "File path" from the data source "tmp.dat" into kst::
1004 
1005       import pykst as kst
1006       client = kst.Client()
1007       s = client.new_datasource_string("tmp.dat", "File Path")
1008 
1009     """
1010     def __init__(self, client, filename, field, name="", new=True):
1011         String.__init__(self, client)
1012 
1013         if new:
1014             self.client.send("newDataString()")
1015             self.handle = self.client.send("endEdit()")
1016             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1017             self.change(filename, field)
1018         else:
1019             self.handle = name
1020 
1021     def change(self, filename, field, frame = 0):
1022         """ Change a DataSource String.
1023 
1024         Change the file and field of a DataSourceString in kst.
1025 
1026         :param filename: The name of the file/data source to read the string from.
1027         :param field: the name of the field in the data source.
1028         :param frame: the frame number if the string is a function of frame number.
1029         """
1030         self.client.send_si(self.handle, b2str("change("+b2str(filename)+","+b2str(field)+","+b2str(frame)+")"))
1031 
1032 
1033 class Scalar(Object):
1034     """ Convenience class. You should not use it directly."""
1035     def __init__(self, client, name=""):
1036         Object.__init__(self, client)
1037 
1038         self.handle = name
1039 
1040     def value(self):
1041         """ Returns the scalar. """
1042         return self.client.send_si(self.handle, "value()")
1043 
1044 class GeneratedScalar(Scalar):
1045     """ A scalar constant inside kst.
1046 
1047     This class represents a scalar you would create via
1048     "Create>Scalar>Generate" from the menubar inside kst.
1049 
1050     :param value: the value to assign to the scalar constant.
1051 
1052     To import the scalar of value 42 into kst::
1053 
1054       import pykst as kst
1055       client = kst.Client()
1056       s = client.new_generated_scalar(42)
1057 
1058     """
1059     def __init__(self, client, value, name="", new=True):
1060         Scalar.__init__(self, client)
1061 
1062         if new:
1063             self.client.send("newGeneratedScalar()")
1064             self.handle = self.client.send("endEdit()")
1065             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1066 
1067             self.set_value(value)
1068             self.set_name(name)
1069         else:
1070             self.handle = name
1071 
1072     def set_value(self, val):
1073         """ set the value of the string inside kst. """
1074         self.client.send_si(self.handle, b2str("setValue("+b2str(val)+")"))
1075 
1076 
1077 class DataSourceScalar(Scalar):
1078     """ A scalar read from a data source inside kst.
1079 
1080     This class represents a scalar you would create via
1081     "Create>Scalar>Read from Data Source" from the menubar inside kst.
1082 
1083     :param filename: The name of the file/data source to read the scalar from.
1084     :param field: the name of the field in the data source.
1085 
1086     To read "CONST1" from the data source "tmp.dat" into kst::
1087 
1088       import pykst as kst
1089       client = kst.Client()
1090       x = client.new_datasource_scalar("tmp.dat", "CONST1")
1091 
1092     """
1093     def __init__(self, client, filename, field, name="", new=True):
1094         Scalar.__init__(self, client)
1095 
1096         if new:
1097             self.client.send("newDataScalar()")
1098             self.handle = self.client.send("endEdit()")
1099             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1100 
1101             self.change(filename, field)
1102         else:
1103             self.handle = name
1104 
1105     def change(self, filename, field):
1106         """ Change a DataSource Scalar.
1107 
1108         Change the file and field of a DataSourceScalar in kst.
1109 
1110         :param filename: The name of the file/data source to read the scalar from.
1111         :param field: the name of the field in the data source.
1112         """
1113         self.client.send_si(self.handle, "change("+filename+","+field+")")
1114 
1115     def file(self):
1116         """ Returns the data source file name. """
1117         return self.client.send_si(self.handle, "file()")
1118 
1119     def field(self):
1120         """ Returns the field. """
1121         return self.client.send_si(self.handle, "field()")
1122 
1123 
1124 class VectorScalar(Scalar):
1125     """ A scalar in kst read from a vector from a data source.
1126 
1127     This class represents a scalar you would create via
1128     "Create>Scalar>Read from vector" from the menubar inside kst.
1129 
1130     :param filename: The name of the file/data source to read the scalar from.
1131     :param field: the name of the vector in the data source.
1132     :param frame: which frame of the vector to read the scalar from.
1133                   frame = -1 (the default) reads from the end of the file.
1134 
1135     To read the last value of the vector INDEX from the file "tmp.dat"
1136     into kst::
1137 
1138       import pykst as kst
1139       client = kst.Client()
1140       x = client.new_vector_scalar("tmp.dat", "INDEX", -1)
1141 
1142     """
1143     def __init__(self, client, filename, field, frame=-1, name="", new=True):
1144         Scalar.__init__(self, client)
1145 
1146         if new:
1147             self.client.send("newVectorScalar()")
1148             self.handle = self.client.send("endEdit()")
1149             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1150 
1151             self.change(filename, field, frame)
1152         else:
1153             self.handle = name
1154 
1155     def change(self, filename, field, frame):
1156         """ Change a Vector Scalar in kst.
1157 
1158         Change the file, field and frame of a VectorScalar in kst.
1159 
1160         :param filename: The name of the file/data source to read the scalar from.
1161         :param field: the name of the vector in the data source.
1162         :param frame: which frame of the vector to read the scalar from.
1163                       frame = -1 reads from the end of the file.
1164         """
1165         self.client.send_si(self.handle, b2str("change("+b2str(filename)+","+
1166                                                b2str(field)+","+b2str(frame)+")"))
1167 
1168     def file(self):
1169         """ Returns the data source file name. """
1170         return self.client.send_si(self.handle, "file()")
1171 
1172     def field(self):
1173         """ Returns the field. """
1174         return self.client.send_si(self.handle, "field()")
1175 
1176     def frame(self):
1177         """ Returns the fame. """
1178         return self.client.send_si(self.handle, "frame()")
1179 
1180 class VectorBase(Object):
1181     """ Convenience class. You should not use it directly."""
1182     def __init__(self, client, name=""):
1183         Object.__init__(self, client)
1184         self.handle = name
1185 
1186     def value(self, index):
1187         """  Returns element i of this vector. """
1188         return self.client.send_si(self.handle, "value("+b2str(index)+")")
1189 
1190     def length(self):
1191         """  Returns the number of samples in the vector. """
1192         return self.client.send_si(self.handle, "length()")
1193 
1194     def min(self):
1195         """  Returns the minimum value in the vector. """
1196         return self.client.send_si(self.handle, "min()")
1197 
1198     def mean(self):
1199         """  Returns the mean of the vector. """
1200         return self.client.send_si(self.handle, "mean()")
1201 
1202     def max(self):
1203         """  Returns the maximum value in the vector. """
1204         return self.client.send_si(self.handle, "max()")
1205 
1206     def get_numpy_array(self):
1207         """ get a numpy array which contains the kst vector values """
1208         with tempfile.NamedTemporaryFile() as f:
1209             self.client.send_si(self.handle, "store(" + f.name + ")")
1210             array = np.fromfile(f.name, dtype=np.float64)
1211 
1212         return array
1213 
1214 
1215 class DataVector(VectorBase):
1216     """ A vector in kst, read from a data source.
1217 
1218     This class represents a vector you would create via
1219     "Create>Vector>Read from Data Source" from the menubar inside kst.
1220 
1221     The parameters of this function mirror the parameters within
1222     "Create>Vector>Read from Data Source".
1223 
1224     :param filename: The name of the file/data source to read the scalar from.
1225     :param field: the name of the vector in the data source.
1226     :param start: The starting index of the vector.
1227                   start = -1 for count from end.
1228     :param num_frames: The number of frames to read.
1229                     num_frames = -1 for read to end.
1230     :param skip: The number of frames per sample read.
1231                  skip = 0 to read every sample.
1232     :param boxcarFirst: apply a boxcar filter before skiping.
1233 
1234     To create a vector from "tmp.dat" with field "INDEX" from
1235     frame 3 to frame 10, reading a sample every other frame without
1236     a boxcar filter::
1237 
1238       import pykst as kst
1239       client = kst.Client()
1240       v = client.new_data_vector("tmp.dat", "INDEX", 3, 10, 2, False)
1241 
1242     """
1243     def __init__(self, client, filename, field, start=0, num_frames=-1,
1244                  skip=0, boxcarFirst=False, name="", new=True):
1245         VectorBase.__init__(self, client)
1246 
1247         if new:
1248             self.client.send("newDataVector()")
1249             self.handle = self.client.send("endEdit()")
1250             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1251             self.change(filename, field, start, num_frames, skip, boxcarFirst)
1252         else:
1253             self.handle = name
1254 
1255     def change(self, filename, field, start, num_frames, skip, boxcarFirst):
1256         """ Change the parameters of a data vector.
1257 
1258         :param filename: The name of the file/data source to read the scalar from.
1259         :param field: the name of the vector in the data source.
1260         :param start: The starting index of the vector.
1261                       start = -1 for count from end.
1262         :param num_frames: The number of frames to read.
1263                         num_frames = -1 for read to end.
1264         :param skip: The number of frames per sample read.
1265                     skip = 0 to read every sample.
1266         :param boxcarFirst: apply a boxcar filter before skiping.
1267 
1268         """
1269         self.client.send_si(self.handle, "change("+filename+","+field+","
1270                             +b2str(start)+","+b2str(num_frames)+","+b2str(skip)
1271                             +","+b2str(boxcarFirst)+")")
1272 
1273     def change_frames(self, start, num_frames, skip, boxcarFirst):
1274         """ Change the parameters of a data vector.
1275 
1276         :param start: The starting index of the vector.
1277                       start = -1 for count from end.
1278         :param num_frames: The number of frames to read.
1279                         num_frames = -1 for read to end.
1280         :param skip: The number of frames per sample read.
1281                     skip = 0 to read every sample.
1282         :param boxcarFirst: apply a boxcar filter before skiping.
1283 
1284         """
1285         self.client.send_si(self.handle, "changeFrames("
1286                             +b2str(start)+","+b2str(num_frames)+","+b2str(skip)
1287                             +","+b2str(boxcarFirst)+")")
1288 
1289     def field(self):
1290         """  Returns the fieldname. """
1291         return self.client.send_si(self.handle, "field()")
1292 
1293     def filename(self):
1294         """  Returns the filename. """
1295         return self.client.send_si(self.handle, "filename()")
1296 
1297     def start(self):
1298         """  Returns the index of first frame in the vector.
1299         -1 means count from end. """
1300         return self.client.send_si(self.handle, "start()")
1301 
1302     def n_frames(self):
1303         """  Returns the number of frames to be read. -1 means read to end. """
1304         return self.client.send_si(self.handle, "NFrames()")
1305 
1306     def skip(self):
1307         """  Returns number of frames to be skipped between samples read. """
1308         return self.client.send_si(self.handle, "skip()")
1309 
1310     def boxcar_first(self):
1311         """  True if boxcar filtering has been applied before skipping. """
1312         return self.client.send_si(self.handle, "boxcarFirst()")
1313 
1314 class GeneratedVector(VectorBase):
1315     """ Create a generated vector in kst.
1316 
1317     This class represents a vector you would create via
1318     "Create>Vector>Generate" from the menubar inside kst.
1319 
1320     :param x0: The first value in the vector.
1321     :param x1: The last value in the vector.
1322     :param n: The number of evenly spaced values in the vector.
1323 
1324     To create the vector {0, 0.2, 0.4, 0.6, 0.8, 1.0}::
1325 
1326       import pykst as kst
1327       client = kst.Client()
1328       v = client.new_generated_vector(0, 1, 6)
1329 
1330     """
1331     def __init__(self, client, x0=0, x1=1, n=100, name="", new=True):
1332         VectorBase.__init__(self, client)
1333 
1334         if new:
1335             self.client.send("newGeneratedVector()")
1336             self.handle = self.client.send("endEdit()")
1337             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1338 
1339             self.change(x0, x1, n)
1340             self.set_name(name)
1341         else:
1342             self.handle = name
1343 
1344     def change(self, x0, x1, n):
1345         """ Change the parameters of a Generated Vector inside kst.
1346 
1347         :param x0: The first value in the vector.
1348         :param x1: The last value in the vector.
1349         :param n: The number of evenly spaced values in the vector.
1350         """
1351         self.client.send_si(self.handle, "change("+b2str(x0)+","+b2str(x1)+
1352                             ","+b2str(n)+")")
1353 
1354 class EditableVector(VectorBase):
1355     """ A vector in kst, which is editable from python.
1356 
1357     This vector in kst can be created from a numpy array,
1358     (with ''load()'') or edited point by point (with ''setValue()'').
1359     "Create>Vector>Generate" from the menubar inside kst.
1360 
1361     :param np_array: initialize the vector in kst to this (optional) 1D numpy array.
1362 
1363     To create a from the num py array np::
1364 
1365       import pykst as kst
1366       client = kst.Client()
1367       v = client.new_editable_vector(np)
1368 
1369     """
1370     def __init__(self, client, np_array=None, name="", new=True):
1371         VectorBase.__init__(self, client)
1372 
1373         if new:
1374             self.client.send("newEditableVector()")
1375             if np_array is not None:
1376                 assert np_array.dtype == np.float64
1377 
1378                 with tempfile.NamedTemporaryFile(delete=False) as f:
1379                     f.close()
1380                     #atexit.register(clean_tmp_file, f)
1381                     np_array.tofile(f.name)
1382                     self.client.send("load(" + f.name + ")")
1383                     os.unlink(f.name)
1384 
1385             self.handle = self.client.send("endEdit()")
1386             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1387 
1388             self.set_name(name)
1389         else:
1390             self.handle = name
1391 
1392     def load(self, np_array):
1393         """  sets the value of the vector to that of the float64
1394         1D np array """
1395 
1396         assert np_array.dtype == np.float64
1397         with tempfile.NamedTemporaryFile(delete=False) as f:
1398             f.close()
1399             #atexit.register(clean_tmp_file, f)
1400             np_array.tofile(f.name)
1401             retval = self.client.send_si(self.handle, "load(" + f.name + ")")
1402             os.unlink(f.name)
1403 
1404         return retval
1405 
1406 class Matrix(Object):
1407     """ Convenience class. You should not use it directly."""
1408     def __init__(self, client, name=""):
1409         Object.__init__(self, client)
1410 
1411         self.handle = name
1412 
1413 
1414     def value(self, i_x, i_y):
1415         """  Returns element (i_x, i_y} of this matrix. """
1416         return self.client.send_si(self.handle, "value("+b2str(i_x)+
1417                                    ","+b2str(i_y)+")")
1418 
1419     def length(self):
1420         """  Returns the number of elements in the matrix. """
1421         return self.client.send_si(self.handle, "length()")
1422 
1423     def min(self):
1424         """  Returns the minimum value in the matrix. """
1425         return self.client.send_si(self.handle, "min()")
1426 
1427     def mean(self):
1428         """  Returns the mean of the matrix. """
1429         return self.client.send_si(self.handle, "mean()")
1430 
1431     def max(self):
1432         """  Returns the maximum value in the matrix. """
1433         return self.client.send_si(self.handle, "max()")
1434 
1435     def width(self):
1436         """  Returns the X dimension of the matrix. """
1437         return self.client.send_si(self.handle, "width()")
1438 
1439     def height(self):
1440         """  Returns the Y dimension of the matrix. """
1441         return self.client.send_si(self.handle, "height()")
1442 
1443     def dx(self):
1444         """  Returns the X spacing of the matrix, for when the matrix is used in an image. """
1445         return self.client.send_si(self.handle, "dX()")
1446 
1447     def dy(self):
1448         """  Returns the Y spacing of the matrix, for when the matrix is used in an image. """
1449         return self.client.send_si(self.handle, "dY()")
1450 
1451     def min_x(self):
1452         """  Returns the minimum X location of the matrix, for when the matrix
1453         is used in an image. """
1454         return self.client.send_si(self.handle, "minX()")
1455 
1456     def min_y(self):
1457         """  Returns the minimum X location of the matrix, for when the matrix
1458         is used in an image. """
1459         return self.client.send_si(self.handle, "minY()")
1460 
1461     def get_numpy_array(self):
1462         """ get a numpy array which contains the kst matrix values """
1463         with tempfile.NamedTemporaryFile() as f:
1464             args = str(self.client.send_si(self.handle, "store(" + f.name + ")"))
1465             dims = tuple(map(int, args.split()))
1466             array = np.fromfile(f.name, dtype=np.float64)
1467             array = array.reshape((dims))
1468 
1469         return array
1470 
1471 
1472 class DataMatrix(Matrix):
1473     """  Create a Data Matrix which reads from a data source inside kst.
1474 
1475     This class represents a matrix you would create via
1476     "Create>Vector>Read from Data Source" from the menubar inside kst.
1477     The parameters of this function mirror the parameters within
1478     "Create>Matrix>Read from Data Source".
1479 
1480     :param filename: The name of the file/data source to read the scalar from.
1481     :param field: the name of the vector in the data source.
1482     :param start_x/start_y: the x/y index to start reading from. start_x/Y = -1
1483                      to count from the right/bottom.
1484     :param num_x/num_y: the number of columns/rows to read.  num_x/Y = -1 to read
1485                  to the end.
1486     :param min_x/min_y: Hint to Images of the coordinates corresponding to the
1487                    the left/bottom of the Matrix
1488     :param dx/dy: Hint to Images of the spacing between points.
1489 
1490     To create a matrix from 'foo.png' with field '1'::
1491 
1492       import pykst as kst
1493       client = kst.Client()
1494       v = client.new_data_matrix("foo.png", "1")
1495 
1496     """
1497     def __init__(self, client, filename, field, start_x=0, start_y=0, num_x=-1, num_y=-1,
1498                  min_x=0, min_y=0, dx=1, dy=1, name="", new=True):
1499         Matrix.__init__(self, client)
1500 
1501         if new:
1502             self.client.send("newDataMatrix()")
1503             self.handle = self.client.send("endEdit()")
1504             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1505 
1506             self.change(filename, field, start_x, start_y, num_x, num_y, min_x, min_y, dx, dy)
1507         else:
1508             self.handle = name
1509 
1510     def change(self, filename, field, start_x=0, start_y=0, num_x=-1, num_y=-1,
1511                min_x=0, min_y=0, dx=1, dy=1):
1512         """ Change the parameters if a Data Matrix inside kst.
1513 
1514         :param filename: The name of the file/data source to read the scalar from.
1515         :param field: the name of the vector in the data source.
1516         :param start_x/start_y: the x/y index to start reading from. start_x/y = -1
1517                         to count from the right/bottom.
1518         :param num_x/num_y: the number of columns/rows to read.  num_x/Y = -1 to read
1519                     to the end.
1520         :param min_x/min_y: Hint to Images of the coordinates corresponding to the
1521                       the left/bottom of the Matrix
1522         :param dx/dy: Hint to Images of the spacing between points.
1523         """
1524         self.client.send_si(self.handle, "change("+b2str(filename)+","+
1525                             b2str(field)+","+b2str(start_x)+","+
1526                             b2str(start_y)+","+b2str(num_x)+","+b2str(num_y)+","+
1527                             b2str(min_x)+","+b2str(min_y)+","+b2str(dx)+","+
1528                             b2str(dy)+")")
1529 
1530     def field(self):
1531         """  Returns the fieldname. """
1532         return self.client.send_si(self.handle, "field()")
1533 
1534     def filename(self):
1535         """  Returns the filename. """
1536         return self.client.send_si(self.handle, "filename()")
1537 
1538     def start_x(self):
1539         """  Returns the X index of the matrix in the file """
1540         return self.client.send_si(self.handle, "startX()")
1541 
1542     def start_y(self):
1543         """  Returns the Y index of the matrix in the file """
1544         return self.client.send_si(self.handle, "startY()")
1545 
1546 class EditableMatrix(Matrix):
1547     """ A matrix in kst, which is editable from python.
1548 
1549     This matrix in kst can be created from 2D float64 numpy array,
1550     (with ''load()'') or edited point by point (with ''setValue()'').
1551 
1552     :param np_array: initialize the matrix in kst to this 2D numpy array.
1553 
1554     To create an editable matrix from the num py array np::
1555 
1556       import pykst as kst
1557       client = kst.Client()
1558       m = client.new_editable_matrix(np)
1559 
1560     """
1561     def __init__(self, client, np_array=None, name="", new=True):
1562         Matrix.__init__(self, client)
1563 
1564         if new:
1565             self.client.send("newEditableMatrix()")
1566             if np_array is not None:
1567                 assert np_array.dtype == np.float64
1568                 nx = np_array.shape[0]
1569                 ny = np_array.shape[1]
1570 
1571                 with tempfile.NamedTemporaryFile(delete=False) as f:
1572                     f.close()
1573                     atexit.register(clean_tmp_file, f)
1574                     np_array.tofile(f.name)
1575                     self.client.send("load(" + f.name + ","+b2str(nx)+","+b2str(ny)+")")
1576 
1577             self.handle = self.client.send("endEdit()")
1578             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1579 
1580             self.set_name(name)
1581         else:
1582             self.handle = name
1583 
1584     def load(self, np_array):
1585         """  sets the values of the matrix in kst to that of the float64
1586         2D np array """
1587 
1588         assert np_array.dtype == np.float64
1589         nx = np_array.shape[0]
1590         ny = np_array.shape[1]
1591 
1592         with tempfile.NamedTemporaryFile(delete=False) as f:
1593             f.close()
1594             atexit.register(clean_tmp_file, f)
1595             np_array.tofile(f.name)
1596             retval = self.client.send_si(self.handle, "load(" + f.name + ","+b2str(nx)+","+
1597                                          b2str(ny)+")")
1598 
1599         return retval
1600 
1601 
1602 class Relation(Object):
1603     """ Convenience class. You should not use it directly."""
1604     def __init__(self, client):
1605         Object.__init__(self, client)
1606 
1607     def max_x(self):
1608         """  Returns the max X value of the curve or image. """
1609         return self.client.send_si(self.handle, "maxX()")
1610 
1611     def min_x(self):
1612         """  Returns the min X value of the curve or image. """
1613         return self.client.send_si(self.handle, "minX()")
1614 
1615     def max_y(self):
1616         """  Returns the max Y value of the curve or image. """
1617         return self.client.send_si(self.handle, "maxY()")
1618 
1619     def min_y(self):
1620         """  Returns the min Y value of the curve or image. """
1621         return self.client.send_si(self.handle, "minY()")
1622 
1623     def show_edit_dialog(self):
1624         """  shows the edit dialog for the curve or image. """
1625         return self.client.send_si(self.handle, "showEditDialog()")
1626 
1627 class Curve(Relation):
1628     """ A Curve inside kst.
1629 
1630     This class represents a string you would create via
1631     "Create>Curve" from the menubar inside kst.  The parameters of this
1632     function mirror the parameters within "Create>Curve".
1633 
1634     :param x_vector: The vector which specifies the X coordinates of each point.
1635     :param x_vector: The vector which specifies the Y coordinates of each point.
1636 
1637     Use the convenience function in client to create a curve in kst session
1638     "client" of vectors v1 and v2::
1639 
1640       c1 = client.new_curve(v1, v2)
1641 
1642     """
1643     def __init__(self, client, x_vector, y_vector, name="", new=True):
1644         Relation.__init__(self, client)
1645 
1646         if new:
1647             self.client.send("newCurve()")
1648             self.client.send("setXVector("+x_vector.handle+")")
1649             self.client.send("setYVector("+y_vector.handle+")")
1650             self.handle = self.client.send("endEdit()")
1651             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1652             self.set_name(name)
1653         else:
1654             self.handle = name
1655 
1656     def set_y_error(self, vector, vectorminus=0):
1657         """ Set the Y Error flags for the curve.
1658 
1659         The error bars are symetric if vectorminus is not set.
1660         """
1661         self.client.send("beginEdit("+self.handle+")")
1662 
1663         self.client.send("setYError("+vector.handle+")")
1664         if vectorminus != 0:
1665             self.client.send("setYMinusError("+vectorminus.handle+")")
1666         else:
1667             self.client.send("setYMinusError("+vector.handle+")")
1668 
1669         self.client.send("endEdit()")
1670 
1671     def set_x_error(self, vector, vectorminus=0):
1672         """ Set the X Error flags for the curve.
1673 
1674         The error bars are symetric if vectorminus is not set.
1675         """
1676         self.client.send("beginEdit("+self.handle+")")
1677 
1678         self.client.send("setXError("+vector.handle+")")
1679         if vectorminus != 0:
1680             self.client.send("setXMinusError("+vectorminus.handle+")")
1681         else:
1682             self.client.send("setXMinusError("+vector.handle+")")
1683 
1684         self.client.send("endEdit()")
1685 
1686     def set_color(self, color):
1687         """ Set the color of the points and lines.
1688 
1689         Colors are given by a name such as ``red`` or a hex number such
1690         as ``#FF0000``.
1691         """
1692         self.client.send_si(self.handle, "setColor("+color+")")
1693 
1694     def set_head_color(self, color):
1695         """ Set the color of the Head marker, if any.
1696 
1697         Colors are given by a name such as ``red`` or a hex number such
1698         as ``#FF0000``.
1699         """
1700         self.client.send_si(self.handle, "setHeadColor("+color+")")
1701 
1702     def set_bar_fill_color(self, color):
1703         """ Set the fill color of the histogram bars, if any.
1704 
1705         Colors are given by a name such as ``red`` or a hex number such
1706         as ``#FF0000``.
1707         """
1708         self.client.send_si(self.handle, "setBarFillColor("+color+")")
1709 
1710     def set_has_points(self, has=True):
1711         """ Set whether individual points are drawn on the curve """
1712         if has:
1713             self.client.send_si(self.handle, "setHasPoints(True)")
1714         else:
1715             self.client.send_si(self.handle, "setHasPoints(False)")
1716 
1717     def set_has_bars(self, has=True):
1718         """ Set whether histogram bars are drawn. """
1719         if has:
1720             self.client.send_si(self.handle, "setHasBars(True)")
1721         else:
1722             self.client.send_si(self.handle, "setHasBars(False)")
1723 
1724     def set_has_lines(self, has=True):
1725         """ Set whether lines are drawn. """
1726         if has:
1727             self.client.send_si(self.handle, "setHasLines(True)")
1728         else:
1729             self.client.send_si(self.handle, "setHasLines(False)")
1730 
1731     def set_has_head(self, has=True):
1732         """ Set whether a point at the head of the line is drawn """
1733         if has:
1734             self.client.send_si(self.handle, "setHasHead(True)")
1735         else:
1736             self.client.send_si(self.handle, "setHasHead(False)")
1737 
1738     def set_line_width(self, x):
1739         """ Sets the width of the curve's line. """
1740         self.client.send_si(self.handle, "setLineWidth("+b2str(x)+")")
1741 
1742     def set_point_size(self, x):
1743         """ Sets the size of points, if they are drawn. """
1744         self.client.send_si(self.handle, "setPointSize("+b2str(x)+")")
1745 
1746     def set_point_density(self, density):
1747         """ Sets the point density.
1748 
1749         When show_points is true, this option can be used to only show a
1750         subset of the points, for example, to use point types to discriminate
1751         between different curves..  This does not effect 'lines', where every
1752         point is always connected.
1753 
1754         density can be from 0 (all points) to 4.
1755         """
1756         self.client.send_si(self.handle, "setPointDensity("+b2str(density)+")")
1757 
1758     def set_point_type(self, point_type):
1759         """ Sets the point type.
1760 
1761         The available point types are::
1762 
1763          0:  X                       1: open square
1764          2:  open circle,           3: filled circle
1765          4:  downward open triangle  5: upward open triangle
1766          6:  filled square           7: +
1767          8:  *                       9: downward filled triangle
1768          10: upward filled triangle 11: open diamond
1769          12: filled diamond
1770 
1771         """
1772         self.client.send_si(self.handle, "setPointType("+b2str(point_type)+")")
1773 
1774     def set_head_type(self, x):
1775         """ Sets the head point type.  See set_point_type for details."""
1776         self.client.send_si(self.handle, "setHeadType("+b2str(x)+")")
1777 
1778     def set_line_style(self, lineStyle):
1779         """ Sets the line type.
1780 
1781         0 is SolidLine, 1 is DashLine, 2 is DotLine, 3 is DashDotLine,
1782         and 4 isDashDotDotLine,
1783         """
1784         self.client.send_si(self.handle, "setLineStyle("+b2str(lineStyle)+")")
1785 
1786 
1787     def color(self):
1788         """ Returns the curve color. """
1789         return self.client.send_si(self.handle, "color()")
1790 
1791     def head_color(self):
1792         """ Returns the curve head color. """
1793         return self.client.send_si(self.handle, "headColor()")
1794 
1795     def bar_fill_color(self):
1796         """ Returns the bar fill color. """
1797         return self.client.send_si(self.handle, "barFillColor()")
1798 
1799     def has_points(self):
1800         """ Returns True if the line has points. """
1801         return self.client.send_si(self.handle, "hasPoints()") == "True"
1802 
1803     def has_lines(self):
1804         """ Returns True if the line has lines. """
1805         return self.client.send_si(self.handle, "hasLines()") == "True"
1806 
1807     def has_bars(self):
1808         """ Returns True if the line has historgram bars. """
1809         return self.client.send_si(self.handle, "hasBars()") == "True"
1810 
1811     def has_head(self):
1812         """ Returns True if the last point has a special marker. """
1813         return self.client.send_si(self.handle, "hasHead()") == "True"
1814 
1815     def line_width(self):
1816         """ Returns the width of the line. """
1817         return self.client.send_si(self.handle, "lineWidth()")
1818 
1819     def point_size(self):
1820         """ Returns the size of the points. """
1821         return self.client.send_si(self.handle, "pointSize()")
1822 
1823     def point_type(self):
1824         """ Returns index of the point type.  See set_point_type. """
1825         return self.client.send_si(self.handle, "pointType()")
1826 
1827     def head_type(self):
1828         """ Returns index of the head point type.  See set_point_type. """
1829         return self.client.send_si(self.handle, "headType()")
1830 
1831     def line_style(self):
1832         """ Returns the index of the line style.  See set_line_style. """
1833         return self.client.send_si(self.handle, "lineStyle()")
1834 
1835     def point_density(self):
1836         """ Returns the density of points shown.  see set_point_density.  """
1837         return self.client.send_si(self.handle, "pointDensity()")
1838 
1839     def x_vector(self):
1840         """ Returns the x vector of the curve.
1841 
1842         FIXME: should figure out what kind of vector this is and return that.
1843         """
1844         vec = VectorBase(self.client)
1845         vec.handle = self.client.send_si(self.handle, "xVector()")
1846         return vec
1847 
1848     def y_vector(self):
1849         """ Returns the y vector of the curve.
1850 
1851         FIXME: should figure out what kind of vector this is and return that.
1852         """
1853         vec = VectorBase(self.client)
1854         vec.handle = self.client.send_si(self.handle, "yVector()")
1855         return vec
1856 
1857     def x_error_vector(self):
1858         """ Returns the +x error vector of the curve.
1859 
1860         FIXME: should figure out what kind of vector this is and return that.
1861         """
1862         vec = VectorBase(self.client)
1863         vec.handle = self.client.send_si(self.handle, "xErrorVector()")
1864         return vec
1865 
1866     def y_error_vector(self):
1867         """ Returns the +y error vector of the curve.
1868 
1869         FIXME: should figure out what kind of vector this is and return that.
1870         """
1871         vec = VectorBase(self.client)
1872         vec.handle = self.client.send_si(self.handle, "yErrorVector()")
1873         return vec
1874 
1875     def x_minus_error_vector(self):
1876         """ Returns the -x error vector of the curve.
1877 
1878         FIXME: should figure out what kind of vector this is and return that.
1879         """
1880         vec = VectorBase(self.client)
1881         vec.handle = self.client.send_si(self.handle, "xMinusErrorVector()")
1882         return vec
1883 
1884     def y_minus_error_vector(self):
1885         """ Returns the -y error vector of the curve.
1886 
1887         FIXME: should figure out what kind of vector this is and return that.
1888         """
1889         vec = VectorBase(self.client)
1890         vec.handle = self.client.send_si(self.handle, "yMinusErrorVector()")
1891         return vec
1892 
1893 class Image(Relation):
1894     """ An image inside kst.
1895 
1896     This class represents an image you would create via
1897     "Create>Image" from the menubar inside kst.  The parameters of this
1898     function mirror the parameters within "Create>Curve".
1899 
1900     :param matrix: The matrix which defines the image.
1901 
1902     Use the convenience function in client to create an image in kst session
1903     "client" of Matrix m::
1904 
1905       i1 = client.new_image(m)
1906 
1907     """
1908     def __init__(self, client, matrix, name="", new=True):
1909         Relation.__init__(self, client)
1910 
1911         if new:
1912             self.client.send("newImage()")
1913             self.client.send("setMatrix("+matrix.handle+")")
1914             self.handle = self.client.send("endEdit()")
1915             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1916             self.set_name(name)
1917 
1918         else:
1919             self.handle = name
1920 
1921     def set_matrix(self, matrix):
1922         """ change the matrix which is the source of the image. """
1923         self.client.send_si(self.handle, "setMatrix("+matrix.handle+")")
1924 
1925     def set_palette(self, palette):
1926         """ set the palette, selected by index.
1927 
1928         The available palettes are::
1929 
1930           0: Grey
1931           1:  Red
1932           2:  Spectrum
1933           3:  EOS-A
1934           4:  EOS-B
1935           5:  8 colors
1936           6:  Cyclical Spectrum
1937 
1938         Note: this is not the same order as the dialog.
1939         """
1940         self.client.send_si(self.handle, "setPalette("+b2str(palette)+")")
1941 
1942     def set_range(self, zmin, zmax):
1943         """ sets the z range of the color map."""
1944         self.client.send_si(self.handle, "setFixedColorRange("+
1945                             b2str(zmin)+","+b2str(zmax)+")")
1946 
1947     def set_auto_range(self, saturated=0):
1948         """ Automatically set the z range of the color map
1949 
1950         :param saturated: The colormap range is set so that this fraction
1951                           of the points in the matrix are saturated.
1952 
1953         Equal numbers of points are saturated at both ends of the color map.
1954         """
1955         self.client.send_si(self.handle, "setAutoColorRange("+b2str(saturated) + ")")
1956 
1957     def max_z(self):
1958         """  Returns the max Z value of the curve or image. """
1959         return self.client.send_si(self.handle, "maxZ()")
1960 
1961     def min_z(self):
1962         """  Returns the max Z value of the curve or image. """
1963         return self.client.send_si(self.handle, "minZ()")
1964 
1965 # Equation ############################################################
1966 class Equation(Object):
1967     """ An equation inside kst.
1968 
1969       :param xvector: the x vector of the equation
1970       :param equation: the equation
1971 
1972       Vectors inside kst are refered to as [vectorname] or [scalarname].
1973     """
1974     def __init__(self, client, xvector, equation, interpolate=True, name="", new=True):
1975         Object.__init__(self, client)
1976 
1977         if new:
1978             self.client.send("newEquation()")
1979 
1980             self.client.send("setEquation(" + equation + ")")
1981             self.client.send("setInputVector(X,"+xvector.handle+")")
1982             self.client.send("interpolateVectors("+b2str(interpolate)+")")
1983             self.handle = self.client.send("endEdit()")
1984             self.handle.remove(0, self.handle.indexOf("ing ")+4)
1985             self.set_name(name)
1986         else:
1987             self.handle = name
1988 
1989     def y(self):
1990         """ a vector containing the equation  """
1991         vec = VectorBase(self.client)
1992         vec.handle = self.client.send_si(self.handle, "outputVector(O)")
1993         return vec
1994 
1995     def x(self):
1996         """ a vector containing the x vector  """
1997         vec = VectorBase(self.client)
1998         vec.handle = self.client.send_si(self.handle, "outputVector(XO)")
1999         return vec
2000 
2001     def set_x(self, xvector):
2002         """ set the x vector of an existing equation.  xvector is a kst vector.  """
2003         self.client.send_si(self.handle, "setInputVector(X,"+xvector.handle+")")
2004 
2005     def set_equation(self, equation):
2006         """ set the equation of an existing equation  """
2007         self.client.send_si(self.handle, "setEquation(" + equation + ")")
2008 
2009     def set_inpterpolate(self, interpolate):
2010         """ set whether all vectors are interpolated to the highest resolution vector. """
2011         self.client.send_si(self.handle, "interpolateVectors(" + b2str(interpolate) + ")")
2012 
2013 # Histogram ############################################################
2014 class Histogram(Object):
2015     """ A Histogram inside kst.
2016 
2017       :param vector: the vector to take the histogram of
2018       :param bin_min: the low end of the lowest bin
2019       :param bin_max: the high end of the highest bin
2020       :param num_bins: the number of bins
2021       :param normalization: see below
2022       :param auto_bin: if True, set xmin and xmax based on the vector
2023 
2024       The normalization types are::
2025 
2026        0: Number in the bin     1: Percent in the bin
2027        2: Fraction in the bin   3: Peak is normalized to 1.0
2028 
2029     """
2030     def __init__(self, client, vector, bin_min, bin_max, num_bins,
2031                  normalization=0, auto_bin=False,
2032                  name="", new=True):
2033         Object.__init__(self, client)
2034 
2035         if new:
2036             self.client.send("newHistogram()")
2037 
2038             self.client.send("change(" + vector.handle + "," +
2039                              b2str(bin_min) + "," +
2040                              b2str(bin_max) + "," +
2041                              b2str(num_bins) + "," +
2042                              b2str(normalization) + "," +
2043                              b2str(auto_bin) + ")")
2044 
2045             self.handle = self.client.send("endEdit()")
2046             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2047             self.set_name(name)
2048         else:
2049             self.handle = name
2050 
2051     def y(self):
2052         """ a vector containing the histogram values  """
2053         vec = VectorBase(self.client)
2054         vec.handle = self.client.send_si(self.handle, "outputVector(H)")
2055         return vec
2056 
2057     def x(self):
2058         """ a vector containing the bin centers  """
2059         vec = VectorBase(self.client)
2060         vec.handle = self.client.send_si(self.handle, "outputVector(B)")
2061         return vec
2062 
2063     def change(self, vector, bin_min, bin_max, num_bins,
2064                normalization=0, auto_bin=False):
2065         """ Change Histogram parameters.
2066 
2067         :param vector: the vector to take the histogram of
2068         :param bin_min: the low end of the lowest bin
2069         :param bin_max: the high end of the highest bin
2070         :param num_bins: the number of bins
2071         :param normalization: See :class:`Histogram`
2072         :param auto_bin: if True, set xmin and xmax based on the vector
2073 
2074         """
2075         self.client.send_si(self.handle, "change(" +
2076                             vector.handle + "," +
2077                             b2str(bin_min) + "," +
2078                             b2str(bin_max) + "," +
2079                             b2str(num_bins) + "," +
2080                             b2str(normalization) + "," +
2081                             b2str(auto_bin) + ")")
2082 
2083     def bin_min(self):
2084         """ the low end of the lowest bin """
2085         retval = self.client.send_si(self.handle, "xMin()")
2086         return retval
2087 
2088     def bin_max(self):
2089         """ the high end of the lowest bin """
2090         retval = self.client.send_si(self.handle, "xMax()")
2091         return retval
2092 
2093     def num_bins(self):
2094         """ the number of bins """
2095         retval = self.client.send_si(self.handle, "nBins()")
2096         return retval
2097 
2098     def normalization(self):
2099         """ how the bins are normalized
2100 
2101         See :class:`Histogram`
2102 
2103         """
2104         retval = self.client.send_si(self.handle, "normalizationType()")
2105         return retval
2106 
2107     def auto_bin(self):
2108         """ if True, xmin and xmax are set based on the vector """
2109         retval = self.client.send_si(self.handle, "autoBin()")
2110         return retval
2111 
2112 # Spectrum ############################################################
2113 class Spectrum(Object):
2114     """ An spectrum inside kst.
2115 
2116       :param vector: the vector to take the spectrum of
2117       :param sample_rate: the sample rate of the vector
2118       :param interleaved_average: average spectra of length fft_length
2119       :param fft_length: the fft is 2^fft_length long if interleaved_average is true.
2120       :param apodize: if true, apodize the vector first
2121       :param remove_mean: if true, remove mean first
2122       :param vector_unints: units of the input vector - for labels.
2123       :param rate_units: the units of the sample rate - for labels.
2124       :param apodize_function: index of the apodization function - see apodize_function()
2125       :param sigma: only used if gausian apodization is selected.
2126       :param output_type: index for the output type - see output_type()
2127 
2128       The apodize function is::
2129 
2130        0: default          1: Bartlett
2131        2: Window           3: Connes
2132        4: Cosine           5: Gaussian
2133        6: Hamming          7: Hann
2134        8: Welch            9: Uniform
2135 
2136       The output type is::
2137 
2138        0: Amplitude Spectral Density  1: Power Spectral Density
2139        2: AmplitudeSpectrum           3: Power Spectrum
2140 
2141 
2142     """
2143     def __init__(self, client,
2144                  vector,
2145                  sample_rate=1.0,
2146                  interleaved_average=False,
2147                  fft_length=10,
2148                  apodize=True,
2149                  remove_mean=True,
2150                  vector_units="",
2151                  rate_units="Hz",
2152                  apodize_function=0,
2153                  sigma=1.0,
2154                  output_type=0,
2155                  name="", new=True):
2156 
2157         Object.__init__(self, client)
2158 
2159         if new:
2160             self.client.send("newSpectrum()")
2161 
2162             self.client.send("change(" + vector.handle + "," +
2163                              b2str(sample_rate) + "," +
2164                              b2str(interleaved_average) + "," +
2165                              b2str(fft_length) + "," +
2166                              b2str(apodize) + "," +
2167                              b2str(remove_mean) + "," +
2168                              vector_units + "," +
2169                              rate_units + "," +
2170                              b2str(apodize_function) + "," +
2171                              b2str(sigma) + "," +
2172                              b2str(output_type) + "," + ")")
2173 
2174             self.handle = self.client.send("endEdit()")
2175             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2176             self.set_name(name)
2177         else:
2178             self.handle = name
2179 
2180     def y(self):
2181         """ a vector containing the spectrum  """
2182         vec = VectorBase(self.client)
2183         vec.handle = self.client.send_si(self.handle, "outputVector(S)")
2184         return vec
2185 
2186     def x(self):
2187         """ a vector containing the frequency bins  """
2188         vec = VectorBase(self.client)
2189         vec.handle = self.client.send_si(self.handle, "outputVector(F)")
2190         return vec
2191 
2192     def set_vector(self, xvector):
2193         """ set the input vector """
2194         self.client.send_si(self.handle, "setInputVector(I,"+xvector.handle+")")
2195 
2196     def interleaved_average(self):
2197         """ average spectra of length fft_length() """
2198         retval = self.client.send_si(self.handle, "interleavedAverage()")
2199         return retval
2200 
2201     def sample_rate(self):
2202         """ the sample rate assumed for the spectra. """
2203         retval = self.client.send_si(self.handle, "sampleRate()")
2204         return retval
2205 
2206     def fft_length(self):
2207         """ ffts are 2^fft_length() long if interleaved_average is set """
2208         retval = self.client.send_si(self.handle, "fftLength()")
2209         return retval
2210 
2211     def apodize(self):
2212         """ apodize before taking spectra, if set """
2213         retval = self.client.send_si(self.handle, "apodize()")
2214         return retval
2215 
2216     def remove_mean(self):
2217         """ remove mean before taking spectra, if set """
2218         retval = self.client.send_si(self.handle, "removeMean()")
2219         return retval
2220 
2221     def vector_units(self):
2222         """ the units of the input vector.  For labels """
2223         retval = self.client.send_si(self.handle, "vectorUnits()")
2224         return retval
2225 
2226     def rate_units(self):
2227         """ the units of the sample rate.  For labels """
2228         retval = self.client.send_si(self.handle, "rateUnits()")
2229         return retval
2230 
2231     def apodize_function(self):
2232         """ the index of the apodize function.
2233 
2234         The apodize funcition is::
2235 
2236          0: default          1: Bartlett
2237          2: Window           3: Connes
2238          4: Cosine           5: Gaussian
2239          6: Hamming          7: Hann
2240          8: Welch            9: Uniform
2241 
2242         """
2243         retval = self.client.send_si(self.handle, "apodizeFunctionIndex()")
2244         return retval
2245 
2246     def gaussian_sigma(self):
2247         """ the width, if apodize_funcion_index() is 5 (gaussian). """
2248         retval = self.client.send_si(self.handle, "gaussianSigma()")
2249         return retval
2250 
2251     def output_type(self):
2252         """ the index of the spectrum output type.
2253 
2254         The output type is::
2255 
2256          0: Amplitude Spectral Density  1: Power Spectral Density
2257          2: AmplitudeSpectrum           3: Power Spectrum
2258 
2259         """
2260 
2261         retval = self.client.send_si(self.handle, "outputTypeIndex()")
2262         return retval
2263 
2264 
2265 # Cross Spectrum ########################################################
2266 class CrossSpectrum(Object):
2267     """ a cross spectrum plugin inside kst.
2268 
2269     Takes two equal sized vectors and calculates their cross spectrum.
2270 
2271       :param V1: First kst vector
2272       :param V2: Second kst vector.  Must be the same size as V1
2273       :param fft_size: the fft will be on subvectors of length 2^fft_size
2274       :param sample_rate: the sample rate of the vectors
2275 
2276     """
2277     def __init__(self, client, V1, V2, fft_size, sample_rate, name="", new=True):
2278         Object.__init__(self, client)
2279 
2280         if new:
2281             self.client.send("newPlugin(Cross Spectrum)")
2282 
2283             self.client.send("setInputVector(Vector In One,"+V1.handle+")")
2284             self.client.send("setInputVector(Vector In Two,"+V2.handle+")")
2285 
2286             if isinstance(fft_size, Scalar):
2287                 self.client.send("setInputScalar(Scalar In FFT,"+fft_size.handle+")")
2288             else:
2289                 tmpscalar = self.client.new_generated_scalar(fft_size)
2290                 self.client.send("setInputScalar(Scalar In FFT,"+tmpscalar.handle+")")
2291 
2292             if isinstance(sample_rate, Scalar):
2293                 self.client.send("setInputScalar(Scalar In Sample Rate,"+sample_rate.handle+")")
2294             else:
2295                 tmpscalar2 = self.client.new_generated_scalar(sample_rate)
2296                 self.client.send("setInputScalar(Scalar In Sample Rate,"+tmpscalar2.handle+")")
2297 
2298             self.handle = self.client.send("endEdit()")
2299             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2300             self.set_name(name)
2301         else:
2302             self.handle = name
2303 
2304     def x(self):
2305         """ a vector containing the frequency bins of the fft  """
2306         vec = VectorBase(self.client)
2307         vec.handle = self.client.send_si(self.handle, "outputVector(Frequency)")
2308         return vec
2309 
2310 
2311     def y(self):
2312         """ a vector containing the real part if the cross spectrum  """
2313         vec = VectorBase(self.client)
2314         vec.handle = self.client.send_si(self.handle, "outputVector(Real)")
2315         return vec
2316 
2317     def yi(self):
2318         """ a vector containing the imaginary part if the cross spectrum  """
2319         vec = VectorBase(self.client)
2320         vec.handle = self.client.send_si(self.handle, "outputVector(Imaginary)")
2321         return vec
2322 
2323 # FILTER ################################################################
2324 class Filter(Object):
2325     """ This is a class which provides some methods common to all filters """
2326     def __init__(self, client):
2327         Object.__init__(self, client)
2328 
2329     def output(self):
2330         """ a vector containing the output of the filter  """
2331         vec = VectorBase(self.client)
2332         vec.handle = self.client.send_si(self.handle, "outputVector(Y)")
2333         return vec
2334 
2335 # SUM FILTER ############################################################
2336 class SumFilter(Filter):
2337     """ a cumulative sum filter inside kst
2338 
2339     The output is the cumulative sum of the input vector
2340     """
2341     def __init__(self, client, yvector, step_dX, name="", new=True):
2342         Filter.__init__(self, client)
2343 
2344         if new:
2345             self.client.send("newPlugin(Cumulative Sum)")
2346             self.client.send("setInputVector(Vector In,"+yvector.handle+")")
2347             self.client.send("setInputScalar(Scale Scalar,"+step_dX.handle+")")
2348             self.handle = self.client.send("endEdit()")
2349             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2350             self.set_name(name)
2351         else:
2352             self.handle = name
2353 
2354     def output_sum(self):
2355         """ a vector containing the output of the filter  """
2356         vec = VectorBase(self.client)
2357         vec.handle = self.client.send_si(self.handle, "outputVector(sum(Y)dX)")
2358         return vec
2359 
2360 
2361 # FLAG FILTER ############################################################
2362 class FlagFilter(Filter):
2363     """ a flagged vector inside kst
2364 
2365     The output is the input when flag == 0, or NaN if flag is non-0.
2366     """
2367     def __init__(self, client, yvector, flag, mask="0xffffff", valid_is_zero=True,
2368                  name="", new=True):
2369         Filter.__init__(self, client)
2370 
2371         if new:
2372             self.client.send("newPlugin(Flag Filter)")
2373 
2374             self.client.send("setInputVector(Y Vector,"+yvector.handle+")")
2375             self.client.send("setInputVector(Flag Vector,"+flag.handle+")")
2376             self.client.send("setProperty(Mask,"+mask+")")
2377             if valid_is_zero:
2378                 self.client.send("setProperty(ValidIsZero,true)")
2379             else:
2380                 self.client.send("setProperty(ValidIsZero,false)")
2381 
2382             self.handle = self.client.send("endEdit()")
2383             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2384             self.set_name(name)
2385         else:
2386             self.handle = name
2387 
2388 
2389 # FIT ###################################################################
2390 class Fit(Object):
2391     """ This is a class which provides some methods common to all fits """
2392     def __init__(self, client):
2393         Object.__init__(self, client)
2394 
2395     def parameters(self):
2396         """ a vector containing the Parameters of the fit  """
2397         vec = VectorBase(self.client)
2398         vec.handle = self.client.send_si(self.handle, "outputVector(Parameters Vector)")
2399         return vec
2400 
2401     def fit(self):
2402         """ a vector containing the fit  """
2403         vec = VectorBase(self.client)
2404         vec.handle = self.client.send_si(self.handle, "outputVector(Fit)")
2405         return vec
2406 
2407     def residuals(self):
2408         """ a vector containing the Parameters of the fit  """
2409         vec = VectorBase(self.client)
2410         vec.handle = self.client.send_si(self.handle, "outputVector(Residuals)")
2411         return vec
2412 
2413     def covariance(self):
2414         """ a vector containing the Covariance of the fit  """
2415         vec = VectorBase(self.client)
2416         vec.handle = self.client.send_si(self.handle, "outputVector(Covariance)")
2417         return vec
2418 
2419     def reduced_chi2(self):
2420         """ a scalar containing the Parameters of the fit  """
2421         X = Scalar(self.client)
2422         X.handle = self.client.send_si(self.handle, "outputScalar(chi^2/nu)")
2423         return X
2424 
2425 
2426 # LINEAR FIT ############################################################
2427 class LinearFit(Fit):
2428     """ A linear fit inside kst.
2429 
2430     If weightvector is 0, then the fit is unweighted.
2431     """
2432     def __init__(self, client, xvector, yvector, weightvector=0, name="", new=True):
2433         Fit.__init__(self, client)
2434 
2435         if new:
2436             if weightvector == 0:
2437                 self.client.send("newPlugin(Linear Fit)")
2438             else:
2439                 self.client.send("newPlugin(Linear Weighted Fit)")
2440                 self.client.send("setInputVector(Weights Vector,"+weightvector.handle+")")
2441 
2442             self.client.send("setInputVector(X Vector,"+xvector.handle+")")
2443             self.client.send("setInputVector(Y Vector,"+yvector.handle+")")
2444             self.handle = self.client.send("endEdit()")
2445             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2446             self.set_name(name)
2447         else:
2448             self.handle = name
2449 
2450     def slope(self):
2451         """ The slope of the fit.  """
2452         vec = VectorBase(self.client)
2453         vec.handle = self.client.send_si(self.handle, "outputVector(Parameters Vector)")
2454         return vec.value(1)
2455 
2456     def intercept(self):
2457         """ The intercept of the fit.  """
2458         vec = VectorBase(self.client)
2459         vec.handle = self.client.send_si(self.handle, "outputVector(Parameters Vector)")
2460         return vec.value(0)
2461 
2462 # POLYNOMIAL FIT ############################################################
2463 class PolynomialFit(Fit):
2464     """ A Polynomial fit inside kst.
2465 
2466        :param order: The order of the fit
2467     """
2468     def __init__(self, client, order, xvector, yvector, weightvector=0, name="", new=True):
2469         Fit.__init__(self, client)
2470 
2471         if new:
2472             if weightvector == 0:
2473                 self.client.send("newPlugin(Polynomial Fit)")
2474             else:
2475                 self.client.send("newPlugin(Polynomial Weighted Fit)")
2476                 self.client.send("setInputVector(Weights Vector,"+weightvector.handle+")")
2477 
2478             self.client.send("setInputVector(X Vector,"+xvector.handle+")")
2479             self.client.send("setInputVector(Y Vector,"+yvector.handle+")")
2480             self.client.send("setInputScalar(Order Scalar,"+order.handle+")")
2481             self.handle = self.client.send("endEdit()")
2482             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2483             self.set_name(name)
2484         else:
2485             self.handle = name
2486 
2487 
2488 
2489 # View Items ################################################################
2490 class ViewItem(NamedObject):
2491     """ Convenience class. You should not use it directly."""
2492     def __init__(self, client):
2493         NamedObject.__init__(self, client)
2494         #self.client = client
2495 
2496     def set_h_margin(self, margin):
2497         self.client.send_si(self.handle,
2498                             "setLayoutHorizontalMargin("+b2str(margin)+")")
2499 
2500     def set_v_margin(self, margin):
2501         self.client.send_si(self.handle,
2502                             "setLayoutVerticalMargin("+b2str(margin)+")")
2503 
2504     def set_h_space(self, space):
2505         self.client.send_si(self.handle,
2506                             "setLayoutHorizontalSpacing("+b2str(space)+")")
2507 
2508     def set_v_space(self, space):
2509         self.client.send_si(self.handle,
2510                             "setLayoutVerticalSpacing("+b2str(space)+")")
2511 
2512     def set_fill_color(self, color):
2513         """ Set the fill/background color.
2514 
2515         Colors are given by a name such as ``red`` or a hex number such
2516         as ``#FF0000``.
2517 
2518         """
2519         self.client.send_si(self.handle, b2str("setFillColor("+b2str(color)+")"))
2520 
2521     def set_fill_style(self, style):
2522         """ Set the background fill style.
2523 
2524         This is equivalent to setting the index of Apperance>Fill>Style within
2525         a view item dialog in kst.::
2526 
2527          0:  NoBrush          1:  SolidPattern
2528          2:  Dense1Pattern    3:  Dense2Pattern
2529          4:  Dense3Pattern    5:  Dense4Pattern
2530          6:  Dense5Pattern    7:  Dense6Pattern
2531          8:  Dense7Pattern    9:  HorPattern
2532          11: VerPattern       12: CrossPattern,
2533          13: BDiagPattern     14: FDiagPattern.
2534 
2535         """
2536         self.client.send_si(self.handle,
2537                             "setIndexOfFillStyle("+b2str(style)+")")
2538 
2539     def set_stroke_style(self, style):
2540         """ Set the stroke style of lines for the item.
2541 
2542         This is equivalent to setting the index of Apperance>Stroke>Style
2543         within a view item dialog in kst::
2544 
2545          0: SolidLine       1: DashLine
2546          2: DotLine         3: DashDotLine
2547          4: DashDotDotLine  5: CustomDashLine
2548 
2549         """
2550         self.client.send_si(self.handle, "setIndexOfStrokeStyle("+b2str(style)+")")
2551 
2552     def set_stroke_width(self, width):
2553         """ Set the width of lines for the item. """
2554         self.client.send_si(self.handle, "setStrokeWidth("+b2str(width)+")")
2555 
2556     def set_stroke_brush_color(self, color):
2557         """ Set the color for lines for the item.
2558 
2559         Colors are given by a name such as ``red`` or a hex number
2560         such as ``#FF0000``.
2561         """
2562         self.client.send_si(self.handle, "setStrokeBrushColor("+b2str(color)+")")
2563 
2564     def set_stroke_brush_style(self, style):
2565         """ Set the brush style for lines for the item.
2566 
2567         This is equivalent to setting the index of Apperance>Stroke>Brush Style
2568         within a view item dialog in kst.
2569 
2570         This sets the brush type for lines in the item, and not for the fill,
2571         so values other than ``1`` (SolidPattern) only make sense for wide lines
2572         and are rarely used::
2573 
2574          0:  NoBrush          1:  SolidPattern
2575          2:  Dense1Pattern    3:  Dense2Pattern
2576          4:  Dense3Pattern    5:  Dense4Pattern
2577          6:  Dense5Pattern    7:  Dense6Pattern
2578          8:  Dense7Pattern    9:  HorPattern
2579          11: VerPattern       12: CrossPattern,
2580          13: BDiagPattern     14: FDiagPattern.
2581 
2582         """
2583         self.client.send_si(self.handle,
2584                             "setIndexOfStrokeBrushStyle("+b2str(style)+")")
2585 
2586     def set_stroke_join_style(self, style):
2587         """ Set the style by which lines are joined in the item.
2588 
2589         This is equivalent to setting the index of Apperance>Stroke>Join Style
2590         within a view item dialog in kst.
2591 
2592         0 is MiterJoin, 1 is BevelJoin, 2 is RoundJoin,
2593         and 3 is SvgMiterJoin.
2594         """
2595         self.client.send_si(self.handle,
2596                             "setIndexOfStrokeJoinStyle("+b2str(style)+")")
2597 
2598     def set_stroke_cap_style(self, style):
2599         """ Set the cap style for the ends of lines in the item.
2600 
2601         This is equivalent to setting the index of Apperance>Stroke>Cap Style
2602         within a view item dialog in kst.
2603 
2604         0 is FlatCap, 1 is SquareCap, and 2 is RoundCap.
2605         """
2606         self.client.send_si(self.handle,
2607                             "setIndexOfStrokeCapStyle("+b2str(style)+")")
2608 
2609     def set_fixed_aspect_ratio(self, fixed=True):
2610         """ if True, fix the aspect ratio of the item to its current value.
2611 
2612         This is equivalent to checking Dimensions>Fix aspect ratio within a
2613         view item dialog in kst.
2614         """
2615         if fixed:
2616             self.client.send_si(self.handle, b2str("lockAspectRatio(True)"))
2617         else:
2618             self.client.send_si(self.handle, b2str("lockAspectRatio(False)"))
2619 
2620     def position(self):
2621         return_message = str(self.client.send_si(self.handle, "position()"))
2622 
2623         ret = literal_eval(return_message)
2624 
2625         return ret
2626 
2627     def dimensions(self):
2628         return_message = str(self.client.send_si(self.handle, "dimensions()"))
2629 
2630         ret = literal_eval(return_message)
2631 
2632         return ret
2633 
2634     def set_pos(self, pos):
2635         """ Set the center position of the item.
2636 
2637         :param pos: a 2 element tuple ``(x, y)`` specifying the position.
2638                     The Top Left of the parent is (0, 0).
2639                     The Bottom Right of the parent is (1, 1)
2640 
2641         """
2642         x, y = pos
2643 
2644         self.client.send("beginEdit("+self.handle+")")
2645         self.client.send("setPos("+b2str(x)+","+b2str(y)+")")
2646         #self.client.send("setPosX("+b2str(x)+")")
2647         #self.client.send("setPosY("+b2str(y)+")")
2648         self.client.send("endEdit()")
2649 
2650     def set_size(self, size):
2651         """ Set the size of the item.
2652 
2653         :param size: a 2 element tuple ``(w, h)`` specifying the size.
2654 
2655         Elements go from 0 to 1.  If the aspect ratio is fixed, then ``h``
2656         is ignored.
2657 
2658         This is equivalent to setting Dimensions>Position within a view
2659         item dialog in kst.
2660 
2661         """
2662         w, h = size
2663         self.client.send("beginEdit("+self.handle+")")
2664         self.client.send("setSize("+b2str(w)+","+b2str(h)+")")
2665         self.client.send("endEdit()")
2666 
2667     def set_lock_pos_to_data(self, lock=True):
2668         """
2669         if lock is True, and the item is in a plot, then the position of the item
2670         will be locked to the data coordinates in the plot.  The item will move with
2671         zooming and scrolling.
2672 
2673         If lock is False, or the item is not in a plot, then the item will be fixed
2674         to the geometry of the window, and zooming/scrolling will not change its
2675         position.
2676 
2677         """
2678         if lock:
2679             self.client.send_si(self.handle, "setLockPosToData(True)")
2680         else:
2681             self.client.send_si(self.handle, "setLockPosToData(False)")
2682 
2683     def set_parent_auto(self):
2684         """
2685         Set the parent of the viewitem to an existing view item which fully contains it.
2686         Once reparented, moving/resizing the parent will also move/resize the child.
2687 
2688         By default view items created by pyKst are parented by the toplevel view unless
2689         this method is called, or if the item is moved/resized in the GUI.
2690         """
2691 
2692         self.client.send_si(self.handle, "updateParent()")
2693 
2694     def set_parent_toplevel(self):
2695         """
2696         Set the parent of the viewitem to the toplevel view.
2697 
2698         By default view items created by pyKst are parented by the toplevel view unless
2699         set_parent_auto() is called, or if the item is moved/resized in the GUI.
2700         """
2701 
2702         self.client.send_si(self.handle, "parentTopLevel()")
2703 
2704     def subplot(self, *args):
2705         """
2706         Set the item position according to the given grid definition.
2707 
2708         Typical call signature::
2709 
2710           subplot(nrows, ncols, plot_number)
2711 
2712         Where *nrows* and *ncols* are used to notionally split the figure
2713         into ``nrows * ncols`` sub-axes, and *plot_number* is used to identify
2714         the particular subplot that this function is to create within the notional
2715         grid. *plot_number* starts at 1, increments across rows first and has a
2716         maximum of ``nrows * ncols``.
2717 
2718         In the case when *nrows*, *ncols* and *plot_number* are all less than 10,
2719         a convenience exists, such that the a 3 digit number can be given instead,
2720         where the hundreds represent *nrows*, the tens represent *ncols* and the
2721         units represent *plot_number*. For instance::
2722 
2723           subplot(211)
2724 
2725         place the plot in the top grid location (i.e. the
2726         first) in a 2 row by 1 column notional grid (no grid actually exists,
2727         but conceptually this is how the returned subplot has been positioned).
2728 
2729 
2730         """
2731 
2732         w = 0
2733         h = 0
2734         x = 0
2735         y = 0
2736         n = 0
2737 
2738         if len(args) == 1:
2739             h = args[0]/100
2740             w = (args[0]%100)/10
2741             n = args[0]%10
2742         elif len(args) == 3:
2743             h = args[0]
2744             w = args[1]
2745             n = args[2]
2746         else:
2747             w = h = n = 1
2748 
2749         x = (n-1)%w
2750         y = (n-1)/w
2751 
2752         size = (1.0/w, 1.0/h)
2753         pos = (x/float(w)+0.5/w, y/float(h)+0.5/h)
2754 
2755         self.set_pos(pos)
2756         self.set_size(size)
2757 
2758     def set_rotation(self, rot):
2759         """ Set the rotation of the item.
2760 
2761         This is equivalent to setting Dimensions>Rotation within a view item dialog.
2762 
2763         """
2764         self.client.send_si(self.handle, b2str("setRotation("+b2str(rot)+")"))
2765 
2766     def remove(self):
2767         """ This removes the object from Kst. """
2768         self.client.send("eliminate("+self.handle+")")
2769 
2770 
2771 # LABELS ######################################################################
2772 class Label(ViewItem):
2773     r"""
2774     A label inside kst.
2775 
2776     :param text: the text of the label.  Supports scalars, equations, and a
2777                  LaTeX subset.
2778     :param pos: a 2 element tuple ``(x, y)`` specifying the position.
2779                 (0, 0) is top left.  (1, 1) is bottom right.
2780     :param rot: rotation of the label in degrees.
2781     :param font_size: size of the label in points, when the printed at the
2782                      reference size.
2783     :param font_color: Colors are given by a name such as ``red`` or a
2784                       hex number such as ``#FF0000``.
2785     :param font_family: The font family.  eg, TimeNewRoman.
2786 
2787     Scalars and scalar equations can be displayed live in labels.
2788     When the scalar is updated, the label is updated.
2789 
2790 
2791     The format is::
2792 
2793         Scalar:         [scalarname]         eg [GYRO1:Mean(X4)]
2794         Vector Element: [vectorName[index]]  eg [GYRO1 (V2)[4]]
2795         Equation:       [=equation]          eg [=[GYRO1:Mean(X4)]/[GYRO1:Sigma (X4)]]
2796 
2797 
2798     These numerical fields can be formatted by appending a C printf format embedded
2799     in { } immediately after the field. For example::
2800 
2801         [GYRO1:Mean(X4)]{%4.2f}
2802 
2803     Labels in kst support a derrivitive subset of LaTeX. For example, to display
2804     the equation for the area of a circle, you could set the label to ``A=2\pir^2``.
2805     Unlike LaTeX, it is not necessary to enter math mode using ``$``. Also,
2806     unlike LaTeX, variables are not automatically displayed in italic font.
2807     If desired, this must be done explicitly using ``\\textit{}``.
2808 
2809     Greek letters: \\\\name or \\\\Name. eg: ``\\alpha``
2810 
2811     Other symbols: ``\\approx, \\cdot, \\ge, \\geq, \\inf, \\approx, \\cdot,
2812     \\ge, \\geq, \\inf, \\int, \\le, \\leq, \\ne, \\n, \\partial, \\prod, \\pm,
2813     \\sum, \\sqrt``
2814 
2815     Font effects: ``\\textcolor{colorname}{colored text}, \\textbf{bold text},
2816     \\textit{italicized text}, \\underline{underlined text},
2817     \\overline{overlined text}.``
2818 
2819     Other:``x^y``, ``x_y``, ``\\t``, ``\\n``, ``\\[``
2820 
2821     This class represents a label you would create via "Create>Annotations>Label"
2822     from the menubar inside kst.
2823 
2824     Use the convenience function in Client to create a label "Test Label" in kst::
2825 
2826       import pykst as kst
2827       client = kst.Client()
2828       L = client.new_label("Test Label", (0.25, 0.25), font_size=18)
2829 
2830     """
2831     def __init__(self, client, text, pos=(0.5, 0.5), rot=0, font_size=12,
2832                  bold=False, italic=False, font_color="black",
2833                  font_family="Serif", name="", new=True):
2834         ViewItem.__init__(self, client)
2835 
2836         if new:
2837             self.client.send("newLabel()")
2838             self.handle = self.client.send("endEdit()")
2839             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2840 
2841             self.set_text(text)
2842             self.set_label_font_size(font_size)
2843             self.set_pos(pos)
2844             self.set_fixed_aspect_ratio(True)
2845             self.set_rotation(rot)
2846             self.set_font_color(font_color)
2847             self.set_font_family(font_family)
2848 
2849             self.set_font_bold(bold)
2850             self.set_font_italic(italic)
2851             self.set_name(name)
2852         else:
2853             self.handle = name
2854 
2855     def set_text(self, text):
2856         r""" Set text displayed by the label.
2857 
2858         Scalars and scalar equations can be displayed live in labels.
2859         When the scalar is updated, the label is updated.
2860         The format is::
2861 
2862           Scalar:         [scalarname]         eg [GYRO1:Mean(X4)]
2863           Vector Element: [vectorName[index]]  eg [GYRO1 (V2)[4]]
2864           Equation:       [=equation]          eg [=[GYRO1:Mean(X4)]/[GYRO1:Sigma (X4)]]
2865 
2866         Labels in kst support a derrivitive subset of LaTeX. For example,
2867         to display the equation for the area of a circle, you could set the
2868         label to ``A=2\pir^2``. Unlike LaTeX, it is not necessary to enter
2869         math mode using ``$``. Also, unlike LaTeX, variables are not
2870         automatically displayed in italic font.  If desired, this must be done
2871         explicitly using ``\\textit{}``.
2872 
2873         Greek letters: \\\\name or \\\\Name. eg: ``\\alpha``
2874 
2875         Other symbols: ``\\approx, \\cdot, \\ge, \\geq, \\inf, \\approx, \\cdot,
2876         \\ge, \\geq, \\inf, \\int, \\le, \\leq, \\ne, \\n, \\partial, \\prod, \\pm,
2877         \\sum, \\sqrt``
2878 
2879         Font effects: ``\\textcolor{colorname}{colored text}, \\textbf{bold text},
2880         \\textit{italicized text}, \\underline{underlined text},
2881         \\overline{overlined text}.``
2882 
2883         Other:``x^y``, ``x_y``, ``\\t``, ``\\n``, ``\\[``
2884         """
2885         self.client.send_si(self.handle, b2str("setLabel("+b2str(text)+")"))
2886 
2887     def set_label_font_size(self, size):
2888         """ size of the label in points, when the printed at the reference size."""
2889         self.client.send_si(self.handle, b2str("setFontSize("+b2str(size)+")"))
2890 
2891     def set_font_bold(self, bold=True):
2892         """ . . . """
2893         if bold:
2894             self.client.send_si(self.handle, b2str("checkLabelBold()"))
2895         else:
2896             self.client.send_si(self.handle, b2str("uncheckLabelBold()"))
2897 
2898     def set_font_italic(self, italic=True):
2899         """ . . . """
2900         if italic:
2901             self.client.send_si(self.handle, b2str("checkLabelItalic()"))
2902         else:
2903             self.client.send_si(self.handle, b2str("uncheckLabelItalic()"))
2904 
2905     def set_font_color(self, color):
2906         """ Colors are given by a name such as ``red`` or a hex number such
2907         as ``#FF0000`` """
2908         self.client.send_si(self.handle, b2str("setLabelColor("+b2str(color)+")"))
2909 
2910     def set_font_family(self, family):
2911         """ set the font family.  eg, TimeNewRoman. """
2912         self.client.send_si(self.handle, b2str("setFontFamily("+b2str(family)+")"))
2913 
2914 
2915 class Legend(ViewItem):
2916     """ A legend in a plot in kst.
2917 
2918     : param plot: a plot in kst.
2919     Use the convenience function in Client to create a legend in kst::
2920 
2921       import pykst as kst
2922       client = kst.Client()
2923      ...
2924       P1 = client.new_plot()
2925       L1 = client.new_legend(P1)
2926 
2927     """
2928     def __init__(self, client, plot, name="", new=True):
2929         ViewItem.__init__(self, client)
2930 
2931         if new:
2932             self.client.send("newLegend("+plot.name()+")")
2933             self.handle = self.client.send("endEdit()")
2934             self.handle.remove(0, self.handle.indexOf("ing ")+4)
2935         else:
2936             self.handle = name
2937 
2938     def set_font_size(self, size):
2939         """ size of the label in points, when the printed at the reference size."""
2940         self.client.send_si(self.handle, b2str("setFontSize("+b2str(size)+")"))
2941 
2942     def set_font_bold(self, bold=True):
2943         """ . . . """
2944         if bold:
2945             self.client.send_si(self.handle, b2str("checkLabelBold()"))
2946         else:
2947             self.client.send_si(self.handle, b2str("uncheckLabelBold()"))
2948 
2949     def set_font_italic(self, italic=True):
2950         """ . . . """
2951         if italic:
2952             self.client.send_si(self.handle, b2str("checkLabelItalic()"))
2953         else:
2954             self.client.send_si(self.handle, b2str("uncheckLabelItalic()"))
2955 
2956     def set_font_color(self, color):
2957         """ Colors are given by a name such as ``red`` or a hex number such
2958         as ``#FF0000`` """
2959         self.client.send_si(self.handle, b2str("setLegendColor("+b2str(color)+")"))
2960 
2961     def set_font_family(self, family):
2962         """ set the font family.  eg, TimeNewRoman. """
2963         self.client.send_si(self.handle, b2str("setFontFamily("+b2str(family)+")"))
2964 
2965 
2966 class Box(ViewItem):
2967     """ A floating box inside kst.
2968 
2969     :param pos: a 2 element tuple ``(x, y)`` specifying the position.
2970                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
2971     :param size: a 2 element tuple ``(w, h)`` specifying the size.
2972                 ``(1, 1)`` is the size of the window.
2973     :param rotation: rotation of the label in degrees.
2974     :param fill_color: the background color.
2975     :param fill_style: the background fill style.  See set_fill_style.
2976     :param stroke_style: see set_stroke_style
2977     :param stroke_width: the pen width for the box outline.
2978     :param stroke_brush_color: the box outline color
2979     :param stroke_brush_style: see set_stroke_brush_style
2980     :param stroke_join_style: see set_stroke_join_style
2981     :param stroke_cap_style: see set_stroke_cap_style
2982     :param fix_aspect: if true, the box will have a fixed aspect ratio.
2983 
2984     Colors are given by a name such as ``red`` or a hex number such
2985     as ``#FF0000``.
2986 
2987     This class represents a box you would create via "Create>Annotations>Box"
2988     from the menubar inside kst.
2989 
2990     Use the convenience function in Client to create a box in kst::
2991 
2992       import pykst as kst
2993       client = kst.Client()
2994       ...
2995       B = client.new_box((0.25, 0.25), (0.2, 0.1), fill_color="blue")
2996 
2997     """
2998     def __init__(self, client, pos=(0.1, 0.1), size=(0.1, 0.1), rot=0,
2999                  fill_color="white", fill_style=1, stroke_style=1, stroke_width=1,
3000                  stroke_brush_color="black", stroke_brush_style=1,
3001                  stroke_join_style=1, stroke_cap_style=1, fix_aspect=False,
3002                  name="", new=True):
3003         ViewItem.__init__(self, client)
3004 
3005         if new:
3006             self.client.send("newBox()")
3007             self.handle = self.client.send("endEdit()")
3008             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3009 
3010             self.set_pos(pos)
3011             self.set_size(size)
3012 
3013             self.set_fixed_aspect_ratio(fix_aspect)
3014             self.set_rotation(rot)
3015 
3016             self.set_stroke_brush_color(stroke_brush_color)
3017             self.set_fill_color(fill_color)
3018             self.set_fill_style(fill_style)
3019             self.set_stroke_style(stroke_style)
3020             self.set_stroke_width(stroke_width)
3021             self.set_stroke_brush_color(stroke_brush_color)
3022             self.set_stroke_brush_style(stroke_brush_style)
3023             self.set_stroke_join_style(stroke_join_style)
3024             self.set_stroke_cap_style(stroke_cap_style)
3025             self.set_name(name)
3026         else:
3027             self.handle = name
3028 
3029 
3030 class Circle(ViewItem):
3031     """ A floating circle inside kst.
3032 
3033     :param pos: a 2 element tuple ``(x, y)`` specifying the position.
3034                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
3035     :param diameter: the diameter of the circle.  1 is the width of the window.
3036     :param fill_color: the background color.
3037     :param fill_style: the background fill style.  See set_fill_style.
3038     :param stroke_style: see set_stroke_style
3039     :param stroke_width: the pen width for the circle outline.
3040     :param stroke_brush_color: the circle outline color
3041     :param stroke_brush_style: see set_stroke_brush_style
3042 
3043     Colors are given by a name such as ``red`` or a hex number such
3044     as ``#FF0000``.
3045 
3046     This class represents a circle you would create via
3047     "Create>Annotations>Circle" from the menubar inside kst.
3048 
3049     Use the convenience function in Client to create a circle in kst::
3050 
3051       import pykst as kst
3052       client = kst.Client()
3053       ...
3054       Cr = client.new_circle((0.5, 0.5), 0.2, fill_color="red")
3055 
3056     """
3057     def __init__(self, client, pos=(0.1, 0.1), diameter=0.1,
3058                  fill_color="white", fill_style=1, stroke_style=1,
3059                  stroke_width=1, stroke_brush_color="grey", stroke_brush_style=1,
3060                  name="", new=True):
3061         ViewItem.__init__(self, client)
3062 
3063         if new:
3064             self.client.send("newCircle()")
3065             self.handle = self.client.send("endEdit()")
3066             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3067 
3068             self.set_pos(pos)
3069             self.set_diameter(diameter)
3070 
3071             self.set_stroke_brush_color(stroke_brush_color)
3072             self.set_fill_color(fill_color)
3073             self.set_fill_style(fill_style)
3074             self.set_stroke_style(stroke_style)
3075             self.set_stroke_width(stroke_width)
3076             self.set_stroke_brush_color(stroke_brush_color)
3077             self.set_stroke_brush_style(stroke_brush_style)
3078             self.set_name(name)
3079         else:
3080             self.handle = name
3081 
3082 
3083     def set_diameter(self, diameter):
3084         """ set the diamter of the circle.
3085 
3086         The width of the window is 1.0.
3087         """
3088         self.client.send_si(self.handle, "setSize("+b2str(diameter)+","+b2str(diameter)+")")
3089 
3090 class Ellipse(ViewItem):
3091     """ A floating ellipse inside kst.
3092 
3093     :param pos: a 2 element tuple ``(x, y)`` specifying the position.
3094                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
3095     :param size: a 2 element tuple ``(w, h)`` specifying the size.
3096                 ``(1, 1)`` is the size of the window.
3097     :param fill_color: the background color.
3098     :param fill_style: the background fill style.  See set_fill_style.
3099     :param stroke_style: see set_stroke_style
3100     :param stroke_width: the pen width for the ellipse outline.
3101     :param stroke_brush_color: the ellipse outline color
3102     :param stroke_brush_style: see set_stroke_brush_style
3103 
3104     Colors are given by a name such as ``red`` or a hex number such
3105     as ``#FF0000``.
3106 
3107     This class represents an ellipse you would create via
3108     "Create>Annotations>Ellipse" from the menubar inside kst.
3109 
3110     Use the convenience function in Client to create an Ellipse in kst::
3111 
3112       import pykst as kst
3113       client = kst.Client()
3114       ...
3115       E = client.new_ellipse((0.25, 0.25), (0.2, 0.1), fill_color="green")
3116 
3117     """
3118     def __init__(self, client, pos=(0.1, 0.1), size=(0.1, 0.1),
3119                  rot=0, fill_color="white", fill_style=1, stroke_style=1,
3120                  stroke_width=1, stroke_brush_color="black", stroke_brush_style=1,
3121                  fix_aspect=False, name="", new=True):
3122         ViewItem.__init__(self, client)
3123 
3124         if new:
3125             self.client.send("newEllipse()")
3126             self.handle = self.client.send("endEdit()")
3127             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3128 
3129             self.set_pos(pos)
3130             self.set_size(size)
3131             if fix_aspect:
3132                 self.set_fixed_aspect_ratio(True)
3133             else:
3134                 self.set_fixed_aspect_ratio(False)
3135 
3136             self.set_rotation(rot)
3137 
3138             self.set_stroke_brush_color(stroke_brush_color)
3139             self.set_fill_color(fill_color)
3140             self.set_fill_style(fill_style)
3141             self.set_stroke_style(stroke_style)
3142             self.set_stroke_width(stroke_width)
3143             self.set_stroke_brush_color(stroke_brush_color)
3144             self.set_stroke_brush_style(stroke_brush_style)
3145             self.set_name(name)
3146         else:
3147             self.handle = name
3148 
3149 
3150 class Line(ViewItem):
3151     """ A floating line inside kst.
3152 
3153     :param start: a 2 element tuple ``(x, y)`` specifying the position of the
3154                   start of the line.
3155                   ``(0, 0)`` is top left of the window, and ``(1, 1)`` is bottom right.
3156     :param end: a 2 element tuple ``(x, y)`` specifying the position of the
3157                 end of the line.
3158                 ``(0, 0)`` is top left of the window, and ``(1, 1)`` is bottom right.
3159     :param length: The length of the line.  1 is the width of the window.
3160     :param rot: rotation of the line in degrees.
3161     :param stroke_style: see set_stroke_style
3162     :param stroke_width: the pen width for the ellipse outline.
3163     :param stroke_brush_color: the ellipse outline color
3164     :param stroke_brush_style: see set_stroke_brush_style
3165     :param stroke_cap_style: see set_stroke_cap_style
3166 
3167     Colors are given by a name such as ``red`` or a hex number such
3168     as ``#FF0000``.
3169 
3170     This class represents a line you would create via "Create>Annotations>Line"
3171     from the menubar inside kst.
3172 
3173     Colors are given by a name such as ``red`` or a hex number such as ``#FF0000``".
3174 
3175     Use the convenience function in Client to create a line in kst::
3176 
3177       import pykst as kst
3178       client = kst.Client()
3179       ...
3180       Ln = client.new_line((0.25, 0.25), (0.5, 0.5))
3181 
3182     """
3183     def __init__(self, client, start=(0, 0), end=(1, 1),
3184                  stroke_style=1, stroke_width=1, stroke_brush_color="black",
3185                  stroke_brush_style=1, stroke_cap_style=1, name="", new=True):
3186         ViewItem.__init__(self, client)
3187 
3188         if new:
3189             self.client.send("newLine()")
3190             self.handle = self.client.send("endEdit()")
3191 
3192             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3193 
3194             self.set_endpoints(start, end)
3195 
3196             self.set_stroke_brush_color(stroke_brush_color)
3197             self.set_stroke_style(stroke_style)
3198             self.set_stroke_width(stroke_width)
3199             self.set_stroke_brush_color(stroke_brush_color)
3200             self.set_stroke_brush_style(stroke_brush_style)
3201             self.set_stroke_cap_style(stroke_cap_style)
3202             self.set_name(name)
3203         else:
3204             self.handle = name
3205 
3206 
3207     def set_length(self, length):
3208         """ set the length of the line.
3209 
3210         The length, between 0 and 1, is as a fraction of the width of the parent item.
3211         """
3212         self.client.send_si(self.handle, "setSize("+b2str(length)+","+b2str(length)+")")
3213 
3214     def set_endpoints(self, start=(0, 0), end=(1, 1)):
3215         """ set the endpoints of the line.
3216 
3217         If lock_pos_to_data has been set True, and the item parent is a plot, then
3218         the coordinates are in terms the data's coordinates.  Otherwise, the coordinates,
3219         between 0 and 1, are relative to the dimensions of the parent object.
3220         """
3221         x1, y1 = start
3222         x2, y2 = end
3223         self.client.send_si(self.handle, "setLineEndpoints("+b2str(x1)+","+b2str(y1)+","+
3224                             b2str(x2)+","+b2str(y2)+")")
3225 
3226 class Arrow(ViewItem):
3227     """ A floating arrow inside kst.
3228 
3229     :param pos: a 2 element tuple ``(x, y)`` specifying the position of the
3230                 center of the line.
3231                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
3232     :param length: The length of the line.  1 is the width of the window.
3233     :param rot: rotation of the line in degrees.
3234     :param arror_at_start: if True, draw an arrow at the start of the line.
3235     :param arrow_at_end: if True, draw an arrow at the end of the line.
3236     :param arrow_size: the size of the arrow.
3237     :param stroke_style: see set_stroke_style.
3238     :param stroke_width: the pen width for the ellipse outline.
3239     :param stroke_brush_color: the ellipse outline color
3240     :param stroke_brush_style: see set_stroke_brush_style
3241     :param stroke_cap_style: see set_stroke_cap_style
3242 
3243     Colors are given by a name such as ``red`` or a hex number such
3244     as ``#FF0000``.
3245 
3246     This class represents an arrow you would create via
3247     "Create>Annotations>Arrow" from the menubar inside kst.
3248 
3249     Use the convenience function in Client to create an arrow in kst::
3250 
3251       import pykst as kst
3252       client = kst.Client()
3253       ...
3254       Ln = client.new_arrow((0.25, 0.25), 0.2, rot=15, arror_at_start=True)
3255 
3256     """
3257     def __init__(self, client, start=(0, 0), end=(1, 1),
3258                  arror_at_start=False, arrow_at_end=True, arrow_size=12.0,
3259                  stroke_style=1, stroke_width=1, stroke_brush_color="black",
3260                  stroke_brush_style=1, stroke_cap_style=1, name="", new=True):
3261         ViewItem.__init__(self, client)
3262 
3263         if new:
3264             self.client.send("newArrow()")
3265             self.handle = self.client.send("endEdit()")
3266             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3267 
3268             self.set_endpoints(start, end)
3269             #self.set_pos(pos)
3270             #self.set_length(length)
3271             #self.set_rotation(rot)
3272 
3273             self.set_stroke_brush_color(stroke_brush_color)
3274             self.set_stroke_style(stroke_style)
3275             self.set_stroke_width(stroke_width)
3276             self.set_stroke_brush_color(stroke_brush_color)
3277             self.set_stroke_brush_style(stroke_brush_style)
3278             self.set_stroke_cap_style(stroke_cap_style)
3279             self.set_arrow_at_start(arror_at_start)
3280             self.set_arrow_at_end(arrow_at_end)
3281             self.set_arrow_size(arrow_size)
3282             self.set_name(name)
3283         else:
3284             self.handle = name
3285 
3286     def set_arrow_at_start(self, arrow=True):
3287         """ Set whether an arrow head is shown at the start of the line """
3288         if arrow:
3289             self.client.send_si(self.handle, b2str("arrowAtStart(True)"))
3290         else:
3291             self.client.send_si(self.handle, b2str("arrowAtStart(False)"))
3292 
3293     def set_arrow_at_end(self, arrow=True):
3294         """ Set whether an arrow head is shown at the end of the line """
3295         if arrow:
3296             self.client.send_si(self.handle, b2str("arrowAtEnd(True)"))
3297         else:
3298             self.client.send_si(self.handle, b2str("arrowAtEnd(False)"))
3299 
3300     def set_arrow_size(self, arrow_size):
3301         self.client.send_si(self.handle, b2str("arrowHeadScale("+b2str(arrow_size)+")"))
3302 
3303     def set_length(self, length):
3304         """ set the length of the line.
3305 
3306         The width of the window is 1.0.
3307         """
3308         self.client.send_si(self.handle, "setSize("+b2str(length)+","+b2str(length)+")")
3309 
3310     def set_endpoints(self, start=(0, 0), end=(1, 1)):
3311         """ set the endpoints of the arrow.
3312 
3313         If lock_pos_to_data has been set True, and the item parent is a plot, then the
3314         coordinates are in terms the data's coordinates.  Otherwise, the coordinates,
3315         between 0 and 1, are relative to the dimensions of the parent object.
3316         """
3317         x1, y1 = start
3318         x2, y2 = end
3319         self.client.send_si(self.handle, "setLineEndpoints("+b2str(x1)+","+b2str(y1)+","+
3320                             b2str(x2)+","+b2str(y2)+")")
3321 
3322 
3323 class Picture(ViewItem):
3324     """ A floating image inside kst.
3325 
3326     :param filename: the file which holds the image to be shown.
3327     :param pos: a 2 element tuple ``(x, y)`` specifying the position of the
3328                 center of the picture.
3329                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
3330     :param width: The width of the picture.  1 is the width of the window.
3331     :param rot: rotation of the picture in degrees.
3332 
3333     This class represents a picture you would create via
3334     "Create>Annotations>Picture" from the menubar inside kst.
3335 
3336     Use the convenience function in Client to create a picture in kst::
3337 
3338       import pykst as kst
3339       client = kst.Client()
3340       ...
3341       pic = client.new_picture("image.jpg", (0.25, 0.25), 0.2)
3342 
3343     BUG: the aspect ratio of the picture is wrong.
3344     """
3345     def __init__(self, client, filename, pos=(0.1, 0.1), width=0.1, rot=0,
3346                  name="", new=True):
3347         ViewItem.__init__(self, client)
3348 
3349         if new:
3350             self.client.send("newPicture("+b2str(filename)+")")
3351             self.handle = self.client.send("endEdit()")
3352 
3353             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3354 
3355             self.set_pos(pos)
3356             self.set_width(width)
3357             self.set_fixed_aspect_ratio(True)
3358             self.set_rotation(rot)
3359             self.set_name(name)
3360         else:
3361             self.handle = name
3362 
3363     def set_width(self, width):
3364         """ set the width of the picture.
3365 
3366         The width of the window is 1.0.
3367         """
3368         self.client.send_si(self.handle, "setSize("+b2str(width)+")")
3369 
3370 
3371     def set_picture(self, pic):
3372         """ BUG: aspect ratio is not changed. There is no parellel for this
3373         function within the kst GUI. """
3374         self.client.send_si(self.handle, b2str("setPicture("+b2str(pic)+")"))
3375 
3376 
3377 class SVG(ViewItem):
3378     """ A floating svg image inside kst.
3379 
3380     :param filename: the file which holds the svg image to be shown.
3381     :param pos: a 2 element tuple ``(x, y)`` specifying the position of the
3382                 center of the picture.
3383                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
3384     :param width: The width of the picture.  1 is the width of the window.
3385     :param rot: rotation of the picture in degrees.
3386 
3387     This class represents a picture you would create via
3388     "Create>Annotations>SVG" from the menubar inside kst.
3389 
3390     Use the convenience function in Client to create an SVG picture in kst::
3391 
3392       import pykst as kst
3393       client = kst.Client()
3394       ...
3395       svg1 = client.new_SVG("image.svg", (0.25, 0.25), 0.2)
3396 
3397     """
3398     def __init__(self, client, filename, pos=(0.1, 0.1), width=0.1, rot=0,
3399                  name="", new=True):
3400         ViewItem.__init__(self, client)
3401 
3402         if new:
3403             self.client.send("newSvgItem("+b2str(filename)+")")
3404             self.handle = self.client.send("endEdit()")
3405 
3406             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3407 
3408             self.set_pos(pos)
3409             self.set_width(width)
3410             self.set_fixed_aspect_ratio(True)
3411             self.set_rotation(rot)
3412             self.set_name(name)
3413         else:
3414             self.handle = name
3415 
3416     def set_width(self, width):
3417         """ set the width of the picture.
3418 
3419         The width of the window is 1.0.
3420         """
3421         self.client.send_si(self.handle, "setSize("+b2str(width)+")")
3422 
3423 
3424 class Plot(ViewItem):
3425     """ A plot inside kst.
3426 
3427     :param pos: a 2 element tuple ``(x, y)`` specifying the position.
3428                 ``(0, 0)`` is top left.  ``(1, 1)`` is bottom right.
3429     :param size: a 2 element tuple ``(w, h)`` specifying the size.
3430                 ``(1, 1)`` is the size of the window.
3431     :param font_size: font size for labels in the plot.  kst default if 0.
3432     :param rotation: rotation of the label in degrees.
3433     :param columns: auto-place the plot, reformatting into this many columns.
3434     :param fill_color: the background color.
3435     :param fill_style: the background fill style.  See set_fill_style.
3436     :param stroke_style: see set_stroke_style
3437     :param stroke_width: the pen width for the plot outline.
3438     :param stroke_brush_color: the plot outline color
3439     :param stroke_brush_style: see set_stroke_brush_style
3440     :param stroke_join_style: see set_stroke_join_style
3441     :param stroke_cap_style: see set_stroke_cap_style
3442     :param fix_aspect: if true, the plot will have a fixed aspect ratio.
3443     :param auto_postion: if True (the default) the plot will be auto-placed.  Ignored if pos is set.
3444 
3445     Colors are given by a name such as ``red`` or a hex number such
3446     as ``#FF0000``.
3447 
3448     This class represents a Plot you would create via
3449     "Create>Annotations>Plot" from the menubar inside kst.
3450 
3451     To create an plot in kst and plot a curve ``curve1``::
3452 
3453       import pykst as kst
3454       client = kst.Client()
3455       ...
3456       P1 = client.new_plot((0.25, 0.25), (0.5, 0.5))
3457       P1.add(curve1)
3458 
3459     """
3460     def __init__(self, client, pos=(0, 0), size=(0, 0), rot=0,
3461                  font_size=0,
3462                  columns=0,
3463                  fill_color="white", fill_style=1, stroke_style=1, stroke_width=1,
3464                  stroke_brush_color="black", stroke_brush_style=1,
3465                  stroke_join_style=1, stroke_cap_style=1, fix_aspect=False,
3466                  auto_position=True,
3467                  name="", new=True):
3468         ViewItem.__init__(self, client)
3469 
3470         if size != (0, 0):
3471             auto_position = False
3472 
3473         if new:
3474             self.client.send("newPlot()")
3475             if columns > 0:
3476                 self.client.send("addToCurrentView(Columns,"+b2str(columns)+")")
3477             elif auto_position:
3478                 self.client.send("addToCurrentView(Auto,2)")
3479             else:
3480                 self.client.send("addToCurrentView(Protect,2)")
3481             self.handle = self.client.send("endEdit()")
3482 
3483             self.handle.remove(0, self.handle.indexOf("ing ")+4)
3484             if size != (0, 0):
3485                 self.set_size(size)
3486                 self.set_pos(pos)
3487 
3488             self.set_global_font(font_size=font_size)
3489             self.set_fixed_aspect_ratio(fix_aspect)
3490             self.set_rotation(rot)
3491 
3492             self.set_stroke_brush_color(stroke_brush_color)
3493             self.set_fill_color(fill_color)
3494             self.set_fill_style(fill_style)
3495             self.set_stroke_style(stroke_style)
3496             self.set_stroke_width(stroke_width)
3497             self.set_stroke_brush_color(stroke_brush_color)
3498             self.set_stroke_brush_style(stroke_brush_style)
3499             self.set_stroke_join_style(stroke_join_style)
3500             self.set_stroke_cap_style(stroke_cap_style)
3501             self.set_name(name)
3502         else:
3503             self.handle = name
3504 
3505 
3506     def add(self, relation):
3507         """ Add a curve or an image to the plot. """
3508         self.client.send_si(self.handle, "addRelation(" + relation.handle + ")")
3509 
3510     def set_x_range(self, x0, x1):
3511         """ Set X zoom range from x0 to x1 """
3512         self.client.send_si(self.handle, "setXRange("+b2str(x0)+","+b2str(x1)+")")
3513 
3514     def set_y_range(self, y0, y1):
3515         """ Set Y zoom range from y0 to y1 """
3516         self.client.send_si(self.handle, "setYRange("+b2str(y0)+","+b2str(y1)+")")
3517 
3518     def set_x_auto(self):
3519         """ Set X zoom range to autoscale """
3520         self.client.send_si(self.handle, "setXAuto()")
3521 
3522     def set_y_auto(self):
3523         """ Set Y zoom range to autoscale """
3524         self.client.send_si(self.handle, "setPlotYAuto()")
3525 
3526     def set_x_auto_border(self):
3527         """ Set X zoom range to autoscale with a small border """
3528         self.client.send_si(self.handle, "setPlotXAutoBorder()")
3529 
3530     def set_y_auto_border(self):
3531         """ Set Y zoom range to autoscale with a small border """
3532         self.client.send_si(self.handle, "setYAutoBorder()")
3533 
3534     def set_x_no_spike(self):
3535         """ Set X zoom range to spike insensitive autoscale """
3536         self.client.send_si(self.handle, "setXNoSpike()")
3537 
3538     def set_y_no_spike(self):
3539         """ Set Y zoom range to spike insensitive autoscale """
3540         self.client.send_si(self.handle, "setYNoSpike()")
3541 
3542     def set_x_ac(self, r):
3543         """ Set X zoom range to fixed range, centered around the mean.
3544 
3545         Similar to AC coupling on an oscilloscope.
3546         """
3547         self.client.send_si(self.handle, "setXAC("+b2str(r)+")")
3548 
3549     def set_y_ac(self, r):
3550         """ Set Y zoom range to fixed range, centered around the mean.
3551 
3552         Similar to AC coupling on an oscilloscope.
3553         """
3554         self.client.send_si(self.handle, "setYAC("+b2str(r)+")")
3555 
3556     def set_global_font(self, family="", font_size=0, bold=False, italic=False):
3557         """ Set the global plot font.
3558 
3559         By default, the axis labels all use this, unless they have been set
3560         to use their own.
3561 
3562         If the parameter 'family' is empty, the font family will be unchanged.
3563         If the parameter 'font_size' is 0, the font size will be unchanged.
3564         The font will be bold if parameter 'bold' is set to 'bold' or 'True'.
3565         The font will be italic if parameter 'italic' is set to 'italic'
3566         or 'True'.
3567         """
3568         self.client.send_si(self.handle, "setGlobalFont("+family+","+
3569                             b2str(font_size)+","+b2str(bold)+","+b2str(italic)+")")
3570 
3571     def set_top_label(self, label=""):
3572         """ Set the plot top label """
3573         self.client.send_si(self.handle, "setTopLabel("+label+")")
3574 
3575     def set_bottom_label(self, label=""):
3576         """ Set the plot bottom label """
3577         self.client.send_si(self.handle, "setBottomLabel("+label+")")
3578 
3579     def set_left_label(self, label=""):
3580         """ Set the plot left label """
3581         self.client.send_si(self.handle, "setLeftLabel("+label+")")
3582 
3583     def set_right_label(self, label=""):
3584         """ Set the plot right label """
3585         self.client.send_si(self.handle, "setRightLabel("+label+")")
3586 
3587     def set_top_label_auto(self):
3588         """ Set the top label to auto generated. """
3589         self.client.send_si(self.handle, "setTopLabelAuto()")
3590 
3591     def set_bottom_label_auto(self):
3592         """ Set the bottom label to auto generated. """
3593         self.client.send_si(self.handle, "setBottomLabelAuto()")
3594 
3595     def set_left_label_auto(self):
3596         """ Set the left label to auto generated. """
3597         self.client.send_si(self.handle, "setLeftLabelAuto()")
3598 
3599     def set_right_label_auto(self):
3600         """ Set the right label to auto generated. """
3601         self.client.send_si(self.handle, "setRightLabelAuto()")
3602 
3603     def normalize_x_to_y(self):
3604         """ Adjust the X zoom range so X and Y have the same scale
3605         per unit (square pixels) """
3606         self.client.send_si(self.handle, "normalizeXtoY()")
3607 
3608     def set_log_x(self, log_mode=True):
3609         """ Set X axis to log mode. """
3610         self.client.send_si(self.handle, "setLogX("+b2str(log_mode) + ")")
3611 
3612     def set_log_y(self, log_mode=True):
3613         """ Set Y axis to log mode. """
3614         self.client.send_si(self.handle, "setLogY("+b2str(log_mode) + ")")
3615 
3616     def set_y_axis_reversed(self, axis_reversed=True):
3617         """ set the Y axis to decreasing from bottom to top. """
3618         if axis_reversed:
3619             self.client.send_si(self.handle, "setYAxisReversed()")
3620         else:
3621             self.client.send_si(self.handle, "setYAxisNotReversed()")
3622 
3623     def set_x_axis_reversed(self, reversed=True):
3624         """ set the X axis to decreasing from left to right. """
3625         if reversed:
3626             self.client.send_si(self.handle, "setXAxisReversed()")
3627         else:
3628             self.client.send_si(self.handle, "setXAxisNotReversed()")
3629 
3630     def set_x_axis_interpretation(self, interp="ctime"):
3631         """ Interpret the x axis as time
3632 
3633         :param interp: interpret the time as follows
3634 
3635         interp can be::
3636 
3637           ctime: Standard unix C time
3638           year:  Decimal year
3639           jd:    Julian Date
3640           mjd:   Modified Julian Date
3641           excel: Time as used by MS Excel
3642 
3643         """
3644         self.client.send_si(self.handle, "setXAxisInterpretation("+interp+")")
3645 
3646     def clear_x_axis_interpretation(self):
3647         """ do not intepret the x axis as time """
3648         self.client.send_si(self.handle, "clearXAxisInterpretation()")
3649 
3650     def set_x_axis_display(self, display="yyyy/MM/dd h:mm:ss ap"):
3651         """ if the x axis has been interpreted as time, set the display.
3652 
3653         Display Types::
3654 
3655           year:              display the decimal year
3656           qttextdtehhmmss:   <Qt Text Date> HH:MM:SS.SS
3657           qtlocaldatehhmmss: <Qt Local Date> HH:MM:SS.SS
3658           jd:                Julian Date
3659           mjd:               Modified Julian Date
3660           All others:        custom format
3661 
3662         The custom format is defined as::
3663 
3664           d         the day as number without a leading zero (1 to 31)
3665           dd        the day as number with a leading zero (01 to 31)
3666           ddd       the abbreviated localized day name (e.g. 'Mon' to 'Sun').
3667                     Uses the system locale to localize the name, i.e. QLocale::system().
3668           dddd      the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
3669                     Uses the system locale to localize the name, i.e. QLocale::system().
3670           M         the month as number without a leading zero (1-12)
3671           MM        the month as number with a leading zero (01-12)
3672           MMM       the abbreviated localized month name (e.g. 'Jan' to 'Dec').
3673                     Uses the system locale to localize the name, i.e. QLocale::system().
3674           MMMM      the long localized month name (e.g. 'January' to 'December').
3675                     Uses the system locale to localize the name, i.e. QLocale::system().
3676           yy        the year as two digit number (00-99)
3677           yyyy      the year as four digit number
3678           h         the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
3679           hh        the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
3680           H         the hour without a leading zero (0 to 23, even with AM/PM display)
3681           HH        the hour with a leading zero (00 to 23, even with AM/PM display)
3682           m         the minute without a leading zero (0 to 59)
3683           mm        the minute with a leading zero (00 to 59)
3684           s         the second without a leading zero (0 to 59)
3685           ss        the second with a leading zero (00 to 59)
3686           z         the milliseconds without leading zeroes (0 to 999)
3687           zzz       the milliseconds with leading zeroes (000 to 999)
3688           AP or A   use AM/PM display. A/AP will be replaced by either "AM" or "PM".
3689           ap or a   use am/pm display. a/ap will be replaced by either "am" or "pm".
3690           t         the timezone (for example "CEST")
3691 
3692            """
3693 
3694         self.client.send_si(self.handle, "setXAxisDisplay("+display+")")
3695 
3696 
3697 class Button(ViewItem):
3698     """ This represents a button inside a View. When the button is pressed, it sends a
3699     message via a socket.
3700 
3701     socket is a QtNetwork.QLocalSocket that is not connected to anything. The message
3702     "clicked" will be sent when the button is pressed. See the bonjourMonde example. """
3703     def __init__(self, client, text, socket, posX=0.1, posY=0.1, sizeX=0.1, sizeY=0.1, rot=0):
3704         ViewItem.__init__(self, client)
3705         self.client.send("newButton()")
3706         self.client.send("setPos("+b2str(posX)+","+b2str(posY)+")")
3707         self.client.send("setSize("+b2str(sizeX)+","+b2str(sizeY)+")")
3708         self.client.send("setText("+b2str(text)+")")
3709         self.client.send("setRotation("+b2str(rot)+")")
3710         self.handle = self.client.send("endEdit()")
3711 
3712         self.handle.remove(0, self.handle.indexOf("ing ")+4)
3713         socket.connectToServer(client.server_name)
3714         socket.waitForConnected(300)
3715         socket.write(b2str("attachTo("+self.handle+")"))
3716 
3717     def set_text(self, text):
3718         """ Sets the text of the button. """
3719         self.client.send("beginEdit("+self.handle+")")
3720         self.client.send("setText("+b2str(text)+")")
3721         self.client.send("endEdit()")
3722 
3723 
3724 
3725 
3726 
3727 class LineEdit(ViewItem):
3728     """ This represents a line edit inside a View. When the lineedit's value is changed,
3729     it sends a message via a socket.
3730 
3731     socket is a QtNetwork.QLocalSocket that is not connected to anything. The message
3732     "valueSet:VAL" where VAL is some text will be sent when the text is changed.
3733     See the ksNspire example. """
3734     def __init__(self, client, text, socket, posX=0.1, posY=0.1, sizeX=0.1, sizeY=0.1, rot=0):
3735         ViewItem.__init__(self, client)
3736         self.client.send("newLineEdit()")
3737         self.client.send("setPos("+b2str(posX)+","+b2str(posY)+")")
3738         self.client.send("setSize("+b2str(sizeX)+","+b2str(sizeY)+")")
3739         self.client.send("setText("+b2str(text)+")")
3740         self.client.send("setRotation("+b2str(rot)+")")
3741         self.handle = self.client.send("endEdit()")
3742 
3743         self.handle.remove(0, self.handle.indexOf("ing ")+4)
3744         socket.connectToServer(b2str(client.server_name))
3745         socket.waitForConnected(300)
3746         socket.write(b2str("attachTo("+self.handle+")"))
3747 
3748     def set_text(self, text):
3749         """ Sets the text of the line edit. """
3750         self.client.send("beginEdit("+self.handle+")")
3751         self.client.send("setText("+b2str(text)+")")
3752         self.client.send("endEdit()")