package jalview.bin; import java.io.File; import java.io.IOException; 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.bin.ArgParser.SubVal; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; import jalview.datamodel.annotations.AlphaFoldAnnotationRowBuilder; import jalview.gui.AlignFrame; import jalview.gui.AlignmentPanel; import jalview.gui.Desktop; import jalview.gui.StructureChooser; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; import jalview.io.FileFormatException; import jalview.io.FileFormatI; import jalview.io.FileLoader; import jalview.io.HtmlSvgOutput; import jalview.io.IdentifyFile; import jalview.schemes.AnnotationColourGradient; import jalview.structure.StructureImportSettings; import jalview.structure.StructureImportSettings.TFType; import jalview.structure.StructureSelectionManager; import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.ws.dbsources.EBIAlfaFold; import mc_view.PDBChain; public class Commands { Desktop desktop; private static boolean headless; private static ArgParser argParser; private Map afMap; public static boolean processArgs(ArgParser ap, boolean h) { argParser = ap; headless = h; boolean argsWereParsed = false; if (headless) { System.setProperty("java.awt.headless", "true"); } 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); } cmds.processImages(id); argsWereParsed |= cmds.wereParsed(); } } if (argParser.getBool(Arg.QUIT)) { Jalview.getInstance().quit(); return true; } // carry on with jalview.bin.Jalview return argsWereParsed; } boolean argsWereParsed = false; private boolean wereParsed() { return argsWereParsed; } public Commands() { this(Desktop.instance); } public Commands(Desktop d) { this.desktop = d; afMap = new HashMap(); } protected void processUnlinked(String id) { Map m = argParser.linkedArgs(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 (ArgParser.getArgValues(m, Arg.OPEN) != null) { long progress = -1; boolean first = true; AlignFrame af; for (String openFile : ArgParser.getValues(m, Arg.OPEN)) { if (openFile == null) continue; argsWereParsed = true; 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 + "'"); } } } 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) { /* * this approach isn't working yet // get default annotations before opening AlignFrame if (m.get(Arg.SSANNOTATION) != null) { Console.debug("***** SSANNOTATION=" + m.get(Arg.SSANNOTATION).getBoolean()); } if (m.get(Arg.NOTEMPFAC) != null) { Console.debug( "***** NOTEMPFAC=" + m.get(Arg.NOTEMPFAC).getBoolean()); } boolean showSecondaryStructure = (m.get(Arg.SSANNOTATION) != null) ? m.get(Arg.SSANNOTATION).getBoolean() : false; boolean showTemperatureFactor = (m.get(Arg.NOTEMPFAC) != null) ? !m.get(Arg.NOTEMPFAC).getBoolean() : false; Console.debug("***** tempfac=" + showTemperatureFactor + ", showSS=" + showSecondaryStructure); StructureSelectionManager ssm = StructureSelectionManager .getStructureSelectionManager(Desktop.instance); if (ssm != null) { ssm.setAddTempFacAnnot(showTemperatureFactor); ssm.setProcessSecondaryStructure(showSecondaryStructure); } */ // get kind of temperature factor annotation StructureImportSettings.TFType tempfacType = TFType.DEFAULT; if ((!ArgParser.getBoolean(m, Arg.NOTEMPFAC)) && ArgParser.getArgValues(m, Arg.TEMPFAC) != null) { try { tempfacType = StructureImportSettings.TFType.valueOf(ArgParser .getValue(m, Arg.TEMPFAC).toUpperCase(Locale.ROOT)); Console.debug("Obtained Temperature Factor type of '" + tempfacType + "'"); } catch (IllegalArgumentException e) { // Just an error message! StringBuilder sb = new StringBuilder().append("Cannot set --") .append(Arg.TEMPFAC.getName()).append(" to '") .append(tempfacType) .append("', ignoring. Valid values are: "); Iterator it = Arrays .stream(StructureImportSettings.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); StructureImportSettings.setTemperatureFactorType(tempfacType); af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol, format); // wrap alignment? if (ArgParser.getBoolean(m, Arg.WRAP)) { af.getCurrentView().setWrapAlignment(true); } // colour aligment? if (ArgParser.hasValue(m, Arg.COLOUR)) { af.changeColour_actionPerformed( ArgParser.getValue(m, Arg.COLOUR)); } // change alignment frame title if (ArgParser.getValue(m, Arg.TITLE) != null) af.setTitle(ArgParser.getValue(m, Arg.TITLE)); /* hacky approach to hiding the annotations */ // show secondary structure annotations? if (ArgParser.getBoolean(m, Arg.SSANNOTATION)) { // do this better (annotation types?) AlignmentUtils.showOrHideSequenceAnnotations( af.getCurrentView().getAlignment(), Collections.singleton("Secondary Structure"), null, false, false); } // show temperature factor annotations? if (ArgParser.getBoolean(m, Arg.NOTEMPFAC)) { // do this better (annotation types?) List hideThese = new ArrayList<>(); hideThese.add("Temperature Factor"); hideThese.add(AlphaFoldAnnotationRowBuilder.LABEL); AlignmentUtils.showOrHideSequenceAnnotations( af.getCurrentView().getAlignment(), hideThese, null, false, false); } else /* comment out hacky approach up to here and add this line: if (showTemperatureFactor) */ { if (ArgParser.getValue(m, Arg.TEMPFAC_LABEL) != null) { AlignmentAnnotation aa = AlignmentUtils .getFirstSequenceAnnotationOfType( af.getCurrentView().getAlignment(), AlignmentAnnotation.LINE_GRAPH); String label = ArgParser.getValue(m, Arg.TEMPFAC_LABEL); if (aa != null) { aa.label = label; } else { Console.info( "Could not find annotation to apply tempfac_label '" + label); } } } // store the AlignFrame for this id afMap.put(id, af); // is it its own structure file? if (format.isStructureFile()) { StructureSelectionManager ssm = StructureSelectionManager .getStructureSelectionManager(Desktop.instance); SequenceI seq = af.alignPanel.getAlignment().getSequenceAt(0); ssm.computeMapping(false, new SequenceI[] { seq }, null, openFile, DataSourceType.FILE, null); } } else { Console.debug( "Opening '" + openFile + "' in existing alignment frame"); af.getCurrentView().addFile(new File(openFile), format); } Console.debug("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); } } } // open the structure (from same PDB file or given PDBfile) if (!ArgParser.getBoolean(m, Arg.NOSTRUCTURE)) { AlignFrame af = afMap.get(id); if (ArgParser.getArgValues(m, Arg.STRUCTURE) != null) { for (String val : ArgParser.getValues(m, Arg.STRUCTURE)) { SubVal subId = new SubVal(val); SequenceI seq = getSpecifiedSequence(af, subId); if (seq == null) { Console.warn("Could not find sequence for argument --" + Arg.STRUCTURE + "=" + val); // you probably want to continue here, not break // break; continue; } File structureFile = null; if (subId.content != null && subId.content.length() != 0) { structureFile = new File(subId.content); Console.debug("Using structure file (from argument) '" + structureFile.getAbsolutePath() + "'"); } /* THIS DOESN'T WORK */ else if (seq.getAllPDBEntries() != null && seq.getAllPDBEntries().size() > 0) { structureFile = new File( seq.getAllPDBEntries().elementAt(0).getFile()); Console.debug("Using structure file (from sequence) '" + structureFile.getAbsolutePath() + "'"); } if (structureFile == null) { Console.warn("Not provided structure file with '" + val + "'"); continue; } if (!structureFile.exists()) { Console.warn("Structure file '" + structureFile.getAbsoluteFile() + "' not found."); continue; } Console.debug("Using structure file " + structureFile.getAbsolutePath()); // open structure view AlignmentPanel ap = af.alignPanel; StructureChooser.openStructureFileForSequence(ap, seq, structureFile); } } } // load a pAE file if given if (ArgParser.getValues(m, Arg.PAEMATRIX) != null) { AlignFrame af = afMap.get(id); if (af != null) { for (String val : ArgParser.getValues(m, Arg.PAEMATRIX)) { SubVal subVal = ArgParser.getSubVal(val); File paeFile = new File(subVal.content); String paePath = null; try { paePath = paeFile.getCanonicalPath(); } catch (IOException e) { paePath = paeFile.getAbsolutePath(); Console.warn( "Problem with the PAE file path: '" + paePath + "'"); } String structId = "structid".equals(subVal.keyName) ? subVal.keyValue : null; if (subVal.notSet()) { // take structid from pdbfilename } if ("structfile".equals(subVal.keyName)) { Console.info("***** Attaching paeFile '" + paePath + "' to " + subVal.keyName + "=" + subVal.keyValue); EBIAlfaFold.addAlphaFoldPAEToStructure( af.getCurrentView().getAlignment(), paeFile, subVal.index, subVal.keyValue, false); } else if ("structid".equals(subVal.keyName)) { Console.info("***** Attaching paeFile '" + paePath + "' to " + subVal.keyName + "=" + subVal.keyValue); EBIAlfaFold.addAlphaFoldPAEToStructure( af.getCurrentView().getAlignment(), paeFile, subVal.index, subVal.keyValue, true); } else { Console.debug("***** Attaching paeFile '" + paePath + "' to sequence index " + subVal.index); EBIAlfaFold.addAlphaFoldPAEToSequence( af.getCurrentView().getAlignment(), paeFile, subVal.index, null); // required to readjust the height and position of the pAE // annotation } for (AlignmentViewPanel ap : af.getAlignPanels()) { ap.adjustAnnotationHeight(); } } } } boolean doShading = ArgParser.getBoolean(m, Arg.TEMPFAC_SHADING); if (doShading) { AlignFrame af = afMap.get(id); for (AlignmentAnnotation aa : af.alignPanel.getAlignment() .findAnnotation(PDBChain.class.getName().toString())) { AnnotationColourGradient acg = new AnnotationColourGradient(aa, af.alignPanel.av.getGlobalColourScheme(), 0); acg.setSeqAssociated(true); af.changeColour(acg); Console.info("Changed colour " + acg.toString()); } } } protected void processImages(String id) { Map m = argParser.linkedArgs(id); AlignFrame af = afMap.get(id); if (af == null) { Console.warn("Did not have an alignment window for id=" + id); return; } if (ArgParser.getValues(m, Arg.IMAGE) != null) { for (String val : ArgParser.getValues(m, Arg.IMAGE)) { SubVal subVal = new SubVal(val); String type = "png"; // default String fileName = subVal.content; File file = new File(fileName); if ("type".equals(subVal.keyName)) { type = subVal.keyValue; } else if (fileName != null) { for (String ext : new String[] { "svg", "png", "html" }) { if (fileName.toLowerCase(Locale.ROOT).endsWith("." + ext)) { type = ext; } } } // for moment we disable JSON export Cache.setPropsAreReadOnly(true); Cache.setProperty("EXPORT_EMBBED_BIOJSON", "false"); switch (type) { case "svg": Console.debug("Outputting type '" + type + "' to " + fileName); af.createSVG(file); break; case "png": Console.debug("Outputting type '" + type + "' to " + fileName); af.createPNG(file); break; case "html": Console.debug("Outputting type '" + type + "' to " + fileName); HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel); htmlSVG.exportHTML(fileName); break; default: Console.warn("--image type '" + type + "' not known. Ignoring"); break; } } } } private SequenceI getSpecifiedSequence(AlignFrame af, SubVal subId) { AlignmentI al = af.getCurrentView().getAlignment(); if (-1 < subId.index && subId.index < al.getSequences().size()) { return al.getSequenceAt(subId.index); } else if ("id".equals(subId.keyName)) { return al.findName(subId.keyValue); } return null; } }