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.ArgValue; import jalview.bin.ArgParser.ArgValuesMap; import jalview.bin.ArgParser.SubVals; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import jalview.datamodel.annotations.AlphaFoldAnnotationRowBuilder; import jalview.gui.AlignFrame; import jalview.gui.AlignmentPanel; import jalview.gui.AssociatePdbFileWithSeq; import jalview.gui.Desktop; import jalview.gui.Preferences; import jalview.gui.StructureChooser; import jalview.gui.StructureViewer; 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 boolean headless; private ArgParser argParser; private Map afMap; private boolean commandArgsProvided = false; private boolean argsWereParsed = false; public Commands(ArgParser argparser, boolean headless) { this(Desktop.instance, argparser, headless); } public Commands(Desktop d, ArgParser argparser, boolean h) { argParser = argparser; headless = h; desktop = d; afMap = new HashMap(); if (argparser != null) { processArgs(argparser, headless); } } private boolean processArgs(ArgParser argparser, boolean h) { argParser = argparser; headless = h; boolean theseArgsWereParsed = false; if (argParser != null && argParser.linkedIds() != null) { for (String id : argParser.linkedIds()) { ArgValuesMap avm = argParser.linkedArgs(id); theseArgsWereParsed = true; if (id == null) { theseArgsWereParsed &= processUnlinked(id); } else { theseArgsWereParsed &= processLinked(id); } theseArgsWereParsed &= processImages(id); // close ap if (avm.getBoolean(Arg.CLOSE)) { AlignFrame af = afMap.get(id); if (af != null) { af.closeMenuItem_actionPerformed(true); } } } } if (argParser.getBool(Arg.QUIT)) { Jalview.getInstance().quit(); return true; } // carry on with jalview.bin.Jalview argsWereParsed = theseArgsWereParsed; return argsWereParsed; } public boolean commandArgsProvided() { return commandArgsProvided; } public boolean argsWereParsed() { return argsWereParsed; } protected boolean processUnlinked(String id) { return processLinked(id); } protected boolean processLinked(String id) { boolean theseArgsWereParsed = false; ArgValuesMap avm = argParser.linkedArgs(id); if (avm == null) return true; /* // 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 (avm.containsArg(Arg.OPEN)) { commandArgsProvided = true; long progress = -1; boolean first = true; boolean progressBarSet = false; AlignFrame af; for (ArgValue av : avm.getArgValueList(Arg.OPEN)) { String openFile = av.getValue(); if (openFile == null) continue; theseArgsWereParsed = true; if (first) { first = false; if (!headless && desktop != null) { desktop.setProgressBar( MessageManager.getString( "status.processing_commandline_args"), progress = System.currentTimeMillis()); progressBarSet = true; } } 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 ((!avm.getBoolean(Arg.NOTEMPFAC)) && avm.containsArg(Arg.TEMPFAC)) { try { tempfacType = StructureImportSettings.TFType .valueOf(avm.getArgValue(Arg.TEMPFAC).getValue() .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 (avm.getBoolean(Arg.WRAP)) { af.getCurrentView().setWrapAlignment(true); } // colour aligment? if (avm.containsArg(Arg.COLOUR)) { af.changeColour_actionPerformed(avm.getValue(Arg.COLOUR)); } // change alignment frame title if (avm.containsArg(Arg.TITLE)) af.setTitle(avm.getValue(Arg.TITLE)); /* hacky approach to hiding the annotations */ // show secondary structure annotations? if (avm.getBoolean(Arg.SSANNOTATION)) { // do this better (annotation types?) AlignmentUtils.showOrHideSequenceAnnotations( af.getCurrentView().getAlignment(), Collections.singleton("Secondary Structure"), null, false, false); } // show temperature factor annotations? if (avm.getBoolean(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 (avm.containsArg(Arg.TEMPFAC_LABEL)) { AlignmentAnnotation aa = AlignmentUtils .getFirstSequenceAnnotationOfType( af.getCurrentView().getAlignment(), AlignmentAnnotation.LINE_GRAPH); String label = avm.getValue(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, null, null); } } else { Console.debug( "Opening '" + openFile + "' in existing alignment frame"); af.getCurrentView().addFile(new File(openFile), format, false); } 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 (progressBarSet && desktop != null) desktop.setProgressBar(null, progress); } // open the structure (from same PDB file or given PDBfile) if (!avm.getBoolean(Arg.NOSTRUCTURE)) { AlignFrame af = afMap.get(id); if (avm.containsArg(Arg.STRUCTURE)) { commandArgsProvided = true; for (ArgValue av : avm.getArgValueList(Arg.STRUCTURE)) { String val = av.getValue(); SubVals subId = new SubVals(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.getContent() != null && subId.getContent().length() != 0) { structureFile = new File(subId.getContent()); Console.debug("Using structure file (from argument) '" + structureFile.getAbsolutePath() + "'"); } // TRY THIS /* PDBEntry fileEntry = new AssociatePdbFileWithSeq() .associatePdbWithSeq(selectedPdbFileName, DataSourceType.FILE, selectedSequence, true, Desktop.instance); sViewer = launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap, new SequenceI[] { selectedSequence }); */ /* 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()); PDBEntry fileEntry = new AssociatePdbFileWithSeq() .associatePdbWithSeq(structureFile.getAbsolutePath(), DataSourceType.FILE, seq, true, Desktop.instance); // open structure view AlignmentPanel ap = af.alignPanel; if (headless) { Cache.setProperty(Preferences.STRUCTURE_DISPLAY, StructureViewer.ViewerType.JMOL.toString()); } // get tft, paeFilename, label? /* ArgValue tftAv = avm.getArgValuesReferringTo("structid", structId, Arg.TEMPFAC); */ StructureChooser.openStructureFileForSequence(null, null, ap, seq, false, structureFile.getAbsolutePath(), null, null); // tft, // paeFilename); } } } // load a pAE file if given if (avm.containsArg(Arg.PAEMATRIX)) { AlignFrame af = afMap.get(id); if (af != null) { for (ArgValue av : avm.getArgValueList(Arg.PAEMATRIX)) { String val = av.getValue(); SubVals subVals = ArgParser.getSubVals(val); File paeFile = new File(subVals.getContent()); String paePath = null; try { paePath = paeFile.getCanonicalPath(); } catch (IOException e) { paePath = paeFile.getAbsolutePath(); Console.warn( "Problem with the PAE file path: '" + paePath + "'"); } String structId = subVals.get("structid"); if (subVals.notSet()) { // take structid from pdbfilename } if (subVals.has("structfile")) { Console.info("***** Attaching paeFile '" + paePath + "' to " + "structfile=" + subVals.get("structfile")); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), paeFile, subVals.getIndex(), subVals.get("structfile"), true, false); } else if (subVals.has("structid")) { Console.info("***** Attaching paeFile '" + paePath + "' to " + "structid=" + subVals.get("structid")); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), paeFile, subVals.getIndex(), subVals.get("structid"), true, true); } else { Console.debug("***** Attaching paeFile '" + paePath + "' to sequence index " + subVals.getIndex()); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), paeFile, subVals.getIndex(), null, false, false); // required to readjust the height and position of the pAE // annotation } for (AlignmentViewPanel ap : af.getAlignPanels()) { ap.adjustAnnotationHeight(); } } } } boolean doShading = avm.getBoolean(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()); } } return theseArgsWereParsed; } protected boolean processImages(String id) { ArgValuesMap avm = argParser.linkedArgs(id); AlignFrame af = afMap.get(id); if (af == null) { Console.warn("Did not have an alignment window for id=" + id); return false; } if (avm.containsArg(Arg.IMAGE)) { for (ArgValue av : avm.getArgValueList(Arg.IMAGE)) { String val = av.getValue(); SubVals subVal = new SubVals(val); String type = "png"; // default String fileName = subVal.getContent(); File file = new File(fileName); if (subVal.has("type")) { type = subVal.get("type"); } 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; } } } return true; } private SequenceI getSpecifiedSequence(AlignFrame af, SubVals subId) { AlignmentI al = af.getCurrentView().getAlignment(); if (-1 < subId.getIndex() && subId.getIndex() < al.getSequences().size()) { return al.getSequenceAt(subId.getIndex()); } else if (subId.has("seqid")) { return al.findName(subId.get("seqid")); } return null; } }