Revision 5b94fd2c12712e04345d4b130358afbb352f6436 authored by vthierry on 28 October 2025, 18:54:37 UTC, committed by vthierry on 28 October 2025, 18:54:37 UTC
1 parent 4ad30c1
run_protege.sh
#!/bin/bash
# /**
# * @function run_protege
# * @static
# * @description Remote control of the Protégé GUI interface system.
# * - This allows to interface a [LValue](./LValue.html) with a reasoner.
# *
# * - Only available as a command line application:
# * ```
# * Usage: ./src/run_protege.sh input.owl
# * Runs Protégé loading the ontology, running the default reasoner, and exporting the inferred axioms.
# * Generates an output file of name input.owl.inferred.owl in Turtle format.
# * Generates a log of all operations in /tmp/run_protege.log.
# * The Protege GUI must be manually parameterized before use, for instance defining the default reasoner.
# * Caution: do not manipulate the mouse or keyboard during the process, only one instance can run at a given time.
# * Disclaimer: this is only an experimental fragile setup, only available under Linux, valid only for Protege-5.5.0
# * (GUI parameters may have to be redefined for another Protégé version).
# * Requires: xdotool.
# * ```
# */
## Show usage if no input file
if [ \! -f "$1" ] ; then grep '^# \* ' `realpath $0` | sed 's/# \* //' ; exit ; fi
input="`realpath $1`"
# Protege remote control via xdotool
##### Ref: https://manpages.ubuntu.com/manpages/trusty/man1/xdotool.1.html
##### Ref: https://gitlab.com/cunidev/gestures/-/wikis/xdotool-list-of-key-codes
## Verifies the installation
### Defines the potential protege installation roots (add yours in the ROOTS list)
ROOTS="/usr/local/Protege-5.5.0 /local/data/linux-install/Protege-5.5.0"
for r in $ROOTS ; do if [ -f "$r/run.sh" ] ; then ROOT="$r" ; fi ; done
if [ -z "$ROOT" ] ; then echo "Error: Unable to find Protege installation in '$ROOTS', sorry." ; exit -1 ; fi
### Checks for xdotool installation
if which xdotool 2>/dev/null >/dev/null ; then ok= ; else echo "Error: Unable to find xdotool, you may have to run 'sudo (dnf|apt) install xdotool'." ; fi
## Defines useful script functions
### Waits until a regex appears in the log tail
function wait_on_log() { # (tail_size, regex_to_detect)
if [ "$1" = "0" ]
then until grep "$2" $logfile >/dev/null ; do echo " waiting for \"$2\"" ; sleep 1 ; done
else until tail -$1 $logfile | grep "$2" >/dev/null ; do echo " waiting for \"$2\"" ; sleep 1 ; done
fi
}
logfile="/tmp/run_protege.log"
### Sets the current active window parameters
function getwindow() {
eval `xdotool getactivewindow getwindowgeometry --shell`
}
### Starts Protege
function start_protege()
{
echo "Starting Protege …"
$ROOT/run.sh > $logfile &
wait_on_log 0 "Auto-update"
getwindow
echo " … done"
}
### Moves the mouse in window based frame
function mouse_move() { # (x_window_relative_position_in_pixel, y_window_relative_position_in_pixel)
xdotool mousemove --sync $X $Y
xdotool mousemove_relative --sync $1 $2
}
### Clicks on a menu item
function click_topmenu_item() { # (x_position_in_pixel, y_position_in_menu_in_pixel)
y_topmenu_position_in_pixel=15
mouse_move $1 $y_topmenu_position_in_pixel
xdotool mousedown 1
sleep 0.1
xdotool mousemove_relative --sync 0 $2
xdotool click 1
}
### Clicks on a menu button, e.g., on a popup window, to be followed by a 'getwindow' after popup closed
function click_menu_button() { # (x_position_in_pixel, y_position_in_pixel)
sleep 0.5
getwindow
mouse_move $1 $2
xdotool click 1
}
### Loads a file (it could also be loaded as command line argument)
function load_file() { # (filepath_with_absolute_path)
echo "File -> Open \"$1\" …"
xdotool key ctrl+o
xdotool type $1
xdotool key return
wait_on_log 30 "Finished loading.*$1"
echo " … done"
}
### Saves in a file a turtle format
function save_file() { # (filename_with_absolute_path_or_relative_to_loaded_aboslute_path)
echo "File -> Save as \"$1\" …"
xdotool key ctrl+shift+s
# Waits for the popup to appears
sleep 0.5
# Clics on the format menu
getwindow
x_format_menu=200
y_format_menu=144
mouse_move $x_format_menu $y_format_menu
xdotool click 1
# Chooses turtle format
xdotool key t
xdotool key space
xdotool key return
# Enters the file name
xdotool type $1
xdotool key return
wait_on_log 30 "Saved ontology.*$1"
# Restores the original window location
getwindow
echo " … done"
}
### Runs the current reasoner
function run_reasoner() { # (final_wait_ok_log_regex)
echo 'Reasoner -> Start Default Reasoner'
x_topmenu_reasoner_menu=150
y_topmenu_start_reasoner=30
click_topmenu_item $x_topmenu_reasoner_menu $y_topmenu_start_reasoner
wait_on_log 10 "$*"
}
### Exports inferred axioms in a file
function export_inferred_axioms() { # (filepath_with_absolute_path)
echo "File -> Export inferred axioms as \"$1\" …"
x_topmenu_file_menu=23
y_topmenu_export=210
click_topmenu_item $x_topmenu_file_menu $y_topmenu_export
x_button_continue=705
y_button_continue=570
# Select axioms to export, might be improved clicking on some options
click_menu_button $x_button_continue $y_button_continue
# Include asserted axioms, might be improved clicking on some options
click_menu_button $x_button_continue $y_button_continue
# Ontology ID, might be improved editing the URL with filepath or filename
click_menu_button $x_button_continue $y_button_continue
# Physical location
xdotool key ctrl+a
xdotool type $1
click_menu_button $x_button_continue $y_button_continue
# Ontology format, here choose turtle format, as in save_file function
x_format_menu=500
y_format_menu=505
mouse_move $x_format_menu $y_format_menu
xdotool click 1
xdotool key t
xdotool key space
click_menu_button $x_button_continue $y_button_continue
# OK
sleep 0.5
xdotool key return
sleep 0.5
getwindow
echo " … done"
}
### Exits from protege
function exit_protege() {
echo 'File -> Exit'
x_topmenu_file_menu=23
y_topmenu_exit=415
click_topmenu_item $x_topmenu_file_menu $y_topmenu_exit
echo " … done"
}
## Runs protege in remote control mode to obtain the inferred axioms
#### Starts the GUI interface
start_protege
# pid="$!" ; pid="`pgrep -P $pid`" ; # PID only for debug
#### Loads a file
load_file $input
#### Starts default reasoner, assuming using HermiT
run_reasoner "Ontologies processed in.*HermiT"
#### Saves and exports inferred axioms
export_inferred_axioms $input.inferred.owl
#### Exit via File -> Exit
exit_protege

Computing file changes ...