package com.cipres.mrBayesPlugin; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.ngbw.directclient.CiCipresException; import org.ngbw.directclient.CiClient; import org.ngbw.directclient.CiJob; import org.ngbw.restdatatypes.ErrorData; import org.ngbw.restdatatypes.LimitStatus; import org.ngbw.restdatatypes.ParamError; import com.biomatters.geneious.publicapi.components.Dialogs; import com.biomatters.geneious.publicapi.documents.AnnotatedPluginDocument; import com.biomatters.geneious.publicapi.documents.sequence.SequenceAlignmentDocument; import com.biomatters.geneious.publicapi.documents.sequence.SequenceDocument; import com.biomatters.geneious.publicapi.plugin.DocumentOperation; import com.biomatters.geneious.publicapi.plugin.DocumentOperationException; import com.biomatters.geneious.publicapi.plugin.DocumentSelectionSignature; import com.biomatters.geneious.publicapi.plugin.GeneiousActionOptions; import com.biomatters.geneious.publicapi.plugin.Icons; import com.biomatters.geneious.publicapi.plugin.Options; import com.biomatters.geneious.publicapi.plugin.PluginUtilities; import com.biomatters.geneious.publicapi.utilities.FileUtilities; import com.biomatters.geneious.publicapi.utilities.IconUtilities; import com.cipres.mrBayesPlugin.ui.LoginOptions; import com.cipres.mrBayesPlugin.ui.MrBayesOptions; import com.cipres.mrBayesPlugin.utilities.CipresUtilities; import com.cipres.mrBayesPlugin.utilities.MrBayesUtilities; import com.cipres.mrBayesPlugin.utilities.DataHandlingUtilities; import jebl.util.ProgressListener; import jebl.util.SafePrintWriter; /** * * @author rjzheng * @author mgujral * */ public class CipresMrBayesTree extends DocumentOperation{ static final String GENEIOUS_NEX = "geneious.nex"; private static final String TAB = "\t"; private static final String NEWLINE = System.getProperty("line.separator"); private static final String NUCLEOTIDE = "nucleotide"; private static final String PROTEIN = "protein"; private static final String DNA = "dna"; private static final String RNA = "rna"; private static final String STANDARD = "standard"; private static final String MORPHOLOGICAL = "morphological"; private static final String CONTINUOUS = "continuous"; private static final String REALNUM = "real number"; private static final String MIXED = "mixed"; private static final String RESTRICTION = "restriction"; private static final String RESTRICTIONSITE = "restriction site"; private static final String AMINOACID = "amino acid"; private static final String UNKNOWN = "unknown"; private static final String SPACE = " "; private static String DOCNAME = null; private static final String UNDERSCORE = "_"; private static final String DOT = "."; private static final String FILESEP = File.separator; public static String getDOCNAME() { return DOCNAME; } public static void setDOCNAME(String dOCNAME) { DOCNAME = dOCNAME; } @Override public GeneiousActionOptions getActionOptions() { //saved under cipres-mrbayes-plugin/GeneiousFiles/resources/images/TreeIcon.png for now Icons icon= IconUtilities.getIcons("tree24.png"); //MrBayes_CIPRES here is used in Tree Panel while making selection for parameters in running job. return new GeneiousActionOptions("MrBayes_CIPRES", "Perform posterior tree simulation from an alignment", icon, GeneiousActionOptions.Category.TreeBuilding); } @Override public String getHelp() { return "Getting Help"; } @Override public DocumentSelectionSignature[] getSelectionSignatures() { DocumentSelectionSignature singleAlignmentSignature = new DocumentSelectionSignature( SequenceAlignmentDocument.class, 1, 1); return new DocumentSelectionSignature[]{singleAlignmentSignature/*, nucleotideSequenceSelectionSignature, proteinSequenceSelectionSignature*/}; } public Options getOptions(final AnnotatedPluginDocument[] docs) throws DocumentOperationException{ Options options = null; if (CipresUtilities.isNewUser()) { options = new LoginOptions(); options.canRestoreDefaults(); } else { options = new MrBayesOptions(docs); } return options; } public List performOperation(AnnotatedPluginDocument[] docs, ProgressListener progress, Options options) throws DocumentOperationException{ String userName = null; String password = null; if (options instanceof LoginOptions) { LoginOptions loginOpt = (LoginOptions)options; userName = loginOpt.getUsername(); password = loginOpt.getPassword(); } if (CipresMrBayesInitializer.Instance.initialize(userName, password) == false) return null; else { if (options instanceof LoginOptions) { Dialogs.showMessageDialog("Your login credentials have been saved. Please right click on your data and select Tree... again."); return null; } } String sb = MrBayesUtilities.getGeneratedCommandBlockFromOptions(options); Map> vParams = new HashMap>(); Map inputParams = new HashMap(); Map metadata = new HashMap(); List files = new ArrayList(); final AnnotatedPluginDocument doc = docs[0]; final SequenceAlignmentDocument alignmentDoc = (SequenceAlignmentDocument) doc.getDocument(); if (alignmentDoc.getNumberOfSequences() < 4) { throw new DocumentOperationException("MrBayes requires at least 4 sequences." + NEWLINE + "Please select an alignment" + " containing 4 or more sequences."); } StringWriter scriptString = new StringWriter(); try { String block = MrBayesUtilities.getCustomOrGeneratedCommandBlockFromOptions(options, alignmentDoc); //numIterations = MrBayesUtilities.getNumOfIterationsFromOptions(options); File tempFolder = FileUtilities.createTempFile("Geneious", "MrBayes", false); //noinspection ResultOfMethoxdCallIgnored tempFolder.delete(); //noinspection ResultOfMethodCallIgnored tempFolder.mkdirs(); //************************************************************// //********** Following block added by Madhu ******************// //****************** on April 14, 2017 ***********************// //*************** Modified on April 25, 2017 *****************// //************************************************************// String seqType = alignmentDoc.getSequenceType().getName().trim(); String docName = alignmentDoc.getName().trim(); setDOCNAME(docName); System.out.println("Name: " + seqType + TAB + "DocName: " + docName); StringBuilder inFileBldr = new StringBuilder("#NEXUS" + NEWLINE + NEWLINE); inFileBldr.append("begin data;" + NEWLINE);; List seqDocList = alignmentDoc.getSequences(); //Following two line are needed to get the dimensions int listSize = seqDocList.size(); int ncharSize = seqDocList.get(0).getSequenceString().trim().length(); inFileBldr.append(TAB + "dimensions ntax=" + listSize + TAB + "nchar=" + ncharSize + ";" + NEWLINE); //inFileBldr.append(TAB + "format datatype=dna missing=? gap=-;" + NEWLINE); inFileBldr.append(TAB + "format datatype="); if(seqType.equalsIgnoreCase(NUCLEOTIDE)){ if(isDNA(seqDocList)){ inFileBldr.append(DNA + SPACE); }else{ inFileBldr.append(RNA + SPACE); } }else if(seqType.equalsIgnoreCase(PROTEIN) || seqType.equalsIgnoreCase(AMINOACID)){ inFileBldr.append(PROTEIN + SPACE); }else if(seqType.equalsIgnoreCase(STANDARD) || seqType.equalsIgnoreCase(MORPHOLOGICAL)){ inFileBldr.append(STANDARD + SPACE); }else if(seqType.equalsIgnoreCase(CONTINUOUS) || seqType.equalsIgnoreCase(REALNUM)){ inFileBldr.append(CONTINUOUS + SPACE); }else if(seqType.equalsIgnoreCase(MIXED)){ inFileBldr.append(MIXED + SPACE); }else if(seqType.equalsIgnoreCase(RESTRICTION) || seqType.equalsIgnoreCase(RESTRICTIONSITE)){ inFileBldr.append(RESTRICTION + SPACE); }else{ inFileBldr.append(UNKNOWN + SPACE); } inFileBldr.append("missing=? gap=-;" + NEWLINE); inFileBldr.append(TAB + "matrix" + NEWLINE); for(SequenceDocument seqDocument: seqDocList){ //MrBayes does not like space or dot(s) in taxa name String seqName = seqDocument.getName().trim() .replaceAll(SPACE, UNDERSCORE) .replaceAll("\\"+ DOT, "") .replaceAll("\\(","") .replaceAll("\\)",""); String seqString = seqDocument.getSequenceString().trim(); //String seqDescription = seqDocument.getDescription().trim(); System.out.println(seqString); System.out.println(seqName + TAB + seqString); //System.out.println("SeqString: " + seqString); //System.out.println("SeqDescription: " + seqDescription);// Not needed inFileBldr.append( seqName + TAB + seqString + NEWLINE); } inFileBldr.append(";" + NEWLINE); inFileBldr.append("End;" + NEWLINE); //************************************************************// //************* End of block added by Madhu ******************// //************************************************************// File outputFile = new File(tempFolder, GENEIOUS_NEX); files.add(outputFile); SafePrintWriter out = new SafePrintWriter(new FileWriter(outputFile)); //Following line commented by Madhu on April 13, 2017 //out.println(scriptString); out.println(inFileBldr.toString()); // Line added by Madhu out.println(block); out.close(); File originalAlignmentFile = new File(tempFolder, "originalAlignment.geneious.zip"); PluginUtilities.exportDocumentsInGeneiousFormat(originalAlignmentFile, true, doc); files.add(originalAlignmentFile); /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// BLOCK FOR TESTING ONLY///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// String canonicalTMPFolder = FileUtilities.getCanonicalOrAbsolutePath(tempFolder).trim(); System.out.println("CANONICAL TEMP FOLDER: " + canonicalTMPFolder); boolean folderCheck = false; //StringBuilder bldr = new StringBuilder(FILESEP); StringBuilder bldr = new StringBuilder(); for(String comp: canonicalTMPFolder.split(Pattern.quote(FILESEP))){ System.out.println("COMP Values: " + comp); if(comp.equals("temp")){ folderCheck = true; } if(!folderCheck){ bldr = bldr.append(comp).append(FILESEP); } } System.out.println("BASE FOLDER PATH: " + bldr.toString()); //////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////// BLOCK END ///////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// //Element optionValues = options.valuesToXML("MrBayesOptions"); File optionsFile = new File(tempFolder, "geneiousOptions.xml"); // XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); // FileWriter optionsWriter = new FileWriter(optionsFile); // outputter.output(optionValues, optionsWriter); // optionsWriter.close(); files.add(optionsFile); } catch (IOException ex) { throw new DocumentOperationException("Could not write temp files to disk", ex); } //metadata = MrBayesUtilities.getMetadata(docs[0].getName()); metadata = MrBayesUtilities.getMetadata(MrBayesOptions.getJobName()); vParams = MrBayesUtilities.getVParams(MrBayesOptions.getJsonCommand()); System.out.println("JsonCommand = " + MrBayesOptions.getJsonCommand() ); System.out.println("vParams = " + vParams); Collection sumtburnins = vParams.get("sumtburnin_"); if (sumtburnins != null && !sumtburnins.isEmpty()) { for (String sumtburnin : sumtburnins) { int sbin = 0; boolean invalidFormat = false; try { sbin = Integer.parseInt(sumtburnin); } catch (NumberFormatException nfe) { System.out.println(nfe.getMessage()); invalidFormat = true; } if (sbin < 10 || invalidFormat) { String errorMsg = null; if (invalidFormat) errorMsg = "Stumt burnin has invalid format"; else errorMsg = "Please enter a sumt burnin value of 10 or more"; Dialogs.showMessageDialog(errorMsg); return null; } } } //Following line commented by Madhu on April 13, 2017 inputParams.put("infile_", files.get(0).toString()); System.out.println(vParams); System.out.println("Number of elements in the List: " + files.size()); System.out.println("0th element of List: " + files.get(0).toString()); if(files.size() >=2){ System.out.println("1st element of List: " + files.get(1).toString()); System.out.println("2nd element of List: " + files.get(2).toString()); } try { CipresUtilities.submitJob("MRBAYES_XSEDE", vParams, inputParams, metadata); } catch (CiCipresException ce) { System.err.println("Caught in SubmitJob"); ErrorData ed = ce.getErrorData(); System.out.println("Cipres error code=" + ed.code + ", message=" + ed.displayMessage); if (ed.code == ErrorData.FORM_VALIDATION) { for (ParamError pe : ed.paramError) { System.out.println(pe.param + ": " + pe.error); } } else if (ed.code == ErrorData.USAGE_LIMIT) { LimitStatus ls = ed.limitStatus; System.out.println("Usage Limit Error, type=" + ls.type + ", ceiling=" + ls.ceiling); } } return null; } /** * This code checks if nucleotide sequences contains U then they represent RNA * @param seqDocumentList * @return true if the sequence represent DNA else return false * @author mgujral */ private boolean isDNA(List seqDocumentList){ boolean check = true; for(SequenceDocument seqDocument: seqDocumentList){ if(seqDocument.getSequenceString().toUpperCase().contains("U")){ check = false; break; } } return check; } /** * * @param name * @return * This method is not used for now. It is used to check the job user is trying to run * is already present on server or not. */ private boolean doesDocNameExistsOnServer(String name){ CiClient myClient = DataHandlingUtilities.getInstance().getClient(); boolean isPresent = false; try{ Collection listJobs = myClient.listJobs(); for(CiJob ciJob: listJobs){ System.out.println(ciJob.getClientJobName()); if(ciJob.getClientJobName().trim().equals(name)){ isPresent = true; } } }catch(CiCipresException cicpre){ cicpre.printStackTrace(); } return isPresent; } public static void main(String[] args){ String p = "Amino acid"; String test = "cdf.j_(kl)"; if(p.equalsIgnoreCase(AMINOACID) || p.equalsIgnoreCase(PROTEIN)) { System.out.println("Match found: " + PROTEIN); }else{ System.out.println("Problem"); } System.out.println(test.replaceAll("\\.", "") .replaceAll("\\(", "") .replaceAll("\\)", "")); } }