In the middle of the desert you can say anything you want
In pycharm, updated black to use these args:
--preview --enable-unstable-feature string_processing $FilePath$
The (future of the) Black code style - Black 24.8.0 documentation has both the preview style and the unstable features one can enable (by passing the flag multilple times).
string_processing
breaks long strings into multiple shorter ones, one on each line.
Is ‘file’ a keyword in python? - Stack Overflow
TL;DR python3 doesn’t care about file
, regardless of what syntax highlighters think about this.
TL;DR:
docstring-convention=google
in flake8 config file, ignores there as well together with the rest.pydocstyle / python-flake8-docstrings is a thing. Forgot I had it installed and spent a lot of time trying to understand pycharm’s output
Usage — pydocstyle 0.0.0.dev0 documentation flake8-docstrings · PyPI
To ignore things, you don’t do:
[pydocstyle]
convention = google
ignore = D401
It’s either ignore or convention. Which quietly happened in the background, and I thought it doesn’t read my config file since D401 was still shown.
Correct would be this:
[pydocstyle]
convention = google
add-ignore = D401
EDIT GodDAMN it, pydocsyle parsing a config file doesn’t mean that flake8(-..docstring) will.
Reading the flake8 plugin docs, I should add THIS and to flake8 config file. Ignores also are set up there using the usual way.
docstring-convention=google
And the pydoctest config file search and add-ignore
is irrelevant. God lost so much time to this
EDIT: this may be all wrong, in the debugger I can just edit the code and it gets automatically used by slicer — logical, since it’s just a CLI script.
It’s the .xml with the interface that’s problematic and it can’t be reloaded using the method below, or at least I couldn’t.
A scriptedcli module imported to Slicer doesn’t show for me the usual “reload” buttons as seen in scripted modules in dev. mode. To develop, I need my changes I need to reload it w/o restarting 3dslicer.
Based on this more complete example1 linked in the script repository2
>>> mpath = "/full/path/to/the/my_module.py"
>>> factoryManager = slicer.app.moduleManager().factoryManager()
>>> factoryManager.registerModule(qt.QFileInfo(mpath))
>>> factoryManager.loadModules(["my_module"])
True
BONUS:
import pydevd_pycharm
pydevd_pycharm.settrace('localhost', port=5678, stdoutToServer=True, stderrToServer=True)
os.getpid()
is my friend/opt/pycharm-professional/debug-eggs/pydevd-pycharm.egg
Loads the module automatically (for some reason doing it manually doesn’t preserve it across restarts?..)
Slicer --additional-module-path /path/to/my/extension/one/lower/than/what/i/would/pick/in/Slicer/GUI
logging.warning("test")
in the python console and it worksDifferent types of modules exist: Module Overview — 3D Slicer documentation
In the first tests there was a lot of latency.
Solution: CLI modules (not extensions) that can run in the background and whose status can be queried, which can be added to new extension from extension editor.
Now I understad this better:
scripted
. It’s the sample thresholding extension
I hope it’s the same as type CLI, but only with python
Is a CLI script w/ an XML that has module metadata + examples
Adding it added it to CMakeLists.xml: add_subdirectory(my_scripted_cli)
python dev tools actually show the CLI used to run a CLI module!
can’t debug it the usual way, I guess I’ll have to add the pydevd-pycharm things to the code
[VTK] /opt/3dslicer/bin/python-real /home/.../cli_model_service.py /tmp/Slicer-sh/IACHCI_vtkMRMLScalarVolumeNodeD.nrrd 1 /tmp/Slicer-sh/IACHCI_vtkMRMLScalarVolumeNodeF.nrrd
Slicer/Docs/developer_guide/parameter_nodes/gui_creation.md at main · Slicer/Slicer seems interesting
CLI modules have an interface specified by the .xml file, and the interface is generated based on it
Bits about the XML
channel
is either input
or output
, and only for pics.index
If I read the volume as volume, it uses the .nrrd
file extension by default — and I want .nii
Module from console with arguments - Support - 3D Slicer Community
Slicer.exe --python-code "selectModule('SampleData'); getModuleGui('SampleData').setCategoryVisible('BuiltIn', False)"
Script repository — 3D Slicer documentation:
# Create a new directory where the scene will be saved into
import time
sceneSaveDirectory = slicer.app.temporaryPath + "/saved-scene-" + time.strftime("%Y%m%d-%H%M%S")
if not os.access(sceneSaveDirectory, os.F_OK):
os.makedirs(sceneSaveDirectory)
outputSegmentation.AddDefaultStorageNode()
outputSegmentation.GetStorageNode().SetFileName(output_segmentation_path)
outputSegmentation.GetStorageNode().ReadData(outputSegmentation)
Main links
slicerrc.py is a thing! sample: 3D-Slicer-Scripts/.slicerrc.py at master · jzeyl/3D-Slicer-Scripts · GitHub
Slicer custom application deployment to many computers - Development - 3D Slicer Community
SlicerQReads.exe --python-code "folder='S:\SlicerQREADS\TestImages'; import os; slicer.util.loadVolume(folder + '/' + os.listdir(folder)[0], {'singleFile': False})"
Slicer.exe --python-script "/full/path/to/myscript.py" --no-splash --no-main-window
3Slicer can run in Docker4
Slicer can run in webbrowser5
Slicer can run in jupyter5, including partially (e.g. only a single view etc!)
Slicer --help
:
--testing Activate testing mode. It implies --disable-settings and --ignore-slicerrc. (default: false)
--disable-python Disable python support. This is equivalent to build the application with Slicer_USE_PYTHONQT=OFF.
--python-script Python script to execute after slicer loads.
--python-code Python code to execute after slicer loads.
-c Python code to execute after slicer loads. By default, no modules are loaded and Slicer exits afterward.
--ignore-slicerrc Do not load the Slicer resource file (~/.slicerrc.py).
--additional-module-path Additional module path to consider when searching for modules to load.
--additional-module-paths List of additional module path to consider when searching for modules to load.
Slicer modules — todo, CLI things with easy arguments
Slicer extensions/modules creation
Extension manager
CI/CD exists for extensions published officially
Misc:
Script repository — 3D Slicer documentation has this:
This code snippet can be useful for sharing code in development without requiring a restart of Slicer.
Fazit:
Other bits
Run Slicer in your web browser - as a Jupyter notebook or as a full application - Announcements - 3D Slicer Community ↩︎
GitHub - Slicer/SlicerDocker: Build, package, test, and run 3D Slicer and Slicer Extensions in Docker. ↩︎
Run Slicer in your web browser - as a Jupyter notebook or as a full application - Announcements - 3D Slicer Community ↩︎ ↩︎
inotifywait(1) - Linux man page
#!/bin/sh
while inotifywait --format '%:e %f' p.* *.bib; do
sleep 1 # files get moved often
echo "rsync!"
rsync -avzirh --progress p.* *.bib me@server.net:dir
done
boltctl monitor
shows changes as they happens — nice when something breaks. I used to do a lot of watch boltctl list
before in this exact scenario
(having a monitor
subcommand in your thing says a lot about stuff, actually, — the best interpretation is that it’s written with developers in mind)
Very proud of this idea, haha :)
For absolute positioned elements one needs to “guess” the correct sizes etc., may not be trivial. Using a pixel ruler won’t help because the .absolute coords don’t map to the screen ones.
Solution:
.grid {
// https://stackoverflow.com/questions/4191260/drawing-a-grid-using-css
background-image:
repeating-linear-gradient(lightblue 0 2px, transparent 2px 100%),
repeating-linear-gradient(90deg, lightblue 0 2px, transparent 2px 100%);
background-size: 50px 50px;
//border: 2px solid red;
}
.smallgrid {
background-image:
repeating-linear-gradient(#ccc 0 1px, transparent 1px 100%),
repeating-linear-gradient(90deg, #ccc 0 1px, transparent 1px 100%);
background-size: 10px 10px;
width: 100%;
height: 100%;
}
::::: {.absolute left=0 right=0 top=0 bottom=0 .grid}
::: {.smallgrid}
:::
:::::
It’s not exactly aligned but close enough to judge the widths and heights involved!
Rectangle in the pic is:
:::: {.redrect .absolute right=200 top=130 width=200 height=100}
::::
(And the small grid can be omitted if not needed by removing the div in the middle. )
For bonus points, can be saved as a file and included if needed:
{\{< include ../_shared/smallgrid.qmd >}\}
ALSO:
// show the border of the slide
.reveal .slides {
border: 1px dashed red;
}
DAMN.
:::: {layout="1,1,1],[1],[1,1,1" layout-valign="center"}
if it’s a layout I do get a valign thing. I just have to use layouts, not columns. Damn.