private void writeBlastResults( Writer writer, BlastResults blastResult, FastaSequence fastaSequence) throws IOException { // candidate uniprot writer.write(NEW_COLUMN); writer.write(blastResult.getAccession()); // write identity writer.write(NEW_COLUMN); writer.write(Float.toString(blastResult.getIdentity())); // write sequence coverages writer.write(NEW_COLUMN); writer.write( Float.toString(getQueryCoveragePercentFor(blastResult, fastaSequence.getSequence()))); writer.write(NEW_COLUMN); writer.write(Float.toString(getMatchCoveragePercentFor(blastResult))); // write start/end writer.write(NEW_COLUMN); writer.write(Integer.toString(blastResult.getStartQuery())); writer.write("-"); writer.write(Integer.toString(blastResult.getEndQuery())); writer.write(NEW_COLUMN); writer.write(Integer.toString(blastResult.getStartMatch())); writer.write("-"); writer.write(Integer.toString(blastResult.getEndMatch())); // write query sequence writer.write(NEW_COLUMN); writer.write(fastaSequence.getSequence()); // write alignment writer.write(NEW_COLUMN); writer.write(blastResult.getAlignment()); // write matching sequence writer.write(NEW_COLUMN); writer.write(blastResult.getSequence()); writer.write(NEW_LINE); writer.flush(); }
/** * Check that all the ranges of the features that the Intact entry can contain in Intact are not * in conflict with the new sequence(s) proposed by the blast on Swissprot to replace the Trembl * entry. * * @param context : the context of the protein * @return the trembl accession in the context if the sequences of the Swissprot proteins have * some conflicts with the ranges of some features, the Swissprot accession if there is only * one Swissprot protein with no conflicts and null if there are several Swissprot proteins * with no conflict. * @throws uk.ac.ebi.intact.protein.mapping.actions.exception.ActionProcessingException */ public String runAction(IdentificationContext context) throws ActionProcessingException { // always clear the list of reports from previous actions this.listOfReports.clear(); IntactContext intactContext = IntactContext.getCurrentInstance(); // We need to have a specific context containing the previous Trembl accession which totally // matched the Intact protein and the possible // proteins from Swissprot which can replace the Trembl match if (!(context instanceof FeatureRangeCheckingContext)) { throw new ActionProcessingException( "We can't process a feature range checking if the context is a " + context.getClass().getSimpleName() + " and not a FeatureRangeCheckingContext instance."); } else { FeatureRangeCheckingContext processContext = (FeatureRangeCheckingContext) context; int initialNumberOfBlastProtein = processContext.getResultsOfSwissprotRemapping().size(); // Create a DefaultBlastReport BlastReport<BlastResults> report = getReportsFactory().getBlastReport(ActionName.feature_range_checking); this.listOfReports.add(report); // If there were no Swissprot proteins which can replace the Trembl entry, it is an error and // this action fails if (processContext.getResultsOfSwissprotRemapping().isEmpty()) { Status status = new Status( StatusLabel.FAILED, "We don't have any valid results from the Swissprot-remapping process, so we will keep the Trembl entry " + processContext.getTremblAccession()); report.setStatus(status); return processContext.getTremblAccession(); } DaoFactory factory = intactContext.getDaoFactory(); // get the components involving the Intact entry List<Component> components = factory.getComponentDao().getByInteractorAc(processContext.getIntactAccession()); // If there is no component containing this protein, we don't have conflicts with feature // ranges if (components.isEmpty()) { report.getBlastMatchingProteins().addAll(processContext.getResultsOfSwissprotRemapping()); } else { // to check that at least one component has a feature boolean hasAtLeastOneFeature = false; // to check when a conflict has been detected boolean hasRangeConflict = false; for (Component component : components) { Collection<Feature> features = component.getBindingDomains(); if (!features.isEmpty()) { hasAtLeastOneFeature = true; for (Feature feature : features) { Collection<Range> ranges = feature.getRanges(); for (Range range : ranges) { // undetermined ranges are not affected by the new sequence if (!range.isUndetermined()) { for (BlastResults protein : processContext.getResultsOfSwissprotRemapping()) { if (!checkRangeValidWithNewSequence(range, protein, report)) { hasRangeConflict = true; } else { // The sequence of this Blast protein is not in conflict with the range, we // can keep it among the Blast results in the report report.addBlastMatchingProtein(protein); } } } } } } } // If all the components didn't contain any feature, there is no conflict, we can keep the // previous blast results if (!hasAtLeastOneFeature) { report.getBlastMatchingProteins().addAll(processContext.getResultsOfSwissprotRemapping()); } else { // there is no conflict, we can keep the previous blast results if (!hasRangeConflict) { report .getBlastMatchingProteins() .addAll(processContext.getResultsOfSwissprotRemapping()); } } } if (report.getBlastMatchingProteins().isEmpty()) { Status status = new Status( StatusLabel.FAILED, "The swissprot remapping is not possible as there are some conflicts between the sequence of the Swissprot entry and some feature ranges of the protein " + processContext.getIntactAccession() + ". We will keep the Trembl entry " + processContext.getTremblAccession()); report.setStatus(status); return processContext.getTremblAccession(); } else if (report.getBlastMatchingProteins().size() < initialNumberOfBlastProtein) { Status status = new Status( StatusLabel.TO_BE_REVIEWED, processContext.getResultsOfSwissprotRemapping().size() + " Swissprot entries on the initial " + initialNumberOfBlastProtein + " matching Swissprot proteins have a conflict between their sequence and some feature ranges of the protein " + processContext.getIntactAccession()); report.setStatus(status); return processContext.getTremblAccession(); } else { if (report.getBlastMatchingProteins().size() == 1) { BlastResults swissprot = report.getBlastMatchingProteins().iterator().next(); Status status = new Status( StatusLabel.COMPLETED, "We don't have any conflicts between the sequence of the Swissprot entry " + swissprot.getAccession() + " and the feature ranges of the protein " + processContext.getIntactAccession()); report.setStatus(status); return swissprot.getAccession(); } else { Status status = new Status( StatusLabel.COMPLETED, "We don't have any conflicts between the sequence(s) of the " + report.getBlastMatchingProteins().size() + " possible Swissprot proteins and the feature ranges of the protein " + processContext.getIntactAccession()); report.setStatus(status); ArrayList<BlastResults> proteins = new ArrayList<BlastResults>(); // merge the isoforms proteins.addAll(report.getBlastMatchingProteins()); Set<String> accessions = mergeIsoformsFromBlastProteins(proteins); if (accessions.size() == 1) { return accessions.iterator().next(); } else { return processContext.getTremblAccession(); } } } } }