controlling running Jalview instance

I tried following an approach to this provided in 2011 in open files from command line without spawning new Jalview instance? and found in 2023 that

  • groovy no longer needs to be installed separately
  • the listener starts up as expected
  • the listener throws an error upon receipt of message

groovy> new groovy.ui.GroovySocketServer(
groovy> new GroovyShell(), false, “(new jalview.io.FileLoader()).LoadFileWaitTillLoaded(line,jalview.io.FormatAdapter.FILE);”, true, 1962)

groovy is listening on port 1962
Result: groovy.ui.GroovySocketServer@af47a6fException in thread “Groovy client connection - 127.0.0.1”
groovy.lang.MissingPropertyException: No such property: FILE for class: jalview.io.FormatAdapter
at groovy.lang.MetaClassImpl.invokeStaticMissingProperty(MetaClassImpl.java:1014)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1852)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1828)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3773)
at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:50)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:299)
at ServerSocketScript1.run(ServerSocketScript1.groovy:1)
at groovy.ui.GroovySocketServer$GroovyClientConnection.run(GroovySocketServer.java:197)
at java.lang.Thread.run(Thread.java:750)

Is there an updated way to achieve the objective of opening alignment files in a running Jalview instance from command line, or perhaps more generally to control a running Jalview instance?

My use case is to control JalView from within VBA macro for Excel on windows (or Mac as well, ideally). I want to rapidly switch between many alignments listed in an Excel table.

Edit:

The approach above works by changing jalview.io.FormatAdapter.FILE to jalview.io.DataSourceType.FILE as I figured out upon examination of this test: testDownloadStructuresIfInputFromURL.

Hooray.

I remain interested in more general approaches to controlling JalView remotely.

Cheers.

1 Like

Hi (again!) Malcolm,

Well done working out the changes in code since the first example – I think you got there more quickly than I would have done!

There has been some work on Jalview using a local listener for an API to do exactly what you’re after (and a whole lot more), but it’s not mature yet and release isn’t imminent I’m afraid.

There’s an issue you can “watch” to be updated when there’s more progress: https://issues.jalview.org/browse/JAL-3851

Ben

1 Like

Hi Malcom.

Jalview’s internals are undergoing some rearrangements due to ongoing Jalview/JS work, so there isn’t a stable versioned API yet, but we’re working on it.

For the moment, I think you might be able to do what you want with the following groovy script:

// simple groovy server that allows you to quickly switch between different alignments
def PORT=1969

// map filename strings to the Jalview alignment frame that was created by importing it
def alignFrames = [:]

def process = { line ->
    def alf = alignFrames[line]
    if (jalview.gui.Desktop.getDesktop().getSelectedFrame() != alf) {
        // minimise the alignment view and its associated frames
        jalview.gui.Desktop.instance.reorderAssociatedWindows(true, false)
    }

    if (alf != null) {
        // unminimise the alignment
        alf.setIcon(false)
        alf.setSelected(true)
        alf.toFront()
        // maximise the window again - this could be optional
        alf.setMaximum(false)
        alf.setMaximum(true)
        alf.requestFocus()
        // and show any associated windows
        jalview.gui.Desktop.instance.
            reorderAssociatedWindows(false, false)
        return 'Viewing already loaded alignment ' + alf.getTitle()
    } else {
        alignFrames[line] = (new jalview.io.FileLoader())
            .LoadFileWaitTillLoaded(line,jalview.io.DataSourceType.FILE)
        // maximises the window
        alignFrames[line].setMaximum(true)
        // and show any associated windows
        jalview.gui.Desktop.instance.reorderAssociatedWindows(false, false)
        return 'Successfully opened ' + line
    }
}

new groovy.ui.GroovySocketServer(
    new GroovyShell(
        new Binding(['process':process])), 
        false, 'process(line)', true, PORT)
1 Like

That is fantastic! Thanks so much!

It is a huge improvement over prior groovy listener and works in my hands perfectly well.

Is there a possibility of extending it easily to load features from a .gff file?

Possibly by listening for a command like:
Load Features
or
Load Features /path/to/local/file.gff

Thanks again!

a file of .gff features to oepn

Try the new version below - once an alignment has been selected to view, sending “ANNOTATE /path/to/file.gff” will load the gff file. This is doing the same thing as the File->Load Features or Annotations…’ entry in the alignment window, meaning you can also add annotations and t-coffee reliability scores. Test the file first by dropping it on to the alignment window to check it does what you expect.

// simple groovy server that allows you to quickly switch between different alignments
def PORT=1972

// map filename strings to the Jalview alignment frame that was created by importing it
def alignFrames = [:]

def annotate="ANNOTATE ";

def process = { line ->
    if (line.startsWith(annotate)) {
       
      def curFrame=jalview.gui.Desktop.getDesktop().getSelectedFrame();
      if (curFrame == null) {
        return "select alignment before sending ANNOTATE"
      }
      String fileName = line.substring(annotate.length())
      jalview.gui.Desktop.getDesktop().getSelectedFrame().loadJalviewDataFile(fileName,jalview.io.DataSourceType.FILE,null,null)
      return "added annotation from "+fileName+" to "+curFrame.getTitle()
    }
    def alf = alignFrames[line]
    if (jalview.gui.Desktop.getDesktop().getSelectedFrame() != alf) {
        // minimise the alignment view and its associated frames
        jalview.gui.Desktop.instance.reorderAssociatedWindows(true, false)
    }

    if (alf != null) {
        // unminimise the alignment
        alf.setIcon(false)
        alf.setSelected(true)
        alf.toFront()
        // maximise the window again - this could be optional
        alf.setMaximum(false)
        alf.setMaximum(true)
        alf.requestFocus()
        // and show any associated windows
        jalview.gui.Desktop.instance.
            reorderAssociatedWindows(false, false)
        return 'Viewing already loaded alignment ' + alf.getTitle()
    } else {
        alignFrames[line] = (new jalview.io.FileLoader())
            .LoadFileWaitTillLoaded(line,jalview.io.DataSourceType.FILE)
        // maximises the window
        alignFrames[line].setMaximum(true)
        // and show any associated windows
        jalview.gui.Desktop.instance.reorderAssociatedWindows(false, false)
        return 'Successfully opened ' + line
    }
}

new groovy.ui.GroovySocketServer(
    new GroovyShell(
        new Binding(['process':process])), 
        false, 'process(line)', true, PORT)
1 Like

Huge thanks, that works exactly as I require.

Happily, I find that the paths may be relative to Jalview’s startup directory.

I find that I must insert a short delay between opening a sequence file and a corresponding ANNOTATION command, else the features are not displayed. One second works for me. Presumably the delay allows Jalview GUI to “settle down” in some fashion.

I also find that I am unable from to read the result of process (e.g. “select alignment before sending ANNOTATE”) within VBA. I was try to do so as part of debugging the above failure to display features. I am using “IO Libraries Suite” (from www.keysight.com/find/iosuite) for TCPIP communication to socket on localhost. Any insight on how to perform such communication without introducing this dependency would be welcome, but I don’t expect to find Window VBA talent in this forum :wink: