package jalview.bin; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import jalview.analysis.AlignmentUtils; import jalview.api.AlignmentViewPanel; import jalview.bin.ArgParser.Arg; import jalview.bin.ArgParser.ArgValues; import jalview.datamodel.AlignmentAnnotation; import jalview.gui.AlignFrame; import jalview.gui.Desktop; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; import jalview.io.FileFormatException; import jalview.io.FileFormatI; import jalview.io.FileLoader; import jalview.io.IdentifyFile; import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.ws.dbsources.EBIAlfaFold; public class Commands { Desktop desktop; private static boolean headless; private static ArgParser argParser; private Map afMap; public static void processArgs(ArgParser ap, boolean h) { argParser = ap; headless = h; if (argParser != null && argParser.linkedIds() != null) { for (String id : argParser.linkedIds()) { Commands cmds = new Commands(); if (id == null) { cmds.processUnlinked(id); } else { cmds.processLinked(id); } } } } public Commands() { this(Desktop.instance); } public Commands(Desktop d) { this.desktop = d; afMap = new HashMap(); } protected void processUnlinked(String id) { processLinked(id); } protected void processLinked(String id) { Map m = argParser.linkedArgs(id); /* // script to execute after all loading is completed one way or another String groovyscript = m.get(Arg.GROOVY) == null ? null : m.get(Arg.GROOVY).getValue(); String file = m.get(Arg.OPEN) == null ? null : m.get(Arg.OPEN).getValue(); String data = null; FileFormatI format = null; DataSourceType protocol = null; */ if (m.get(Arg.OPEN) != null) { long progress = -1; boolean first = true; AlignFrame af; OPEN: for (String openFile : m.get(Arg.OPEN).getValues()) { if (openFile == null) continue OPEN; if (first) { first = false; if (!headless) { desktop.setProgressBar( MessageManager.getString( "status.processing_commandline_args"), progress = System.currentTimeMillis()); } } if (!Platform.isJS()) /** * ignore in JavaScript -- can't just file existence - could load it? * * @j2sIgnore */ { if (!HttpUtils.startsWithHttpOrHttps(openFile)) { if (!(new File(openFile)).exists()) { Console.warn("Can't find file '" + openFile + "'"); continue OPEN; } } } DataSourceType protocol = AppletFormatAdapter .checkProtocol(openFile); FileFormatI format = null; try { format = new IdentifyFile().identify(openFile, protocol); } catch (FileFormatException e1) { Console.error("Unknown file format for '" + openFile + "'"); } af = afMap.get(id); if (af == null) { // get kind of temperature factor annotation AlignmentAnnotation.TFType tempfacType = null; if ((m.get(Arg.NOTEMPFAC) == null || !m.get(Arg.NOTEMPFAC).getBoolean()) && m.get(Arg.TEMPFAC) != null) { try { tempfacType = AlignmentAnnotation.TFType .valueOf(m.get(Arg.TEMPFAC).getValue() .toUpperCase(Locale.ROOT)); Console.debug("Obtained Temperature Factor type of '" + tempfacType + "'"); } catch (IllegalArgumentException e) { StringBuilder sb = new StringBuilder().append("Cannot set --") .append(Arg.TEMPFAC.getName()).append(" to '") .append(tempfacType) .append("', ignoring. Valid values are: "); Iterator it = Arrays .stream(AlignmentAnnotation.TFType.values()) .iterator(); while (it.hasNext()) { sb.append(it.next().toString().toLowerCase(Locale.ROOT)); if (it.hasNext()) sb.append(", "); } Console.warn(sb.toString()); } } Console.debug( "Opening '" + openFile + "' in new alignment frame"); FileLoader fileLoader = new FileLoader(!headless); af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol, format, tempfacType); // wrap alignment? if (m.get(Arg.WRAP) != null && m.get(Arg.WRAP).getBoolean()) { af.getCurrentView().setWrapAlignment(true); } // change alignment frame title if (m.get(Arg.TITLE) != null) af.setTitle(m.get(Arg.TITLE).getValue()); // show secondary structure annotations? if (m.get(Arg.SSANNOTATION) != null && !m.get(Arg.SSANNOTATION).getBoolean()) { // do this better (annotation types?) AlignmentUtils.showOrHideSequenceAnnotations( af.getCurrentView().getAlignment(), Collections.singleton("Secondary Structure"), null, false, false); } // show temperature factor annotations? if (m.get(Arg.NOTEMPFAC) != null && m.get(Arg.NOTEMPFAC).getBoolean()) { // do this better (annotation types?) List hideThese = new ArrayList<>(); hideThese.add("Temperature Factor"); hideThese.add(MessageManager .getString("label.alphafold_reliability")); AlignmentUtils.showOrHideSequenceAnnotations( af.getCurrentView().getAlignment(), hideThese, null, false, false); } else { if (m.get(Arg.TEMPFAC_LABEL) != null) { AlignmentAnnotation aa = AlignmentUtils .getFirstSequenceAnnotationOfType( af.getCurrentView().getAlignment(), AlignmentAnnotation.LINE_GRAPH); if (aa != null) { aa.label = m.get(Arg.TEMPFAC_LABEL).getValue(); } } } // store the AlignFrame for this id afMap.put(id, af); } else { Console.debug( "Opening '" + openFile + "' in existing alignment frame"); af.getCurrentView().addFile(new File(openFile), format); } System.out .println("Command " + Arg.OPEN + " executed successfully!"); } if (first) // first=true means nothing opened { if (headless) { Console.error("Could not open any files in headless mode"); System.exit(1); } } else { Console.warn("No more files to open"); if (desktop != null) desktop.setProgressBar(null, progress); } } // load a pAE file if given if (m.get(Arg.PAEMATRIX) != null) { AlignFrame af = afMap.get(id); if (af != null) { for (String val : m.get(Arg.PAEMATRIX).getValues()) { SubId subId = new SubId(val); File paeFile = new File(subId.content); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), paeFile, subId.index, "id".equals(subId.keyName) ? subId.keyValue : null); // required to readjust the height and position of the pAE // annotation for (AlignmentViewPanel ap : af.getAlignPanels()) { ap.adjustAnnotationHeight(); } } } } } /** * A helper class to parse a string of the possible forms "content" * "[index]content", "[keyName=keyValue]content" and return the integer index, * the strings keyName and keyValue, and the content after the square brackets * (if present). Values not set will be -1 or null. */ protected class SubId { protected int index = 0; protected String keyName = null; protected String keyValue = null; protected String content = null; protected SubId(String item) { if (item.indexOf('[') == 0 && item.indexOf(']') > 1) { int openBracket = item.indexOf('['); int closeBracket = item.indexOf(']'); String indexString = item.substring(openBracket + 1, closeBracket); this.content = item.substring(closeBracket + 1); int equals = indexString.indexOf('='); if (equals > -1) { this.keyName = indexString.substring(0, equals); this.keyValue = indexString.substring(equals + 1); this.index = -1; } else { try { this.index = Integer.parseInt(indexString); } catch (NumberFormatException e) { Console.warn("Failed to obtain sequenced id or index from '" + item + "'. Setting index=0 and using content='" + content + "'."); } } } else { this.content = item; } } } }