SlicerSegmentEditorExtraEffects icon indicating copy to clipboard operation
SlicerSegmentEditorExtraEffects copied to clipboard

Fast marching effect : crash may occur

Open chir-set opened this issue 4 years ago • 5 comments

I noticed frequent crashes when using 'Fast marching' effect. Sometimes it occurs on first initialization, but most often after 'Cancel', modify 'Maximum volume' parameter and repeat initialization.

It is also volume dependent. I can reproduce it on one sample volume (of good quality), but not with CTA-cardio for example.

Here is a backtrace :

error: libstdc++.so.6 {0x00181389}: DIE has DW_AT_ranges(0x119c8) attribute, but range extraction failed (missing or invalid range list table), please file a bug and attach the file at the start of this error message
Process 111504 stopped
* thread #1, name = 'SlicerApp-real', stop reason = signal SIGSEGV: invalid address (fault address: 0x5555657e6c6c)
    frame #0: 0x00007fff7d907ad4 libvtkSlicerSegmentEditorFastMarchingModuleLogic.so`PichonFastMarchingPDF::update(this=0x000055555aa4aa80) at vtkPichonFastMarchingPDF.cxx:139:14
(lldb) bt
* thread #1, name = 'SlicerApp-real', stop reason = signal SIGSEGV: invalid address (fault address: 0x5555657e6c6c)
  * frame #0: 0x00007fff7d907ad4 libvtkSlicerSegmentEditorFastMarchingModuleLogic.so`PichonFastMarchingPDF::update(this=0x000055555aa4aa80) at vtkPichonFastMarchingPDF.cxx:139:14
    frame #1: 0x00007fff7d90819c libvtkSlicerSegmentEditorFastMarchingModuleLogic.so`PichonFastMarchingPDF::addRealization(this=<unavailable>, k=<unavailable>) at vtkPichonFastMarchingPDF.cxx:224:5
    frame #2: 0x00007fff7d906cb7 libvtkSlicerSegmentEditorFastMarchingModuleLogic.so`vtkPichonFastMarching::addSeedIJK(int, int, int) [inlined] vtkPichonFastMarching::collectInfoSeed(this=0x000055555daa8ad0, index=<unavailable>) at vtkPichonFastMarching.cxx:46:19
    frame #3: 0x00007fff7d906c93 libvtkSlicerSegmentEditorFastMarchingModuleLogic.so`vtkPichonFastMarching::addSeedIJK(this=0x000055555daa8ad0, I=<unavailable>, J=<unavailable>, K=<unavailable>) at vtkPichonFastMarching.cxx:1223
    frame #4: 0x00007fff7d906f1e libvtkSlicerSegmentEditorFastMarchingModuleLogic.so`vtkPichonFastMarching::addSeedsFromImage(this=0x000055555daa8ad0, label=<unavailable>) at vtkPichonFastMarching.cxx:1258:19
    frame #5: 0x00007fff7d913e36 vtkSlicerSegmentEditorFastMarchingModuleLogicPython.so`PyvtkPichonFastMarching_addSeedsFromImage(self=<unavailable>, args=<unavailable>) at vtkPichonFastMarchingPython.cxx:0
    frame #6: 0x00007fffe55d09fc libpython3.6m.so`_PyCFunction_FastCallDict(func_obj=0x00007ffee084b120, args=0x000055555daf5de0, nargs=<unavailable>, kwargs=0x0000000000000000) at methodobject.c:234:22
    frame #7: 0x00007fffe56451bb libpython3.6m.so`call_function(pp_stack=0x00007fffffffb038, oparg=<unavailable>, kwnames=<unavailable>) at ceval.c:4837:9
    frame #8: 0x00007fffe564243e libpython3.6m.so`_PyEval_EvalFrameDefault(f=0x000055555daf5ba8, throwflag=<unavailable>) at ceval.c:3335:19
    frame #9: 0x00007fffe5646492 libpython3.6m.so`fast_function [inlined] PyEval_EvalFrameEx(f=0x000055555daf5ba8, throwflag=0) at ceval.c:754:12
    frame #10: 0x00007fffe5646483 libpython3.6m.so`fast_function [inlined] _PyFunction_FastCall(co=<unavailable>, args=<unavailable>, nargs=2, globals=<unavailable>) at ceval.c:4919
    frame #11: 0x00007fffe564642b libpython3.6m.so`fast_function(func=<unavailable>, stack=<unavailable>, nargs=2, kwnames=<unavailable>) at ceval.c:4954
    frame #12: 0x00007fffe5645194 libpython3.6m.so`call_function(pp_stack=0x00007fffffffb1f8, oparg=<unavailable>, kwnames=<unavailable>) at ceval.c:4858:17
    frame #13: 0x00007fffe564243e libpython3.6m.so`_PyEval_EvalFrameDefault(f=0x00007ffee07ef428, throwflag=<unavailable>) at ceval.c:3335:19
    frame #14: 0x00007fffe5646887 libpython3.6m.so`_PyFunction_FastCallDict(func=<unavailable>, args=<unavailable>, nargs=<unavailable>, kwargs=<unavailable>) at ceval.c:0
    frame #15: 0x00007fffe558e612 libpython3.6m.so`_PyObject_FastCallDict(func=0x00007fff201e09d8, args=0x00007fffffffb360, nargs=1, kwargs=0x0000000000000000) at abstract.c:2310:18
    frame #16: 0x00007fffe558e7b1 libpython3.6m.so`_PyObject_Call_Prepend(func=0x00007fff201e09d8, obj=0x00007ffee074e908, args=<unavailable>, kwargs=0x0000000000000000) at abstract.c:2373:14
    frame #17: 0x00007fffe558e6b4 libpython3.6m.so`_PyObject_FastCallDict(func=0x00007ffee0770088, args=0x0000000000000000, nargs=0, kwargs=0x0000000000000000) at abstract.c:2331:18
    frame #18: 0x00007fffec1c979b libPythonQt.so`PythonQtSignalTarget::call(callable=0x00007ffee0770088, methodInfos=0x000055555624f140, arguments=0x00007fffffffb5a0, skipFirstArgumentOfMethodInfo=<unavailable>) at PythonQtSignalReceiver.cpp:130:14
    frame #19: 0x00007fffec1ca1d1 libPythonQt.so`PythonQtSignalReceiver::qt_metacall(QMetaObject::Call, int, void**) [inlined] PythonQtSignalTarget::call(this=0x000055555d8e78b0, arguments=0x00007fffffffb5a0) const at PythonQtSignalReceiver.cpp:56:22
    frame #20: 0x00007fffec1ca1b9 libPythonQt.so`PythonQtSignalReceiver::qt_metacall(this=0x000055555d8e7320, c=<unavailable>, id=5, arguments=<unavailable>) at PythonQtSignalReceiver.cpp:273
    frame #21: 0x00007ffff644a4f7 libQt5Core.so.5`___lldb_unnamed_symbol4768$$libQt5Core.so.5 + 631
    frame #22: 0x00007ffff6fe25e3 libQt5Widgets.so.5`QAbstractButton::clicked(bool) + 67
    frame #23: 0x00007ffff6fe286c libQt5Widgets.so.5`___lldb_unnamed_symbol1438$$libQt5Widgets.so.5 + 60
    frame #24: 0x00007ffff6fe4474 libQt5Widgets.so.5`___lldb_unnamed_symbol1444$$libQt5Widgets.so.5 + 196
    frame #25: 0x00007ffff6fe4695 libQt5Widgets.so.5`QAbstractButton::mouseReleaseEvent(QMouseEvent*) + 245
    frame #26: 0x00007fffec462a81 libPythonQt.so`PythonQtShell_QPushButton::mouseReleaseEvent(this=0x000055555d8e7070, e0=<unavailable>) at com_trolltech_qt_gui7.cpp:7639:16
    frame #27: 0x00007ffff6f2e0be libQt5Widgets.so.5`QWidget::event(QEvent*) + 526
    frame #28: 0x00007fffec46023c libPythonQt.so`PythonQtShell_QPushButton::event(this=0x000055555d8e7070, e0=<unavailable>) at com_trolltech_qt_gui7.cpp:7111:23
    frame #29: 0x00007ffff6eead62 libQt5Widgets.so.5`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 130
    frame #30: 0x00007ffff6ef2ac9 libQt5Widgets.so.5`QApplication::notify(QObject*, QEvent*) + 2729
    frame #31: 0x00007ffff7c90d0e libqSlicerBaseQTGUI.so`qSlicerApplication::notify(this=<unavailable>, receiver=<unavailable>, event=<unavailable>) at qSlicerApplication.cxx:412:26
    frame #32: 0x00007ffff64133fa libQt5Core.so.5`QCoreApplication::notifyInternal2(QObject*, QEvent*) + 314
    frame #33: 0x00007ffff6ef157b libQt5Widgets.so.5`QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) + 443
    frame #34: 0x00007ffff6f47a84 libQt5Widgets.so.5`___lldb_unnamed_symbol921$$libQt5Widgets.so.5 + 740
    frame #35: 0x00007ffff6f4adb5 libQt5Widgets.so.5`___lldb_unnamed_symbol932$$libQt5Widgets.so.5 + 517
    frame #36: 0x00007ffff6eead62 libQt5Widgets.so.5`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 130
    frame #37: 0x00007ffff7c90d0e libqSlicerBaseQTGUI.so`qSlicerApplication::notify(this=<unavailable>, receiver=<unavailable>, event=<unavailable>) at qSlicerApplication.cxx:412:26
    frame #38: 0x00007ffff64133fa libQt5Core.so.5`QCoreApplication::notifyInternal2(QObject*, QEvent*) + 314
    frame #39: 0x00007ffff67ec1f0 libQt5Gui.so.5`QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) + 1712
    frame #40: 0x00007ffff67c17d5 libQt5Gui.so.5`QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 181
    frame #41: 0x00007fffce39afcc libQt5XcbQpa.so.5`___lldb_unnamed_symbol407$$libQt5XcbQpa.so.5 + 28
    frame #42: 0x00007fffe0b834dc libglib-2.0.so.0`g_main_context_dispatch + 620
    frame #43: 0x00007fffe0bd7799 libglib-2.0.so.0`___lldb_unnamed_symbol452$$libglib-2.0.so.0 + 521
    frame #44: 0x00007fffe0b80bc1 libglib-2.0.so.0`g_main_context_iteration + 49
    frame #45: 0x00007ffff646c026 libQt5Core.so.5`QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 102
    frame #46: 0x00007ffff6411d6c libQt5Core.so.5`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 300
    frame #47: 0x00007ffff641a2d4 libQt5Core.so.5`QCoreApplication::exec() + 148
    frame #48: 0x00007ffff752f4c6 libqSlicerBaseQTCore.so`qSlicerCoreApplication::exec() at qSlicerCoreApplication.cxx:876:19
    frame #49: 0x000055555555999c SlicerApp-real`main [inlined] (anonymous namespace)::SlicerAppMain(argc=1, argv=0x00007fffffffc498) at Main.cxx:62:10
    frame #50: 0x00005555555597b1 SlicerApp-real`main(argc=<unavailable>, argv=0x00007fffffffc498) at qSlicerApplicationMainWrapper.cxx:56
    frame #51: 0x00007fffe156bb25 libc.so.6`__libc_start_main + 213
    frame #52: 0x00005555555596be SlicerApp-real`_start + 46
(lldb) 

Please not that this happens before and after 88673aa.

Hoping it may help for a resolution.

chir-set avatar Nov 06 '21 15:11 chir-set

vtkPichonFastMarching filter is research code, never got really cleaned up, hardened, or optimized. The main reason is that while it is useful, it is not that useful in practice compared to other algorithms, such as fast grow-cut (in Grow from seeds effect).

Nevertheless, if you can give step-by-step instructions for reproducing the crash then I might be able to take a look. The backtrace is useful, and normally it could be sufficient to identify and fix an error, but it is not enough in this case because there are so many things wrong in this class.

lassoan avatar Nov 06 '21 16:11 lassoan

The crash is reproducible in this dataset (I had it on others too).

Just do a single paint stroke at 3% in the thrombus of the aneurysm, or any paint stroke anywhere. Go to 'Fast marching'. Initialize at default 10% Cancel Initialize at 11% Cancel Initialize at 8%

Slicer crashes then more often. Sometimes it's on first initialization of 'Fast marching'.

Now it's not an immediate problem, I don't use it everyday, and probably would be seldom using it. I just found that its very useful to segment thrombus in big aneurysms and to segment veins.

Thank you for willing to look into this.

chir-set avatar Nov 06 '21 19:11 chir-set

What do you think about this deal: I fix this issue, and you create a video tutorial of how you use it for thromvus and vein segmentation (no need for voice, subtitles are enough). Are you in?

lassoan avatar Nov 07 '21 18:11 lassoan

What do you think about this deal

Good deal !

Here is a link for segmenting abdomino-pelvic veins. Basically, seed the vein with 'Draw tube', then apply 'Fast marching' with low 'Maximum volume' values (2% to 5%), adjust with 'Segment volume' (can be as low as < 1%), check throughout for some residual leaks (usually 3rd - 4th duodenum, or muscle) and erase the minimal leaks.

Do multiple segmentations, with veins of more or less same diameter, and also, with intensity distribution quite even.

Then combine all segments with logical operators in a new segment, 'Fill holes' smoothing, and optionally 'Joint smoothing'.

'Fast marching' has 2 particulars :

  • it does not need a stopper segment
  • the leaks can be worked on in post-processing, that's a unique feature.

For aneurysmal thrombus, it will take some days, as I am resuming work, and there are aneurysms and aneurysms.

Regards.

chir-set avatar Nov 07 '21 19:11 chir-set

Here are videos of segmenting a simple and a complex aortic aneurysm thrombus using 'Fast marching'.

It follows the same method as for veins, with these two specifics :

  • create the target segment with 'Surface cut', including thrombus and contrasted lumen
  • exclude the contrast with a second segment, overwriting that part in the target segment

The rest follows the same workflow : 'Fast marching', reduce leaks, apply, erase small leaks, paint small misses, 'Fill holes' smoothing and perhaps 'Joint smoothing'.

chir-set avatar Nov 08 '21 21:11 chir-set