1

I want to get the file path of the current file in Digital Micrograph in python. How do I do this?


I tried to use

__file__

but I get NameError: Name not found globally.

I tried to use the dm-script GetCurrentScriptSourceFilePath() with the following code to get the value to python

import DigitalMicrograph as DM
import time
    
# get the __file__ by executing dm-scripts GetCurrentScriptSourceFilePath()
# function, then save the value in the persistent tags and delete the key
# again
tag = "__python__file__{}".format(round(time.time() * 100))
DM.ExecuteScriptString(
    "String __file__;\n" + 
    "GetCurrentScriptSourceFilePath(__file__);\n" + 
    "number i = GetPersistentTagGroup().TagGroupCreateNewLabeledTag(\"" + tag + "\");\n" + 
    "GetPersistentTagGroup().TagGroupSetIndexedTagAsString(i, __file__);\n"
);
_, __file__ = DM.GetPersistentTagGroup().GetTagAsString(tag);
DM.ExecuteScriptString("GetPersistentTagGroup().TagGroupDeleteTagWithLabel(\"" + tag + "\");")

but it seems that the GetCurrentScriptSourceFilePath() function does not contain a path (which makes sense because it is executed from a string).

I found this post recommending

import inspect
src_file_path = inspect.getfile(lambda: None)

but the src_file_path is "<string>" which is obviously wrong.

I tried to raise an exception and then get the filename of it with the following code

try:
    raise Exception("No error")
except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    filename = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    print("File: ", filename)

but again I get <string> as the filename.

I tried to get the path out of the script window but I could not find any function to get it. But the script window has to know where its path is, otherwise Ctrl+S cannot work.


Some background

I am developing a module used for Digital Micrograph. There I also have test files. But to import the (still developed) module in the test file(s), I need the path relative to the test file.

Later the module will be installed somewhere so this should not be a problem then. But for offering a compelte set of tests, I want to be able to execute the tests without having to install the (not working) module.

miile7
  • 2,547
  • 3
  • 23
  • 38

3 Answers3

1

For the file path to your current working directory, use:

import os
os.getcwd()
David Collins
  • 848
  • 3
  • 10
  • 28
0

In DM-script, which you could call from a Python script, the command GetApplicationDirectory() gives you what you need. Usually, you would want to use the "open_save" one, i.e.

GetApplicationDirectory("open_save",0)

This will return the directory (String variable) that appears when File/Open is used, or File/Save is used on a new image. It is, however, not what is used on a "File/Save Workspace" or other saves.

From the F1 help documentation on that command: enter image description here

Note, that the concept of "current" directory is somewhat broken on Win10 with applications - including GMS.In particular the "SetApplicationDirectory" commands do not always work as expected...


If you want to find out what the folder of a specific, currently shown document is (image or text) you can use the following DM-script. The assumption here is, that the window is the front-most window.

documentwindow win = GetDocumentWindow(0)
if ( win.WindowIsvalid() )
    if ( win.WindowIsLinkedToFile() )
        Result("\n" + win.WindowGetCurrentFile())
    
BmyGuest
  • 6,331
  • 1
  • 21
  • 35
  • So for testing this is enough for me. For others: Note that as soon as you save another file, the "open_save" directory changes to this directory! – miile7 Aug 20 '20 at 13:35
  • @miile7 Well, you could use one of the other "default" directories from the list instead... – BmyGuest Aug 20 '20 at 19:37
  • I need exactly the directory where the executing script file is in because in the same directory there are other python files which i need to import. – miile7 Aug 21 '20 at 08:29
  • ( But also: Just save your script file in any of those locations, i.e. the plugins-folder f.e.. Or a subfolder or relative path to any of those...) – BmyGuest Aug 21 '20 at 19:36
  • That sounds very promising. I will try it out tomorrow. – miile7 Aug 24 '20 at 09:17
0

For everyone who also needs this (and just wants to copy some code) I created the following code based on @BmyGuests answer. This takes the file the script window is bound to and saves it as a persistent tag. This tag is then read from the python file (and the tag is deleted).

Important Note: This only works in the python script window where you press the Execute Script button and only if this file is saved! But from there on you probably are importing scripts which should provide the module.__file__ attribute. This meas this does not work for plugins/libraries.

import DigitalMicrograph as DM

# the name of the tag is used, this is deleted so it shouldn't matter anyway
file_tag_name = "__python__file__"
# the dm-script to execute, double curly brackets are used because of the 
# python format function
script = ("\n".join((
    "DocumentWindow win = GetDocumentWindow(0);",
    "if(win.WindowIsvalid()){{",
        "if(win.WindowIsLinkedToFile()){{",
            "TagGroup tg = GetPersistentTagGroup();",
            "if(!tg.TagGroupDoesTagExist(\"{tag_name}\")){{",
                "number index = tg.TagGroupCreateNewLabeledTag(\"{tag_name}\");",
                "tg.TagGroupSetIndexedTagAsString(index, win.WindowGetCurrentFile());",
            "}}",
            "else{{",
                "tg.TagGroupSetTagAsString(\"{tag_name}\", win.WindowGetCurrentFile());",
            "}}",
        "}}",
    "}}"
))).format(tag_name=file_tag_name)

# execute the dm script
DM.ExecuteScriptString(script)

# read from the global tags to get the value to the python script
global_tags = DM.GetPersistentTagGroup()
if global_tags.IsValid():
    s, __file__ = global_tags.GetTagAsString(file_tag_name);
    if s:
        # delete the created tag again
        DM.ExecuteScriptString(
            "GetPersistentTagGroup()." + 
            "TagGroupDeleteTagWithLabel(\"{}\");".format(file_tag_name)
        )
    else:
        del __file__

try:
    __file__
except NameError:
    # set a default if the __file__ could not be received
    __file__ = ""
    
print(__file__);
miile7
  • 2,547
  • 3
  • 23
  • 38