Exemplo n.º 1
0
    def _createRunningDialog(self) -> None:
        """Create and show the running dialog in another thread.
        
        Note: Make sure to set the `DMView.progress_max` before calling this 
        function!

        Notes
        -----
        This function creates a dialog that is running in the current dm-script
        main thread. UI components always run in the main thread!
        """
        path = os.path.join(self._rel_path, "dm_view_progress_dialog.s")
        sv = {
            "max_progress": self.progress_max,
            "progress_tn": self._progress_dialog_progress_tagname,
            "text_tn": self._progress_dialog_text_tagname,
            "success_tn": self._progress_dialog_success_tagname,
            "kill_tn": self._progress_dialog_kill_tagname
        }
        self._created_tagnames.add(self._progress_dialog_progress_tagname)
        self._created_tagnames.add(self._progress_dialog_success_tagname)
        self._created_tagnames.add(self._progress_dialog_text_tagname)

        log_debug(self._logger,
                  ("Showing running dialog by executing " +
                   "dmscript '{}' with setvars '{}'").format(path, sv))
        with execdmscript.exec_dmscript(path,
                                        setvars=sv,
                                        debug=self._exec_debug):
            pass
Exemplo n.º 2
0
    def _createKillDialog(self) -> None:
        """A dialog that shows the kill button only."""

        id_ = int(time.time() * 100)
        dmscript = "\n".join((
            "class handler_{} : UIFrame {{".format(id_),
            "void killTaks(object self){",
            "if(!GetPersistentTagGroup().TagGroupDoesTagExist(\"{}\")){{".
            format(self._progress_dialog_kill_tagname),
            "GetPersistentTagGroup().TagGroupCreateNewLabeledTag(\"{}\");".
            format(self._progress_dialog_kill_tagname),
            "}",
            "GetPersistentTagGroup().TagGroupSetTagAsBoolean(\"{}\", 1);".
            format(self._progress_dialog_kill_tagname),
            "}",
            "}",
            "TagGroup Dialog = DLGCreateDialog(\"Kill task\");",
            "TagGroup kill_button = DLGCreatePushButton(\"Kill Task\", \"killTaks\");",
            "Dialog.DLGAddElement(kill_button);",
            "object kill_dialog = alloc(handler_{}).init(Dialog)".format(id_),
            "kill_dialog.display(\"Kill task\");",
        ))
        self._created_tagnames.add(self._progress_dialog_kill_tagname)

        log_debug(self._logger,
                  "Creating kill dialg by executing dmscript '{}'")
        with execdmscript.exec_dmscript(dmscript, debug=self._exec_debug):
            pass
Exemplo n.º 3
0
    def showError(self,
                  error: typing.Union[str, Exception],
                  how_to_fix: typing.Optional[str] = None) -> None:
        """Show the user a hint.

        Raises
        ------
        StopProgram
            When the user clicks the cancel button.
        
        Parameters
        ----------
        hint : str
            The text to show
        how_to_fix : str, optional
            A text that helps the user to interpret and avoid this error,
            default: None
        """
        msg = ""
        if isinstance(error, Exception):
            try:
                msg = type(error).__name__
            except:
                pass

        if msg == "":
            msg = "Error"

        msg += ": " + str(error)

        print(msg)
        print("  Fix:", how_to_fix)

        self.print(msg)
        self.print("  Fix:", how_to_fix)

        if isinstance(error, Exception):
            traceback.print_exc()
            log_error(self._logger, error)
        elif do_log(self._logger, logging.ERROR):
            self._logger.error(msg)

        if isinstance(how_to_fix, str) and how_to_fix != "":
            msg += "\n\nPossible Fix:\n{}".format(how_to_fix)

        dmscript = "showAlert(msg, 0);"
        setvars = setvars = {"msg": msg}
        log_debug(
            self._logger, "Executing dmscript '{}' with setvars '{}'".format(
                dmscript, setvars))
        with execdmscript.exec_dmscript(dmscript,
                                        setvars=setvars,
                                        debug=self._exec_debug):
            pass
Exemplo n.º 4
0
    def _createNewWorkspace(
            self,
            name: typing.Optional[str] = None,
            activate: typing.Optional[bool] = True) -> typing.Tuple[int, str]:
        """Create a new workspace and save the workspace id.
        
        Parameters
        ----------
        name : str, optional
            The workspace name, if not given the `config.PROGRAM_NAME` with a
            trailing number is used, default: None
        activate : bool, optional
            Whether to set the new workspace as the active one, default: True
        
        Returns
        -------
        int, str
            The id of the new workspace and the name
        """

        from pylo.config import PROGRAM_NAME

        if not isinstance(name, str) or name == "":
            name = "{} {}".format(PROGRAM_NAME, DMCamera.workspace_number + 1)

        dmscript = [
            "number wsid = WorkspaceAdd(0);",
            "WorkspaceSetName(wsid, \"{}\");".format(
                execdmscript.escape_dm_string(name)),
        ]

        if activate:
            dmscript.append("WorkspaceSetActive(wsid);")

        dmscript = "\n".join(dmscript)

        readvars = {"wsid": int}

        logginglib.log_debug(self._logger,
                             ("Creating new workspace by " +
                              "executing dmscript '{}' with " +
                              "readvars '{}'").format(dmscript, readvars))

        with execdmscript.exec_dmscript(dmscript, readvars=readvars) as script:
            self._workspace_id = script["wsid"]
            DMCamera.workspace_number += 1

        logginglib.log_debug(self._logger,
                             ("New workspace with id '{}' and " +
                              "name '{}'.").format(self._workspace_id, name))

        return self._workspace_id, name
Exemplo n.º 5
0
    def _ensureWorkspace(self,
                         name: typing.Optional[str] = None,
                         activate_new: typing.Optional[bool] = True,
                         force_active: typing.Optional[bool] = False) -> None:
        """Ensure that the `DMCamera._workspace_id` exists.

        If the workspace does not exist, it is created.
        
        Parameters
        ----------
        name : str, optional
            The workspace name, if not given the `config.PROGRAM_NAME` with a
            trailing number is used, default: None
        activate_new : bool, optional
            Whether to set the workspace new as the active one, default: True
        force_active : bool, optional
            Whether to set the workspace as active also if it already exists,
            default: False
        """

        logginglib.log_debug(self._logger,
                             ("Checking if workspace id '{}' " +
                              "is valid").format(self._workspace_id))

        if (not isinstance(self._workspace_id, int)
                or DM.WorkspaceCountWindows(self._workspace_id) == 0):
            # either the workspace id does not exist or it exists but the user
            # closed the workspace already
            logginglib.log_debug(self._logger,
                                 ("Workspace with id '{}' does " +
                                  "not exist, creating a new " +
                                  "one.").format(self._workspace_id))

            self._createNewWorkspace(activate_new)

            # reset shown images if a new workspace is created
            DMImage.shown_images_counter = 0
        elif force_active:
            setvars = {"wsid": self._workspace_id}
            dmscript = "WorkspaceSetActive(wsid);"

            logginglib.log_debug(
                self._logger,
                ("Forcing workspace to be " + "active by executing " +
                 "dmscript '{}' with setvars " + "'{}'").format(
                     dmscript, setvars))

            with execdmscript.exec_dmscript(dmscript, setvars=setvars):
                pass
Exemplo n.º 6
0
    def _getWorkspaceRect(self) -> typing.Tuple[int, int, int, int]:
        """Get the available workspace area in GMS.

        Raises
        ------
        LookupError
            When the workspace area could not be detected
        
        Returns
        -------
        tuple of int
            A tuple containing the *top*, *left*, *bottom* and *right* 
            coordinates of the available space for images in the stated order
        """

        log_debug(self._logger, "Trying to get the workspace rect")

        readvars = {"top": int, "left": int, "bottom": int, "right": int}
        dmscript = "\n".join(
            ("number top, left, bottom, right;",
             "GetMaximalDocumentWindowRect(1+2+240, top, left, bottom, right);"
             ))

        log_debug(
            self._logger, "Executing dm-script '{}' with readvars '{}'".format(
                dmscript, readvars))
        workspace_rect = None
        with execdmscript.exec_dmscript(dmscript, readvars=readvars) as script:
            workspace_rect = (script["top"], script["left"], script["bottom"],
                              script["right"])

        log_debug(self._logger, ("Found workspace rect to be " +
                                 "'{}'").format(workspace_rect))

        if not isinstance(workspace_rect, tuple):
            err = LookupError("Could not detect the workspace area in GMS.")
            log_error(self._logger, err)
            raise err

        return workspace_rect
Exemplo n.º 7
0
    def showHint(self, hint: str) -> None:
        """Show the user a hint.

        Raises
        ------
        StopProgram
            When the user clicks the cancel button.
        
        Parameters
        ----------
        hint : str
            The text to show
        """
        dmscript = "showAlert(msg, 2);"
        setvars = {"msg": hint}
        log_debug(self._logger,
                  ("Showing alert by executing dmscript '{}' " +
                   "with setvars '{}'").format(dmscript, setvars))
        with execdmscript.exec_dmscript(dmscript,
                                        setvars=setvars,
                                        debug=self._exec_debug):
            pass
Exemplo n.º 8
0
    def getNumberOfWorkspaces() -> int:
        """Get the number of 'Pylo <number>' workspaces

        Returns
        -------
        int
            The number of workspaces whose name starts with the program name
            and ends with a number
        """

        from pylo.config import PROGRAM_NAME

        dmscript = "\n".join(
            (
                "number workspace_number = 0;",
                "for(number i = 0; i < WorkspaceGetCount(); i++){",
                "number wsid = WorkspaceGetFromIndex(i);",
                "string name = WorkspaceGetName(wsid);",
                "if(name.left({}) == \"{}\"){{".format(
                    len(PROGRAM_NAME),
                    execdmscript.escape_dm_string(PROGRAM_NAME)),
                "name = name.right(name.len() - 1 - {});".format(
                    len(PROGRAM_NAME)),
                "if(name.val() > workspace_number){",
                "workspace_number = name.val()",
                "}",
                "}",
                "}",
            ))

        readvars = {"workspace_number": int}

        with execdmscript.exec_dmscript(dmscript, readvars=readvars) as script:
            return script["workspace_number"]

        return 0
Exemplo n.º 9
0
import execdmscript

# set the text in python
world_text = "Hello World!"

# create an executable dm-script code
dmscript = """
OKDialog(text);
result(text);
"""

# save which variables should be passed from python to dm-script and how they should be 
# called
setvars = {
	"text": world_text
}

# execute the script
with execdmscript.exec_dmscript(dmscript, setvars=setvars):
	pass
Exemplo n.º 10
0
import execdmscript

# Tell the dm-script the variables it should know
setvars = {"variable1": 1, "variable2": "B", "variable3": False}

# Get the list of headlines
readvars = {"variable4": str, "variable5": int}

# set your filepath, needs to be the complete path, not just the name!
path = r"C:\testdmscript3.s"

with execdmscript.exec_dmscript(path,
                                setvars=setvars,
                                readvars=readvars,
                                debug=True,
                                debug_file=r"C:\debugfile.s") as script:
    pass
Exemplo n.º 11
0
    def _show(
        self,
        image_doc: DM.Py_ImageDocument,
        workspace_id: typing.Optional[int] = None,
        file_path: typing.Optional[typing.Union[pathlib.PurePath, str]] = None
    ) -> DM.Py_ImageDocument:
        """Show the given image document.

        If the `workspace_id` is given, the image will be shown in this 
        workspace.

        Parameters
        ----------
        image_doc : DigitalMicrograph.Py_ImageDocument
            The image document to show
        workspace_id: int, optional
            The workspace id to show in, if not an int the image will be shown 
            in the current workspace, default: None
        file_path : str or pathlib.PurePath, optional
            The path where the image is
        
        Returns
        -------
        DigitalMicrograph.Py_ImageDocument
            The image document that shows the image
        """
        log_debug(
            self._logger,
            ("Showing image with " +
             "DigitalMicrograph.Py_ImageDocument '{}'").format(image_doc))
        if (isinstance(workspace_id, int)
                and DM.WorkspaceCountWindows(workspace_id) > 0):
            log_debug(
                self._logger,
                "Moving image document '{}' to workspace '{}'".format(
                    image_doc, workspace_id))
            # check if the workspace exists (if not it does not have windows),
            # if the workspace does not exist and ImageDocument.MoveToWorkspace()
            # is called, a RuntimeError is raised
            image_doc.MoveToWorkspace(workspace_id)

        # calculate position depending on the available size and the
        # number of columns
        from .config import DEFAULT_DM_SHOW_IMAGES_ROW_COUNT
        rows = DEFAULT_DM_SHOW_IMAGES_ROW_COUNT

        length = round(
            (self.workspace_rect[2] - self.workspace_rect[0]) / rows)
        cols = math.floor(
            (self.workspace_rect[3] - self.workspace_rect[1]) / length)
        row_index = (DMImage.shown_images_counter // cols) % rows
        col_index = (DMImage.shown_images_counter % cols)
        pos = (self.workspace_rect[0] + row_index * length,
               self.workspace_rect[1] + col_index * length,
               self.workspace_rect[0] + (row_index + 1) * length,
               self.workspace_rect[1] + (col_index + 1) * length)

        log_debug(self._logger,
                  "Setting image document to position '{}'".format(pos))
        # show in the workspace
        image_doc.ShowAtRect(*pos)

        from .config import DM_IMAGE_DISABLE_PYTHON_ANNOTATIONS

        # link to file and/or add annotations
        if (isinstance(file_path, str)
                or isinstance(file_path, pathlib.PurePath)
                or (DM_IMAGE_DISABLE_PYTHON_ANNOTATIONS
                    and isinstance(self.annotations, (list, tuple)))):
            if isinstance(workspace_id, int):
                wsid = workspace_id
            else:
                wsid = ""

            dmscript = []
            if (DM_IMAGE_DISABLE_PYTHON_ANNOTATIONS
                    and isinstance(self.annotations, (list, tuple))):
                # do not link to file because annotations are missing in the
                # file, force user to save the workspace

                log_debug(self._logger, ("Adding annotations in dm-script " +
                                         "after showing the file, not " +
                                         "linking to file because in file " +
                                         "the annotations are missing."))

                from .config import DM_IMAGE_ANNOTATION_COLOR
                from .config import DM_IMAGE_ANNOTATION_PADDING_FRACTION
                from .config import DM_IMAGE_ANNOTATION_SCALEBAR_LENGTH_FRACTION
                from .config import DM_IMAGE_ANNOTATION_HEIGHT_FRACTION
                if (not isinstance(self.annotations_height_fraction, float)
                        or self.annotations_height_fraction <= 0
                        or math.isclose(
                            self.annotations_height_fraction, 0, abs_tol=1e-10)
                        or self.annotations_height_fraction > 1):
                    self.annotations_height_fraction = DM_IMAGE_ANNOTATION_HEIGHT_FRACTION

                dmscript += [
                    "if(img_doc.ImageDocumentCountImages() > 0){",
                    "Image img := img_doc.ImageDocumentGetImage(0);",
                    "ImageDisplay display;",
                    "if(img.ImageCountImageDisplays() == 0){",
                    "display = img_doc.ImageDocumentAddImageDisplay(img, -2);",
                    "}", "else{", "display = img.ImageGetImageDisplay(0);",
                    "}", "Component annotation;",
                    "number image_width = img.ImageGetDimensionSize(0);",
                    "number image_height = img.ImageGetDimensionSize(1);",
                    "number top, left, bottom, right, font_size, t, l, b, r;",
                    "top = (1 - {ah} - {ap}) * image_height".format(
                        ah=self.annotations_height_fraction,
                        ap=DM_IMAGE_ANNOTATION_PADDING_FRACTION),
                    "left = {ap} * image_width".format(
                        ap=DM_IMAGE_ANNOTATION_PADDING_FRACTION),
                    "font_size = {ah} * image_height".format(
                        ah=self.annotations_height_fraction)
                ]

                for annotation in self.annotations:
                    log_debug(self._logger, ("Trying to add annotation " +
                                             "'{}'").format(annotation))

                    if annotation == "scalebar":
                        dmscript += [
                            "bottom = (1 - {ap}) * image_height".format(
                                ap=DM_IMAGE_ANNOTATION_PADDING_FRACTION),
                            "right = left + {sl} * image_width".format(
                                sl=DM_IMAGE_ANNOTATION_SCALEBAR_LENGTH_FRACTION
                            ),
                            "annotation = NewComponent(31, top, left, bottom, right);"
                        ]
                    else:
                        dmscript += [
                            "annotation = NewTextAnnotation(left, top, \"{}\", font_size);"
                            .format(execdmscript.escape_dm_string(annotation))
                        ]

                    dmscript += [
                        "annotation.ComponentSetForegroundColor({r}, {g}, {b})"
                        .format(r=DM_IMAGE_ANNOTATION_COLOR[0],
                                g=DM_IMAGE_ANNOTATION_COLOR[1],
                                b=DM_IMAGE_ANNOTATION_COLOR[2]),
                        "display.ComponentAddChildAtEnd(annotation);",
                        "annotation.ComponentGetBoundingRect(t, l, b, r);",
                        "left = r + {ap} * image_width;".format(
                            ap=DM_IMAGE_ANNOTATION_PADDING_FRACTION)
                    ]

                dmscript += ["}"]
            else:
                log_debug(self._logger,
                          "Trying to link image document to the file")
                dmscript = [
                    "if(path != \"\"){",
                    "img_doc.ImageDocumentSetCurrentFile(path);",
                    "if(format != \"\"){",
                    "img_doc.ImageDocumentSetCurrentFileSaveFormat(format);",
                    "}", "img_doc.ImageDocumentClean();", "}"
                ]

            dmscript = "\n".join([
                "number wsid = {}".format(
                    "WorkspaceGetActive();" if wsid ==
                    "" else wsid), "if(WorkspaceGetIndex(wsid) >= 0){",
                "for(number i = CountImageDocuments(wsid) - 1; i >= 0; i--){",
                "ImageDocument img_doc = GetImageDocument(i, wsid);",
                "if(img_doc.ImageDocumentGetName() == name){"
            ] + dmscript + ["break;", "}", "}", "}"])

            if (isinstance(file_path, str)
                    or isinstance(file_path, pathlib.PurePath)):
                _, extension = os.path.splitext(file_path)

                if extension in DMImage.gatan_file_types:
                    file_format = DMImage.gatan_file_types[extension]
                else:
                    file_format = ""
            else:
                file_path = ""
                file_format = ""

            svars = {
                "name": image_doc.GetName(),
                "path": file_path,
                "format": file_format
            }

            log_debug(
                self._logger,
                "Executing dmscript '{}' with setvars '{}'".format(
                    dmscript, svars))
            with execdmscript.exec_dmscript(dmscript, setvars=svars):
                pass

        DMImage.shown_images_counter += 1

        return image_doc
Exemplo n.º 12
0
import execdmscript

import urllib.request
import html.parser
import re

# get the text of example.com
content = str(urllib.request.urlopen("https://www.example.com/").read())

# get all headlines
matches = re.findall(r"<h([\d])>([^<]+)</h\1>", content)
if matches is not None:
    headlines = [x[1] for x in matches]
    text = "Headlines:\n- " + "\n- ".join(headlines)
else:
    headlines = []
    text = "*No headlines found*"

# Tell the dm-script the variables it should know
setvars = {"text": text}

# set your filepath, needs to be the complete path, not just the name!
path = r"C:\testdmscript.s"

with execdmscript.exec_dmscript(path, setvars=setvars):
    pass
Exemplo n.º 13
0
    def _showDialog(
            self,
            measurement_variables: typing.Optional[
                typing.List["MeasurementVariable"]] = None,
            series: typing.Optional[dict] = None,
            start: typing.Optional[dict] = None,
            configuration: typing.Optional[AbstractConfiguration] = None,
            ask_for_values: typing.Optional[typing.Sequence[AskInput]] = None,
            ask_for_msg: typing.Optional[str] = "",
            custom_tags: typing.Optional[dict] = {},
            dialog_type: typing.Optional[int] = 0b11):
        """Show the dm-script dialog.

        The base dialog is the same for all dialogs. The `dialog_type` shows 
        which dialog is created in the dm-script code. Only the parameters for
        this dialog are required, the others can be omitted

        Parameters
        ----------
        measurement_variables : list of MeasurementVariable
            The measurement variables that the current microscope supports,
            required for 'series' dialog (`0b0010`)
        series : dict
            The series dict that defines the series that is shown on startup
            with uncalibrated and parsed values, if not given the default 
            values are used, optional for 'series' dialog (`0b0010`), 
            default: None
        start : dict
            The series start definition that is shown on startup  with 
            uncalibrated and parsed values, if not given the default values are 
            used, optional for 'series' dialog (`0b0010`), default: None
        configuration : AbstractConfiguration
            The configuration to get the values of, required for 'configuration'
            dialog (`0b0001`)
        ask_for_values : sequence of dicts
            A sequence of dicts where the dict contains the "datatype" and the 
            "name" index and an optional "description" defining the values 
            to ask the user for, required for 'ask_for' dialog (`0b0100`)
        ask_for_msg : str
            The message to show in the ask for dialog, optional for 'ask_for' 
            dialog (`0b0100`)
        custom_tags : dict of dicts
            The tags dict where the keys are the tag names and the values are 
            dicts with the "value" and "save" indices, required for 
            'custom_tags' dialog (`0b1000`)
        dialog_type : int, optional
            Define which dialog to show, use
            - `0b01` for showing the configuration dialog
            - `0b10` for showing the series dialog
            - `0b01 | 0b10 | 0b1000 = 0b1011` for showing the series dialog 
              but the user can switch to the configuration dialog and the 
              custom tags dialog and back
            - `0b100` for showing the ask for dialog
            - `0b1000` for showing the custom tags dialog
        """

        if (dialog_type & 0b01) > 0 and (dialog_type & 0b10) > 0:
            dialog_startup = ""
        elif (dialog_type & 0b01) > 0:
            dialog_startup = "configuration"
        elif (dialog_type & 0b100) > 0:
            dialog_startup = "ask_for"
        elif (dialog_type & 0b1000) > 0:
            dialog_startup = "custom_tags"
        else:
            dialog_startup = "series"

        log_debug(self._logger, ("Showing dialog with mode '{:b}' which is " +
                                 "converted to '{}' as a string value").format(
                                     dialog_type, dialog_startup))

        if isinstance(measurement_variables, dict):
            measurement_variables = list(measurement_variables.values())

        m_vars = []
        series_def = []

        # add all measurement variables if there are some
        if isinstance(measurement_variables, list):
            var_keys = ("unique_id", "name", "unit", "min_value", "max_value",
                        "start", "end", "step")
            cal_keys = ("name", "unit")
            num_keys = ("start", "step", "end", "min_value", "max_value")

            if not isinstance(series, dict):
                series = {}
            if not isinstance(start, dict):
                start = {}

            series, *_ = MeasurementSteps.formatSeries(measurement_variables,
                                                       series,
                                                       add_default_values=True,
                                                       parse=False,
                                                       uncalibrate=False,
                                                       start=start)

            start, *_ = MeasurementSteps.formatStart(measurement_variables,
                                                     start,
                                                     series,
                                                     add_default_values=True,
                                                     parse=False,
                                                     uncalibrate=False)

            series_nests = list(MeasurementSteps.getSeriesNests(series))
            series_def = list(map(lambda s: s["variable"], series_nests))

            for var in measurement_variables:
                m_var = {}

                if var.unique_id in series_def:
                    i = series_def.index(var.unique_id)
                    fake_series = series_nests[i]

                    if "on-each-point" in fake_series:
                        # not used and just more formatting overhead
                        del fake_series["on-each-point"]
                else:
                    fake_series = {"variable": var.unique_id}

                if var.unique_id in start:
                    fake_series["start"] = start[var.unique_id]

                defaults, *_ = MeasurementSteps.formatSeries(
                    measurement_variables,
                    fake_series,
                    add_default_values=True,
                    parse=False,
                    uncalibrate=False)

                for name in var_keys:
                    val = None

                    if name == "step":
                        key = "step-width"
                    else:
                        key = name

                    if var.has_calibration and name in cal_keys:
                        n = "calibrated_{}".format(name)
                        if hasattr(var, n) and getattr(var, n) != None:
                            val = getattr(var, n)

                    if val is None and key in defaults:
                        val = defaults[key]

                    if val is None and hasattr(var, name):
                        val = getattr(var, name)

                    if name in num_keys and val != "":
                        if var.has_calibration:
                            val = var.ensureCalibratedValue(float(val))

                            if (var.calibrated_format is not None
                                    and isinstance(var.calibrated_format,
                                                   Datatype)):
                                m_var["formatted_{}".format(name)] = (
                                    var.calibrated_format.format(val))

                        elif (var.format is not None
                              and isinstance(var.format, Datatype)):
                            m_var["formatted_{}".format(name)] = (
                                var.format.format(val))

                    if val == None:
                        val = ""
                    elif not isinstance(val, (bool, str, float, int)):
                        val = str(val)

                    m_var[name] = val

                if var.has_calibration:
                    if isinstance(var.calibrated_format, OptionDatatype):
                        m_var["format"] = "options"
                        m_var["options"] = var.calibrated_format.options
                    elif var.has_calibration and var.calibrated_format is not None:
                        m_var["format"] = get_datatype_name(
                            var.calibrated_format)
                elif isinstance(var.format, OptionDatatype):
                    m_var["format"] = "options"
                    m_var["options"] = var.format.options
                elif var.format is not None:
                    m_var["format"] = get_datatype_name(var.format)

                m_vars.append(m_var)

        config_vars = {}
        if isinstance(configuration, AbstractConfiguration):
            for group in configuration.getGroups():
                if (not group in config_vars
                        or not isinstance(config_vars[group], dict)):
                    config_vars[group] = {}

                for key in configuration.getKeys(group):
                    try:
                        val = configuration.getValue(group, key)
                    except KeyError:
                        val = ""

                    try:
                        var_type = configuration.getDatatype(group, key)
                    except KeyError:
                        var_type = str

                    if isinstance(var_type, OptionDatatype):
                        var_type_name = "options"
                    else:
                        var_type_name = get_datatype_name(var_type)

                    # make sure the vaue is valid, parse it and then format it
                    # again
                    val = parse_value(var_type, val)
                    val = format_value(var_type, val)

                    try:
                        default_value = configuration.getDefault(group, key)
                    except KeyError:
                        default_value = ""

                    try:
                        description = configuration.getDescription(group, key)
                    except KeyError:
                        description = ""

                    try:
                        ask_if_not_present = configuration.getAskIfNotPresent(
                            group, key)
                    except KeyError:
                        ask_if_not_present = False

                    try:
                        restart_required = configuration.getRestartRequired(
                            group, key)
                    except KeyError:
                        restart_required = False

                    config_vars[group][key] = {
                        "value": val,
                        "default_value": default_value,
                        "datatype": var_type_name,
                        "description": str(description),
                        "ask_if_not_present": ask_if_not_present,
                        "restart_required": restart_required,
                    }

                    if isinstance(var_type, OptionDatatype):
                        config_vars[group][key]["options"] = var_type.options

        ask_vals = []
        if isinstance(ask_for_values, (tuple, list)):
            for input_definition in ask_for_values:
                input_definition = input_definition.copy()
                if "datatype" in input_definition:
                    if isinstance(input_definition["datatype"],
                                  OptionDatatype):
                        input_definition["options"] = input_definition[
                            "datatype"].options
                        input_definition["datatype"] = "options"
                    elif not isinstance(input_definition["datatype"], str):
                        if hasattr(input_definition["datatype"], "name"):
                            input_definition["datatype"] = input_definition[
                                "datatype"].name
                        elif hasattr(input_definition["datatype"], "__name__"):
                            input_definition["datatype"] = input_definition[
                                "datatype"].__name__
                        else:
                            input_definition["datatype"] = str(
                                input_definition["datatype"])
                    else:
                        input_definition["datatype"] = "string"
                else:
                    input_definition["datatype"] = "string"

                ask_vals.append(input_definition)

        variables = {
            "m_vars": m_vars,
            "series_def": series_def,
            "config_vars": config_vars,
            "ask_vals": ask_vals,
            "message": ask_for_msg,
            "dialog_startup": dialog_startup,
            "custom_tag_vals": custom_tags
        }

        path = os.path.join(self._rel_path, "dm_view_dialog.s")
        sync_vars = {
            "start": dict,
            "series": dict,
            "configuration": dict,
            "ask_for": list,
            "custom_tags": dict,
            "success": bool
        }
        libs = (os.path.join(self._rel_path, "pylolib.s"), )

        start = None
        series = None
        config = None
        ask_for_values = None
        custom_tags = None
        success = None

        log_debug(self._logger, ("Executing dm libs '{}' and dmscript '{}' " +
                                 "with readvars '{}' and setvars '{}'").format(
                                     libs, path, sync_vars, variables))

        # shows the dialog (as a dm-script dialog) in dm_view_series_dialog.s
        # and sets the start and series variables
        with execdmscript.exec_dmscript(*libs,
                                        path,
                                        readvars=sync_vars,
                                        setvars=variables,
                                        debug=self._exec_debug) as script:
            try:
                success = bool(script["success"])
            except KeyError:
                success = False

            if isinstance(measurement_variables, list):
                try:
                    series = script["series"]
                except KeyError:
                    series = None

                if series is not None:
                    series = MeasurementSteps.formatSeries(
                        measurement_variables,
                        series,
                        add_default_values=False,
                        parse=True,
                        uncalibrate=True)
                else:
                    series = None

            if isinstance(measurement_variables, list):
                try:
                    start = script["start"]
                except KeyError:
                    start = None

                if start is not None and series is not None:
                    start = MeasurementSteps.formatStart(
                        measurement_variables,
                        start,
                        series,
                        add_default_values=False,
                        parse=True,
                        uncalibrate=True)
                else:
                    start = None

            try:
                config = script["configuration"]
            except KeyError:
                config = None

            try:
                ask_for_values = script["ask_for"]
            except KeyError:
                ask_for_values = None

            try:
                custom_tags = script["custom_tags"]
            except KeyError:
                custom_tags = None

        if success and ((start is not None and series is not None)
                        or config is not None or ask_for_values is not None
                        or custom_tags is not None):
            log_debug(self._logger,
                      ("Returning start '{}', series '{}', " +
                       "config '{}', ask_for_values '{}' and " +
                       "custom_tags '{}'").format(start, series, config,
                                                  ask_for_values, custom_tags))
            return start, series, config, ask_for_values, custom_tags
        else:
            err = StopProgram()
            log_debug(self._logger, "Stopping program", exc_info=err)
            raise err
Exemplo n.º 14
0
    def askForDecision(
        self,
        text: str,
        options: typing.Optional[typing.Sequence[str]] = ("Ok", "Cancel")
    ) -> int:
        """Ask for a decision between the given `options`.

        The `options` are shown to the user depending on the view 
        implementation. In most of the times this are the buttons shown on a 
        dialog.

        The selected index will be returned.

        Raises
        ------
        ValueError
            When the `options` is empty
        StopProgram
            When the view is closed in another way (e.g. the close icon of a 
            dialog is clicked)
        
        Parameters
        ----------
        text : str
            A text that is shown to the users to explain what they are deciding
        options : sequence of str
            The texts to show to the users they can select from
        
        Returns
        -------
        int
            The selected index
        """

        if len(options) == 0:
            raise ValueError("The options must not be empty.")
        elif len(options) == 2:
            dmscript = "number index = TwoButtonDialog(text, button0, button1);"
            readvars = {"index": int}
            setvars = {
                "text": text,
                "button0": options[0],
                "button1": options[1]
            }

            log_debug(self._logger,
                      ("Asking for decision by executing " +
                       "dmscript '{}' with setvars '{}' and " +
                       "readvars '{}'").format(dmscript, setvars, readvars))
            with execdmscript.exec_dmscript(dmscript,
                                            setvars=setvars,
                                            readvars=readvars,
                                            debug=self._exec_debug) as script:
                index = script["index"]

                # for dm-script the buttons are the "confirm" and the "cancel"
                # buttons, so the left button (button0 in this case) is always
                # true, the right button (button1 in this case) is always false
                # which are, converted to int, 0 and 1 in the exact other way
                # than this function is retunring its values
                if index == 0:
                    index = 1
                elif index == 1:
                    index = 0
        else:
            id_ = "__pylo_pressed_button_{}".format(int(time.time() * 100))
            setvars = {
                "text": text,
                "persistent_tag_name": id_,
                "title": "Please select"
            }
            self._created_tagnames.add(id_)

            dmscript_button_pressed_handlers = []
            dmscript_button_creations = []

            for i, o in enumerate(options):
                setvars["button{}".format(i)] = o
                dmscript_button_pressed_handlers.append(
                    ("void button{i}_pressed(object self){{" +
                     "self.button_pressed({i});" + "}}").format(i=i))
                dmscript_button_creations.append((
                    "b = DLGCreatePushButton(button{i}, \"button{i}_pressed\");"
                    + "b.DLGWidth(80);" +
                    "wrapper.DLGAddElement(b);").format(i=i))

            dmscript = "\n".join([
                "class ButtonDialog : UIFrame{",
                "void button_pressed(object self, number i){",
                "if(GetPersistentTagGroup().TagGroupDoesTagExist(persistent_tag_name)){",
                "GetPersistentTagGroup().TagGroupDeleteTagWithLabel(persistent_tag_name);",
                "}",
                "GetPersistentTagGroup().TagGroupCreateNewLabeledTag(persistent_tag_name);",
                "GetPersistentTagGroup().TagGroupSetTagAsShort(persistent_tag_name, i);",
                "self.close();", "exit(0);", "}", ""
            ] + dmscript_button_pressed_handlers + [
                ""
                "object init(object self){",
                "TagGroup dlg, dlg_items, wrapper, label, b;",
                "dlg = DLGCreateDialog(title, dlg_items);", "",
                "dlg_items.DLGAddElement(DLGCreateLabel(text));", "",
                "wrapper = DLGCreateGroup();",
                "wrapper.DLGTableLayout({}, 1, 1);".format(len(
                    options)), "dlg_items.DLGAddElement(wrapper);", ""
            ] + dmscript_button_creations + [
                "", "self.super.init(dlg);", "return self;", "}", "}",
                "alloc(ButtonDialog).init().display(title);"
            ])

            log_debug(self._logger,
                      ("Asking for decision by executing " +
                       "dmscript '{}' with setvars '{}' and " +
                       "readvars '{}'").format(dmscript, setvars, readvars))
            log_debug(
                self._logger,
                "Deleting persistent tag with label " + "'{}'".format(id_))
            DM.GetPersistentTagGroup().DeleteTagWithLabel(id_)
            with execdmscript.exec_dmscript(dmscript,
                                            setvars=setvars,
                                            debug=self._exec_debug):
                # wait for dm-script to show the dialog, the user takes longer
                # to react anyway
                time.sleep(0.5)

            log_debug(self._logger, ("Repetitively checking persistent tag " +
                                     "'{}' as a short").format(id_))
            while DM is not None:
                s, v = DM.GetPersistentTagGroup().GetTagAsShort(id_)

                if s:
                    index = v
                    DM.GetPersistentTagGroup().DeleteTagWithLabel(id_)
                    log_debug(self._logger,
                              ("Found tag '{}' with value '{}', " +
                               "deleted it now.").format(id_, v))
                    break

                time.sleep(0.1)

        if 0 <= index and index < len(options):
            log_debug(
                self._logger, "User was asked '{}' and clicked '{}'".format(
                    text, options[index]))
            return index
        else:
            err = StopProgram()
            log_debug(self._logger, "Stopping program", exc_info=err)
            raise err
Exemplo n.º 15
0
    setvars = {
        "b": -193.3288,
        "tg4": {
            "test-key 1": 1,
            "test-key 2": {
                "test-key 3": False,
                "test-key 4": None
            }
        },
        "tl6": ["A", "B", ["U", "V"], (-101, -120)]
    }

    with execdmscript.exec_dmscript(script1,
                                    script2,
                                    script3,
                                    readvars=readvars,
                                    setvars=setvars,
                                    separate_thread=False,
                                    debug=False,
                                    debug_file=None) as script:
        for key in script.synchronized_vars.keys():
            print("Variable '", key, "'")
            pprint.pprint(script[key])

    # wrapper = execdmscript.DMScriptWrapper(script1, script2, script3,
    # 										 readvars=readvars, setvars=setvars)
    #
    # exec_script = wrapper.getExecDMScriptCode()
    #
    # print("The following script is being executed:")
    # print(exec_script)
except Exception as e:
Exemplo n.º 16
0
			self.super.init(Dialog);
			return self;
		}
	}
	// do not move this in the thread part, this will not work anymore
	object progress_dlg = alloc(ProgressDialog).init();
	
	"""
	exec_script = """
	if(!GetPersistentTagGroup().TagGroupDoesTagExist("__progress")){
		GetPersistentTagGroup().TagGroupCreateNewLabeledTag("__progress");
		GetPersistentTagGroup().TagGroupSetTagAsLong("__progress", 0);
	}
	
	progress_dlg.pose();
	
	if(GetPersistentTagGroup().TagGroupDoesTagExist("__progress")){
		GetPersistentTagGroup().TagGroupDeleteTagWithLabel("__progress");
	}
	RemoveMainThreadTask(update_task);
	"""
	with exec_dmscript(dialog_script, separate_thread=(exec_script, ), debug=False) as script:
		pass
		
	thread.join()
except Exception as e:
	# dm-script error messages are very bad, use this for getting the error text and the 
	# correct traceback
	print("Exception: ", e)
	import traceback
	traceback.print_exc()
Exemplo n.º 17
0
import execdmscript

dmscript1 = "number c = a + b;"
dmscript2 = "number d = c + a;"
dmscript3 = r"C:\testdmscript5.s"

setvars = {"a": 1, "b": 2}
readvars = {"c": int, "d": int, "e": int}

with execdmscript.exec_dmscript(dmscript1, dmscript2, dmscript3, setvars=setvars, 
								readvars=readvars) as script:
	print("c:", script["c"])
	print("d:", script["d"])
	print("e:", script["e"])
Exemplo n.º 18
0
    # whether to add another tag
    add_tag = True
    while add_tag:
        # ask for the tag name and value
        tag_name = input("Please enter a tag name to add to the image")
        tag_value = input(
            "Please enter the value for the tag '{}'".format(tag_name))

        tags[tag_name] = tag_value

        tag_str = execdmscript.escape_dm_string(pprint.pformat(tags))
        print(tag_str)

        # ask whether to add another tag
        add_tag = False
        with execdmscript.exec_dmscript(dm_code.format(tag_str),
                                        readvars={"add_tag": int}) as script:
            add_tag = script["add_tag"]

    # convert the tags to a tag group object
    tags = execdmscript.convert_to_taggroup(tags)
    # apply the tag group object to the image
    img.GetTagGroup().DeleteAllTags()
    img.GetTagGroup().CopyTagsFrom(tags)

    img.ShowImage()
except Exception as e:
    # dm-script error messages only show the error type but not the message
    print("Exception: ", e)

    import traceback
    traceback.print_exc()
Exemplo n.º 19
0
import execdmscript

# `a` and `b` are given in python
a = 10
b = 20

# This is the dm-script to execute
dmscript = "number c = a + b;"

# This are the variables the upper dm-script will know
setvars = {"a": a, "b": b}

# This are the variables this python script will know after the execution
readvars = {"c": int}

with execdmscript.exec_dmscript(dmscript, setvars=setvars,
                                readvars=readvars) as script:
    # now we can access `c` because it is set in the `readvars`
    print(script["c"])