package org.molgenis.mutation.service; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.molgenis.auth.MolgenisUser; import org.molgenis.core.OntologyTerm; import org.molgenis.core.dto.PublicationDTO; import org.molgenis.core.service.PublicationService; import org.molgenis.framework.db.Database; import org.molgenis.framework.db.DatabaseException; import org.molgenis.mutation.dto.ExonSearchCriteriaDTO; import org.molgenis.mutation.dto.ExonDTO; import org.molgenis.mutation.dto.GeneDTO; import org.molgenis.mutation.dto.MutationSummaryDTO; import org.molgenis.mutation.dto.PatientSummaryDTO; import org.molgenis.mutation.dto.ProteinDomainDTO; import org.molgenis.mutation.dto.VariantDTO; import org.molgenis.mutation.util.SequenceUtils; import org.molgenis.pheno.AlternateId; import org.molgenis.pheno.ObservableFeature; import org.molgenis.pheno.ObservationElement; import org.molgenis.pheno.ObservedValue; import org.molgenis.pheno.dto.ObservedValueDTO; import org.molgenis.pheno.dto.ProtocolDTO; import org.molgenis.pheno.service.PhenoService; import org.molgenis.protocol.Protocol; import org.molgenis.submission.Submission; import org.molgenis.variant.Exon; import org.molgenis.variant.Gene; import org.molgenis.variant.Patient; import org.molgenis.variant.Protein; import org.molgenis.variant.ProteinDomain; import org.molgenis.variant.SequenceCharacteristic; import org.molgenis.variant.SequenceRelation; import org.molgenis.variant.Variant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MolgenisVariantService { protected Database db; protected EntityManager em; protected Map<String, OntologyTerm> ontologyTermCache; @Autowired protected PhenoService phenoService; @Autowired protected PublicationService publicationService; //@Autowired public void setDatabase(final Database db) { this.db = db; /*FIXME: This should not be in a setter */ this.phenoService.setDatabase(db); this.publicationService.setDatabase(db); this.em = db.getEntityManager(); this.init(); } private void init() { try { List<OntologyTerm> ontologyTermList = this.db.query(OntologyTerm.class).find(); this.ontologyTermCache = new HashMap<String, OntologyTerm>(); for (OntologyTerm ontologyTerm : ontologyTermList) { this.ontologyTermCache.put(ontologyTerm.getName(), ontologyTerm); } } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public Map<String, OntologyTerm> getOntologyTermCache() { return this.ontologyTermCache; } public ExonDTO findExonByMutationPosition(final String position) { try { Pattern reExon = Pattern.compile("^(\\d+)$"); Pattern reIntron = Pattern.compile("^(\\d+)([+-])(\\d+)$"); Matcher mExon = reExon.matcher(position); Matcher mIntron = reIntron.matcher(position); if (mExon.matches()) { return this.findExonByCdnaPosition(Integer.parseInt(mExon.group(1))); } else if (mIntron.matches()) { // search by gDNA position since intron don't have cDNA position int cdnaPosition = Integer.parseInt(mIntron.group(1)); String operation = mIntron.group(2); int cdnaAdder = Integer.parseInt(mIntron.group(3)); int gdnaPosition; ExonDTO exonDTO = this.findExonByCdnaPosition(cdnaPosition); if ("+".equals(operation)) gdnaPosition = ("F".equals(exonDTO.getOrientation()) ? exonDTO.getGdnaStart() + cdnaAdder : exonDTO.getGdnaStart() - cdnaAdder); else gdnaPosition = ("F".equals(exonDTO.getOrientation()) ? exonDTO.getGdnaStart() - cdnaAdder : exonDTO.getGdnaStart() + cdnaAdder); return this.findExonByGdnaPosition(gdnaPosition); } else { throw new SearchServiceException("Invalid position notation: " + position); } } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public ExonDTO findExonByCdnaPosition(final int position) { try { List<Exon> exons = this.db.query(Exon.class).equals(Exon.ISINTRON, false).lessOrEqual(Exon.STARTCDNA, position).greaterOrEqual(Exon.ENDCDNA, position).find(); if (exons.size() != 1) throw new SearchServiceException("Not exactly one exon matching for cDNA position " + position); return this.exonToExonDTO(exons.get(0)); } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public ExonDTO findExonByGdnaPosition(final int position) { try { String sql = "SELECT e FROM Exon e WHERE ((e.startGdna <= :startPos AND :endPos <= e.endGdna AND e.strand = '+1') OR (e.endGdna <= :endPos AND :startPos <= e.startGdna AND e.strand = '-1'))"; TypedQuery<Exon> query = this.em.createQuery(sql, Exon.class); query.setParameter("startPos", position); query.setParameter("endPos", position); List<Exon> exonList = query.getResultList(); if (exonList.size() != 1) throw new SearchServiceException("Not exactly one exon matching for gDNA position " + position); return this.exonToExonDTO(exonList.get(0)); } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } /* * Retrieve the one and only gene from the database * @return data transfer object for the gene */ public GeneDTO findGene() { try { List<Gene> geneList = this.db.query(Gene.class).find(); if (geneList.size() == 0) throw new SearchServiceException("No gene found in database."); Gene gene = geneList.get(0); // return this.sequenceCharacteristicToGeneDTO(gene); return this.geneToGeneDTO(gene); } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } /** * Convert a list of Genes into a list of GeneDTOs * @param geneList * @return geneDTOList */ public List<GeneDTO> geneListToGeneDTOList(final List<Gene> geneList) { List<GeneDTO> geneDTOList = new ArrayList<GeneDTO>(); for (Gene gene : geneList) { geneDTOList.add(this.geneToGeneDTO(gene)); } return geneDTOList; } /** * Convert a Gene into a GeneDTO * @param Gene gene * @return GeneDTO */ public GeneDTO geneToGeneDTO(final Gene gene) { GeneDTO geneDTO = new GeneDTO(); geneDTO.setId(gene.getId()); geneDTO.setLength(gene.getSeqlen()); geneDTO.setName(gene.getName()); geneDTO.setNuclSequence(gene.getResidues()); geneDTO.setSymbol(gene.getName()); // For simplicity: name == symbol (name is not needed) geneDTO.setBpEnd(gene.getEndGdna()); geneDTO.setBpStart(gene.getStartGdna()); geneDTO.setOrientation("-1".equals(gene.getStrand()) ? "R" : "F"); //TODO: What about "0"??? // find the relations to chromosome and protein List<SequenceRelation> relationList = Arrays.asList(gene.getSequenceFeatureSequenceRelationCollection().toArray(new SequenceRelation[0])); for (SequenceRelation relation : relationList) { SequenceCharacteristic tmp = relation.getSequenceTarget(); if ("chromosome".equals(tmp.getFeatureType().getName())) { geneDTO.setChromosome(tmp.getName()); } } Protein protein = gene.getProtein(); geneDTO.setAaSequence(protein.getResidues()); List<ObservedValue> observedValueList = Arrays.asList(gene.getFeatureObservedValueCollection().toArray(new ObservedValue[0])); for (ObservedValue observedValue : observedValueList) { if ("genbank".equals(observedValue.getFeature().getName())) geneDTO.setGenbankId(observedValue.getValue()); else if ("build".equals(observedValue.getFeature().getName())) geneDTO.setGenomeBuild(observedValue.getValue()); } // Query and sort the protein domains List<ProteinDomain> proteinDomainList = Arrays.asList(gene.getGeneProteinDomainCollection().toArray(new ProteinDomain[0])); List<ProteinDomainDTO> proteinDomainDTOList = proteinDomainListToProteinDomainDTOList(proteinDomainList); Collections.sort(proteinDomainDTOList); geneDTO.setProteinDomainDTOList(proteinDomainDTOList); return geneDTO; } /** * Convert a SequenceCharacteristic into a GeneDTO * @param SequenceCharacteristic gene * @return GeneDTO */ public GeneDTO sequenceCharacteristicToGeneDTO(final SequenceCharacteristic gene) { GeneDTO geneDTO = new GeneDTO(); geneDTO.setLength(gene.getSeqlen()); geneDTO.setName(gene.getName()); geneDTO.setNuclSequence(gene.getResidues()); geneDTO.setSymbol(gene.getName()); // For simplicity: name == symbol (name is not needed) // find the relations to chromosome and protein List<SequenceRelation> relationList = Arrays.asList(gene.getSequenceFeatureSequenceRelationCollection().toArray(new SequenceRelation[0])); for (SequenceRelation relation : relationList) { SequenceCharacteristic tmp = relation.getSequenceTarget(); if ("chromosome".equals(tmp.getFeatureType().getName())) { geneDTO.setBpEnd(relation.getFmax()); geneDTO.setBpStart(relation.getFmin()); geneDTO.setChromosome(tmp.getName()); geneDTO.setOrientation("-1".equals(relation.getStrand()) ? "R" : "F"); //TODO: What about "0"??? } else if ("protein".equals(tmp.getFeatureType().getName())) { geneDTO.setAaSequence(tmp.getResidues()); } } List<ObservedValue> observedValueList = Arrays.asList(gene.getFeatureObservedValueCollection().toArray(new ObservedValue[0])); for (ObservedValue observedValue : observedValueList) { if ("genbank".equals(observedValue.getFeature().getName())) geneDTO.setGenbankId(observedValue.getValue()); else if ("build".equals(observedValue.getFeature().getName())) geneDTO.setGenomeBuild(observedValue.getValue()); } return geneDTO; } /** * Convert a SequenceCharacteristic into a ExonDTO * @param SequenceCharacteristic exon * @return ExonDTO * @throws DatabaseException */ /* public ExonDTO sequenceCharacteristicToExonDTO(final SequenceCharacteristic exon) throws DatabaseException { ExonDTO exonDTO = new ExonDTO(); exonDTO.setId(exon.getId()); exonDTO.setIsIntron("intron".equals(exon.getFeatureType().getName()) ? true : false); exonDTO.setLength(exon.getSeqlen()); exonDTO.setName(exon.getName()); if (exon.getSeqlen() != null && exon.getSeqlen() % 3 == 0) exonDTO.setMultiple3Nucl(true); else exonDTO.setMultiple3Nucl(false); // find relation to the sequence of the gene List<SequenceRelation> sequenceRelationList = this.db.query(SequenceRelation.class).equals(SequenceRelation.SEQUENCEFEATURE, exon.getId()).find(); for (SequenceRelation relation : sequenceRelationList) { if (relation.getRelationType() == null) continue; SequenceCharacteristic tmp = relation.getSequenceTarget(); if ("part-of".equals(relation.getRelationType().getName()) && "cdna_sequence".equals(tmp.getFeatureType().getName())) { exonDTO.setCdnaEnd(relation.getFmax()); exonDTO.setCdnaStart(relation.getFmin()); } else if ("part-of".equals(relation.getRelationType().getName()) && "chromosome".equals(tmp.getFeatureType().getName())) { exonDTO.setGdnaEnd(relation.getFmax()); exonDTO.setGdnaStart(relation.getFmin()); } else if ("part-of".equals(relation.getRelationType().getName()) && "protein_domain".equals(tmp.getFeatureType().getName())) { exonDTO.getDomainId().add(tmp.getId()); exonDTO.getDomainName().add(tmp.getName()); } } // find protein domains String sql = "SELECT s FROM SequenceRelation r JOIN r.sequenceFeature s WHERE s.featureType.name = 'protein_domain' AND ((r.fmin <= :pos AND :pos <= r.fmax AND r.strand = '+1') OR (r.fmax <= :pos AND :pos <= r.fmin AND r.strand = '-1'))"; TypedQuery<SequenceCharacteristic> query = this.em.createQuery(sql, SequenceCharacteristic.class); query.setParameter("pos", exonDTO.getGdnaStart()); for (SequenceCharacteristic proteinDomain : query.getResultList()) { exonDTO.getDomainId().add(proteinDomain.getId()); exonDTO.getDomainName().add(proteinDomain.getName()); } GeneDTO geneDTO = this.findGene(); Integer gdnaStart = Math.abs(exonDTO.getGdnaStart() - geneDTO.getBpStart().intValue()); Integer gdnaEnd = Math.abs(exonDTO.getGdnaEnd() - geneDTO.getBpStart().intValue());//gdnaStart + exon.getLength(); exonDTO.setNuclSequence(StringUtils.substring(geneDTO.getNuclSequence(), gdnaStart, gdnaEnd + 1)); exonDTO.setNuclSequenceFlankLeft(this.getNuclSequenceFlankLeft(exonDTO, geneDTO)); exonDTO.setNuclSequenceFlankRight(this.getNuclSequenceFlankRight(exonDTO, geneDTO)); exonDTO.setOrientation(geneDTO.getOrientation()); if (!exonDTO.getIsIntron()) { exonDTO.setNuclSequence(exonDTO.getNuclSequence().toUpperCase()); exonDTO.setNuclSequenceFlankLeft(exonDTO.getNuclSequenceFlankLeft().toLowerCase()); exonDTO.setNuclSequenceFlankRight(exonDTO.getNuclSequenceFlankRight().toLowerCase()); exonDTO.setAaSequence(StringUtils.substring(geneDTO.getAaSequence(), exonDTO.getCdnaStart(), exonDTO.getCdnaEnd() + 1)); exonDTO.setNumFullAminoAcids(SequenceUtils.getNumFullAminoAcids(exonDTO.getAaSequence())); exonDTO.setNumPartAminoAcids(SequenceUtils.getNumPartAminoAcids(exonDTO.getAaSequence())); exonDTO.setNumGlyXYRepeats(SequenceUtils.getNumGlyXYRepeats(exonDTO.getAaSequence())); } if (exonDTO.getIsIntron()) { exonDTO.setNuclSequence(exonDTO.getNuclSequence().toLowerCase()); exonDTO.setNuclSequenceFlankLeft(exonDTO.getNuclSequenceFlankLeft().toUpperCase()); exonDTO.setNuclSequenceFlankRight(exonDTO.getNuclSequenceFlankRight().toUpperCase()); } return exonDTO; } */ /** * Convert a SequenceCharacteristic into a ExonDTO * @param SequenceCharacteristic exon * @return ExonDTO * @throws DatabaseException */ public ExonDTO exonToExonDTO(final Exon exon) throws DatabaseException { ExonDTO exonDTO = new ExonDTO(); exonDTO.setId(exon.getId()); exonDTO.setIsIntron(exon.getIsIntron()); exonDTO.setLength(exon.getSeqlen()); exonDTO.setName(exon.getName()); if (exon.getSeqlen() != null && exon.getSeqlen() % 3 == 0) exonDTO.setMultiple3Nucl(true); else exonDTO.setMultiple3Nucl(false); exonDTO.setGdnaStart(exon.getStartGdna()); exonDTO.setGdnaEnd(exon.getEndGdna()); if (!exonDTO.getIsIntron()) { exonDTO.setCdnaStart(exon.getStartCdna()); exonDTO.setCdnaEnd(exon.getEndCdna()); } // find protein domains String sql = "SELECT p FROM ProteinDomain p WHERE ((p.startGdna <= :startPos AND :endPos <= p.endGdna AND p.strand = '+1') OR (p.endGdna <= :endPos AND :startPos <= p.startGdna AND p.strand = '-1'))"; TypedQuery<ProteinDomain> query = this.em.createQuery(sql, ProteinDomain.class); query.setParameter("startPos", exon.getStartGdna()); query.setParameter("endPos", exon.getEndGdna()); // String sql = "SELECT s FROM SequenceRelation r JOIN r.sequenceFeature s WHERE s.featureType.name = 'protein_domain' AND ((r.fmin <= :pos AND :pos <= r.fmax AND r.strand = '+1') OR (r.fmax <= :pos AND :pos <= r.fmin AND r.strand = '-1'))"; // TypedQuery<SequenceCharacteristic> query = this.em.createQuery(sql, SequenceCharacteristic.class); // query.setParameter("pos", exonDTO.getGdnaStart()); for (ProteinDomain proteinDomain : query.getResultList()) { exonDTO.getDomainId().add(proteinDomain.getId()); exonDTO.getDomainName().add(proteinDomain.getName()); } Integer gdnaStart = Math.abs(exonDTO.getGdnaStart() - exon.getGene().getStartGdna()); Integer gdnaEnd = Math.abs(exonDTO.getGdnaEnd() - exon.getGene().getStartGdna());//gdnaStart + exon.getLength(); exonDTO.setNuclSequence(StringUtils.substring(exon.getGene().getResidues(), gdnaStart, gdnaEnd + 1)); exonDTO.setNuclSequenceFlankLeft(this.getNuclSequenceFlankLeft(exonDTO, exon.getGene())); exonDTO.setNuclSequenceFlankRight(this.getNuclSequenceFlankRight(exonDTO, exon.getGene())); exonDTO.setOrientation("-1".equals(exon.getStrand()) ? "R" : "F"); //TODO: What about "0"??? if (!exonDTO.getIsIntron()) { exonDTO.setNuclSequence(exonDTO.getNuclSequence().toUpperCase()); exonDTO.setNuclSequenceFlankLeft(exonDTO.getNuclSequenceFlankLeft().toLowerCase()); exonDTO.setNuclSequenceFlankRight(exonDTO.getNuclSequenceFlankRight().toLowerCase()); exonDTO.setAaSequence(StringUtils.substring(exon.getGene().getProtein().getResidues(), exonDTO.getCdnaStart() - 1, exonDTO.getCdnaEnd())); exonDTO.setNumFullAminoAcids(SequenceUtils.getNumFullAminoAcids(exonDTO.getAaSequence())); exonDTO.setNumPartAminoAcids(SequenceUtils.getNumPartAminoAcids(exonDTO.getAaSequence())); exonDTO.setNumGlyXYRepeats(SequenceUtils.getNumGlyXYRepeats(exonDTO.getAaSequence())); } if (exonDTO.getIsIntron()) { exonDTO.setNuclSequence(exonDTO.getNuclSequence().toLowerCase()); exonDTO.setNuclSequenceFlankLeft(exonDTO.getNuclSequenceFlankLeft().toUpperCase()); exonDTO.setNuclSequenceFlankRight(exonDTO.getNuclSequenceFlankRight().toUpperCase()); } return exonDTO; } public List<ExonDTO> exonListToExonDTOList(final List<Exon> exons) throws DatabaseException { List<ExonDTO> result = new ArrayList<ExonDTO>(); for (Exon exon : exons) result.add(this.exonToExonDTO(exon)); return result; } /* public List<ExonDTO> sequenceCharacteristicListToExonDTOList(final List<SequenceCharacteristic> exons) throws DatabaseException { List<ExonDTO> result = new ArrayList<ExonDTO>(); for (SequenceCharacteristic exon : exons) result.add(this.sequenceCharacteristicToExonDTO(exon)); return result; } */ public List<VariantDTO> variantListToVariantDTOList(final List<Variant> variantList) { List<VariantDTO> result = new ArrayList<VariantDTO>(); for (Variant variant : variantList) result.add(this.variantToVariantDTO(variant)); return result; } public List<VariantDTO> sequenceCharacteristicListToVariantDTOList(final List<SequenceCharacteristic> variantList) { List<VariantDTO> result = new ArrayList<VariantDTO>(); for (SequenceCharacteristic variant : variantList) result.add(this.sequenceCharacteristicToVariantDTO(variant)); return result; } public VariantDTO variantToVariantDTO(final Variant variant) { try { VariantDTO variantDTO = new VariantDTO(); variantDTO.setAaNotation(variant.getNameAa()); variantDTO.setAaStart(variant.getStartAa()); variantDTO.setCdnaNotation(variant.getNameCdna()); variantDTO.setCdnaStart(variant.getStartCdna()); variantDTO.setGdnaStart(variant.getStartGdna()); variantDTO.setId(variant.getId()); /* Find the external molgenis variant id */ for (AlternateId alternateId : variant.getAlternateId()) { if ("molgenis_variant_id".equals(alternateId.getDefinition())) variantDTO.setIdentifier(alternateId.getName()); } /* Find corresponding exon/intron */ String sql = "SELECT e FROM Exon e WHERE ((e.startGdna <= :position AND :position <= e.endGdna AND e.strand = '+1') OR (e.endGdna <= :position AND :position <= e.startGdna AND e.strand = '-1'))"; TypedQuery<Exon> exonQuery = this.em.createQuery(sql, Exon.class); exonQuery.setParameter("position", variant.getStartGdna()); for (Exon exon : exonQuery.getResultList()) { variantDTO.setExonId(exon.getId()); variantDTO.setExonName(exon.getName()); } variantDTO.setGeneName(variant.getGene().getName()); /* Find prominent value to be displayed in table view */ String pathoSql = "SELECT ov FROM ObservedValue ov JOIN ov.feature f WHERE ov.target = :target AND (f.name = 'Pathogenicity' OR f.name = 'Consequence' OR f.name = 'Inheritance')"; TypedQuery<ObservedValue> pathoQuery = this.em.createQuery(pathoSql, ObservedValue.class); pathoQuery.setParameter("target", variant); List<ObservedValue> observedValueList = pathoQuery.getResultList(); for (ObservedValue observedValue : observedValueList) { if (StringUtils.equals(observedValue.getFeature_Name(), "Pathogenicity")) { variantDTO.setObservedValue(observedValue.getValue()); } else if (StringUtils.equals(observedValue.getFeature_Name(), "Consequence")) { variantDTO.setConsequence(observedValue.getValue()); } else if (StringUtils.equals(observedValue.getFeature_Name(), "Inheritance")) { variantDTO.setInheritance(observedValue.getValue()); } } return variantDTO; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public VariantDTO sequenceCharacteristicToVariantDTO(final SequenceCharacteristic variant) { try { VariantDTO variantDTO = new VariantDTO(); variantDTO.setCdnaNotation(variant.getName()); variantDTO.setId(variant.getId()); /* Find the amino acid notation */ List<SequenceRelation> targetRelations = this.db.query(SequenceRelation.class).equals(SequenceRelation.TARGET, variant.getId()).find(); for (SequenceRelation relation : targetRelations) { if ("result-of".equals(relation.getRelationType().getName())) { SequenceCharacteristic feature = relation.getSequenceFeature(); OntologyTerm featureType = feature.getFeatureType(); if (featureType == null) continue; if ("gdna-variant".equals(feature.getFeatureType().getName())) { variantDTO.setGdnaStart(relation.getFmin()); } else if ("aa-variant".equals(feature.getFeatureType().getName())) { variantDTO.setAaNotation(feature.getName()); variantDTO.setAaStart(relation.getFmin()); } } } /* Find the external molgenis variant id */ for (AlternateId alternateId : variant.getAlternateId()) { if ("molgenis_variant_id".equals(alternateId.getDefinition())) variantDTO.setIdentifier(alternateId.getName()); } /* Find corresponding exon/intron */ String exonSql = "SELECT DISTINCT r FROM SequenceRelation r JOIN r.sequenceTarget t WHERE t.featureType.name IN ('exon', 'intron') AND r.sequenceFeature = :feature"; TypedQuery<SequenceRelation> exonQuery = this.em.createQuery(exonSql, SequenceRelation.class); exonQuery.setParameter("feature", variant); for (SequenceRelation relation : exonQuery.getResultList()) { variantDTO.setExonId(relation.getSequenceTarget().getId()); variantDTO.setExonName(relation.getSequenceTarget().getName()); variantDTO.setCdnaStart(relation.getFmin()); } /* Find prominent value to be displayed in table view */ String pathoSql = "SELECT ov FROM ObservedValue ov JOIN ov.feature f WHERE ov.target = :target AND (f.name = 'Pathogenicity' OR f.name = 'consequence')"; TypedQuery<ObservedValue> pathoQuery = this.em.createQuery(pathoSql, ObservedValue.class); pathoQuery.setParameter("target", variant); List<ObservedValue> observedValueList = pathoQuery.getResultList(); /* A proper data model would ensure that exactly one is found. * But you get what you deserve. */ if (observedValueList.size() == 1) variantDTO.setObservedValue(observedValueList.get(0).getValue()); return variantDTO; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public MutationSummaryDTO sequenceCharacteristicToMutationSummaryDTO(final SequenceCharacteristic variant) { try { MutationSummaryDTO mutationSummaryDTO = new MutationSummaryDTO(); mutationSummaryDTO.setId(variant.getId()); mutationSummaryDTO.setCdnaNotation(variant.getName()); mutationSummaryDTO.setGdnaNotation(""); mutationSummaryDTO.setAaNotation(""); /* Find the external molgenis variant id */ for (AlternateId alternateId : variant.getAlternateId()) { if ("molgenis_variant_id".equals(alternateId.getDefinition())) mutationSummaryDTO.setIdentifier(alternateId.getName()); } /* Find all relevant SequenceRelations */ List<SequenceRelation> featureRelations = this.db.query(SequenceRelation.class).equals(SequenceRelation.FEATURE, variant.getId()).find(); for (SequenceRelation relation : featureRelations) { if ("part-of".equals(relation.getRelationType().getName())) { SequenceCharacteristic target = (SequenceCharacteristic) relation.getTarget(); if ("exon".equals(target.getFeatureType().getName()) || "intron".equals(target.getFeatureType().getName())) { mutationSummaryDTO.setCdnaEnd(relation.getFmax()); mutationSummaryDTO.setCdnaStart(relation.getFmin()); mutationSummaryDTO.setExonId(target.getId()); mutationSummaryDTO.setExonName(target.getName()); } } } List<SequenceRelation> targetRelations = this.db.query(SequenceRelation.class).equals(SequenceRelation.TARGET, variant.getId()).find(); for (SequenceRelation relation : targetRelations) { if ("result-of".equals(relation.getRelationType().getName())) { SequenceCharacteristic feature = relation.getSequenceFeature(); OntologyTerm featureType = feature.getFeatureType(); if (featureType == null) continue; if ("gdna-variant".equals(feature.getFeatureType().getName())) { mutationSummaryDTO.setGdnaEnd(relation.getFmax()); mutationSummaryDTO.setGdnaNotation(feature.getName()); mutationSummaryDTO.setGdnaStart(relation.getFmin()); } else if ("aa-variant".equals(feature.getFeatureType().getName())) { mutationSummaryDTO.setAaEnd(relation.getFmax()); mutationSummaryDTO.setAaNotation(feature.getName()); mutationSummaryDTO.setAaStart(relation.getFmin()); } } } if (StringUtils.isNotEmpty(mutationSummaryDTO.getAaNotation())) mutationSummaryDTO.setNiceNotation(mutationSummaryDTO.getCdnaNotation() + " (" + mutationSummaryDTO.getAaNotation() + ")"); else mutationSummaryDTO.setNiceNotation(mutationSummaryDTO.getCdnaNotation()); /* find ObservedValue's, separate 'Inheritance' and 'Consequence' */ mutationSummaryDTO.setProtocolDTOList(new ArrayList<ProtocolDTO>()); mutationSummaryDTO.setObservedValueDTOHash(new HashMap<String, List<ObservedValueDTO>>()); List<Protocol> protocolList = this.em.createQuery("SELECT p FROM Protocol p", Protocol.class).getResultList(); for (Protocol protocol : protocolList) { String sql = "SELECT ov FROM ObservedValue ov WHERE ov.target = :target AND feature IN (:features)"; TypedQuery<ObservedValue> query = this.em.createQuery(sql, ObservedValue.class); query.setParameter("target", variant); query.setParameter("features", protocol.getFeatures()); List<ObservedValue> observedValueList = query.getResultList(); if (observedValueList.size() > 0) { mutationSummaryDTO.getProtocolDTOList().add(phenoService.protocolToProtocolDTO(protocol)); mutationSummaryDTO.getObservedValueDTOHash().put("Protocol" + protocol.getId(), phenoService.observedValueListToObservedValueDTOList(observedValueList)); } } /* Set "special" values that are displayed prominent: * Consequence, Inheritance, Pathogenicity */ String sql = "SELECT ov FROM ObservedValue ov WHERE ov.target = :target"; TypedQuery<ObservedValue> query = this.em.createQuery(sql, ObservedValue.class); query.setParameter("target", variant); List<ObservedValue> specialObservedValueList = query.getResultList(); for (ObservedValue observedValue : specialObservedValueList) { if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "codon change")) { mutationSummaryDTO.setCodonChange(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "consequence")) { mutationSummaryDTO.setConsequence(observedValue.getValue()); mutationSummaryDTO.setObservedValue(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "inheritance")) { mutationSummaryDTO.setInheritance(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "pathogenicity")) { mutationSummaryDTO.setPathogenicity(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "type of mutation")) { mutationSummaryDTO.setType(observedValue.getValue()); } } mutationSummaryDTO.setPatientSummaryDTOList(new ArrayList<PatientSummaryDTO>()); // helper hash to get distinct phenotypes HashMap<String, String> phenotypeNameHash = new HashMap<String, String>(); // helper hash to get distinct publications HashMap<String, PublicationDTO> publicationDTOHash = new HashMap<String, PublicationDTO>(); List<Patient> patients = this.db.query(Patient.class).equals(Patient.MUTATIONS, variant.getId()).find(); // Get distinct list, not available in Molgenis query language HashMap<Integer, Patient> patientHash = new HashMap<Integer, Patient>(); for (Patient patient : patients) patientHash.put(patient.getId(), patient); patients = Arrays.asList(patientHash.values().toArray(new Patient[0])); List<ObservableFeature> features = this.db.query(ObservableFeature.class).equals(ObservableFeature.NAME, "Phenotype").or().equals(ObservableFeature.DESCRIPTION, "Phenotype").find(); if (features.size() != 1) throw new DatabaseException("Not exactly one ObservableFeature with name 'Phenotype' found."); for (Patient patient : patients) { PatientSummaryDTO patientSummaryDTO = new PatientSummaryDTO(); patientSummaryDTO.setPatientIdentifier(patient.getAlternateId().get(0).getName()); List<ObservedValue> phenotypes = this.db.query(ObservedValue.class).equals(ObservedValue.FEATURE, features.get(0).getId()).equals(ObservedValue.TARGET, patient.getId()).find(); List<String> phenotypeNames = new ArrayList<String>(); for (ObservedValue phenotype : phenotypes) { phenotypeNames.add(phenotype.getValue()); phenotypeNameHash.put(phenotype.getValue(), phenotype.getValue()); } patientSummaryDTO.setPhenotypeMajor(StringUtils.join(phenotypeNames, ", ")); patientSummaryDTO.setPhenotypeSub(""); /* We will also retrieve the mutation that we already have * Delete the first we find from the otherVariants list * (It can be present more than once.) */ boolean found = false; for (SequenceCharacteristic patientVariant : patient.getMutations()) { if (patientVariant.getId().equals(variant.getId()) && !found) { found = true; continue; } patientSummaryDTO.getVariantDTOList().add(this.sequenceCharacteristicToVariantDTO(patientVariant)); } Submission submission = patient.getSubmission(); MolgenisUser submitter = submission.getSubmitters().get(0); patientSummaryDTO.setSubmitterDepartment(submitter.getDepartment()); patientSummaryDTO.setSubmitterInstitute(submitter.getAffiliation_Name()); patientSummaryDTO.setSubmitterCity(submitter.getCity()); patientSummaryDTO.setSubmitterCountry(submitter.getCountry()); patientSummaryDTO.setPublicationDTOList(new ArrayList<PublicationDTO>()); if (CollectionUtils.isNotEmpty(patient.getPatientreferences())) { List<PublicationDTO> publicationDTOList = publicationService.publicationListToPublicationDTOList(patient.getPatientreferences()); for (PublicationDTO publicationDTO : publicationDTOList) { patientSummaryDTO.getPublicationDTOList().add(publicationDTO); publicationDTOHash.put(publicationDTO.getName(), publicationDTO); } } mutationSummaryDTO.getPatientSummaryDTOList().add(patientSummaryDTO); } mutationSummaryDTO.setPhenotypeNameList(new ArrayList<String>()); mutationSummaryDTO.getPhenotypeNameList().addAll(phenotypeNameHash.values()); mutationSummaryDTO.setPublicationDTOList(new ArrayList<PublicationDTO>()); mutationSummaryDTO.getPublicationDTOList().addAll(publicationDTOHash.values()); mutationSummaryDTO.setPubmedURL(PublicationService.PUBMED_URL); return mutationSummaryDTO; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public MutationSummaryDTO variantToMutationSummaryDTO(final Variant variant) { try { MutationSummaryDTO mutationSummaryDTO = new MutationSummaryDTO(); mutationSummaryDTO.setId(variant.getId()); mutationSummaryDTO.setCdnaNotation(variant.getNameCdna()); mutationSummaryDTO.setCdnaStart(variant.getStartCdna()); mutationSummaryDTO.setGdnaNotation(variant.getNameGdna()); mutationSummaryDTO.setGdnaStart(variant.getStartGdna()); mutationSummaryDTO.setAaNotation(variant.getNameAa()); mutationSummaryDTO.setAaStart(variant.getStartAa()); mutationSummaryDTO.setType(variant.getType()); /* Find the external molgenis variant id */ for (AlternateId alternateId : variant.getAlternateId()) { if ("molgenis_variant_id".equals(alternateId.getDefinition())) mutationSummaryDTO.setIdentifier(alternateId.getName()); } /* Find exons */ String sql = "SELECT e FROM Exon e WHERE ((e.startGdna <= :pos AND :pos <= e.endGdna AND e.strand = '+1') OR (e.endGdna <= :pos AND :pos <= e.startGdna AND e.strand = '-1'))"; TypedQuery<Exon> query = this.em.createQuery(sql, Exon.class); query.setParameter("pos", variant.getStartGdna()); for (Exon exon : query.getResultList()) { mutationSummaryDTO.setExonId(exon.getId()); mutationSummaryDTO.setExonName(exon.getName()); } // mutationSummaryDTO.setExonId(variant.getExon().getId()); // mutationSummaryDTO.setExonName(variant.getExon().getName()); /* Find protein domains */ String sqlpd = "SELECT pd FROM ProteinDomain pd WHERE ((pd.startGdna <= :pos AND :pos <= pd.endGdna AND pd.strand = '+1') OR (pd.endGdna <= :pos AND :pos <= pd.startGdna AND pd.strand = '-1'))"; TypedQuery<ProteinDomain> querypd = this.em.createQuery(sqlpd, ProteinDomain.class); querypd.setParameter("pos", variant.getStartGdna()); mutationSummaryDTO.setProteinDomainNameList(new ArrayList<String>()); for (ProteinDomain proteinDomain : querypd.getResultList()) { mutationSummaryDTO.getProteinDomainNameList().add(proteinDomain.getName()); } mutationSummaryDTO.setGeneName(variant.getGene().getName()); if (StringUtils.isNotEmpty(mutationSummaryDTO.getAaNotation())) mutationSummaryDTO.setNiceNotation(mutationSummaryDTO.getCdnaNotation() + " (" + mutationSummaryDTO.getAaNotation() + ")"); else mutationSummaryDTO.setNiceNotation(mutationSummaryDTO.getCdnaNotation()); /* find ObservedValue's, separate 'Inheritance' and 'Consequence' */ mutationSummaryDTO.setProtocolDTOList(new ArrayList<ProtocolDTO>()); mutationSummaryDTO.setObservedValueDTOHash(new HashMap<String, List<ObservedValueDTO>>()); List<Protocol> protocolList = this.em.createQuery("SELECT p FROM Protocol p", Protocol.class).getResultList(); for (Protocol protocol : protocolList) { if (protocol.getFeatures().size() == 0) continue; String sql2 = "SELECT ov FROM ObservedValue ov WHERE ov.target = :target AND feature IN (:features)"; TypedQuery<ObservedValue> query2 = this.em.createQuery(sql2, ObservedValue.class); query2.setParameter("target", variant); query2.setParameter("features", protocol.getFeatures()); List<ObservedValue> observedValueList = query2.getResultList(); if (observedValueList.size() > 0) { mutationSummaryDTO.getProtocolDTOList().add(phenoService.protocolToProtocolDTO(protocol)); mutationSummaryDTO.getObservedValueDTOHash().put("Protocol" + protocol.getId(), phenoService.observedValueListToObservedValueDTOList(observedValueList)); } } /* Set "special" values that are displayed prominent: * Consequence, Inheritance, Pathogenicity */ String sql3 = "SELECT ov FROM ObservedValue ov WHERE ov.target = :target"; TypedQuery<ObservedValue> query3 = this.em.createQuery(sql3, ObservedValue.class); query3.setParameter("target", variant); List<ObservedValue> specialObservedValueList = query3.getResultList(); for (ObservedValue observedValue : specialObservedValueList) { if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "codon change")) { mutationSummaryDTO.setCodonChange(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "consequence")) { mutationSummaryDTO.setConsequence(observedValue.getValue()); mutationSummaryDTO.setObservedValue(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "inheritance")) { mutationSummaryDTO.setInheritance(observedValue.getValue()); } else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "pathogenicity")) { mutationSummaryDTO.setPathogenicity(observedValue.getValue()); } // else if (StringUtils.equalsIgnoreCase(observedValue.getFeature().getName(), "type of mutation")) // { // mutationSummaryDTO.setType(observedValue.getValue()); // } } mutationSummaryDTO.setPatientSummaryDTOList(new ArrayList<PatientSummaryDTO>()); // helper hash to get distinct phenotypes HashMap<String, String> phenotypeNameHash = new HashMap<String, String>(); // helper hash to get distinct publications HashMap<Integer, PublicationDTO> publicationDTOHash = new HashMap<Integer, PublicationDTO>(); List<Patient> patients = this.db.query(Patient.class).equals(Patient.MUTATIONS, variant.getId()).find(); // Get distinct list, not available in Molgenis query language HashMap<Integer, Patient> patientHash = new HashMap<Integer, Patient>(); for (Patient patient : patients) patientHash.put(patient.getId(), patient); patients = Arrays.asList(patientHash.values().toArray(new Patient[0])); for (Patient patient : patients) { PatientSummaryDTO patientSummaryDTO = new PatientSummaryDTO(); for (AlternateId alternateId : patient.getAlternateId()) { if ("molgenis_patient_id".equals(alternateId.getDefinition())) { patientSummaryDTO.setPatientIdentifier(alternateId.getName()); } } patientSummaryDTO.setPhenotypeMajor(patient.getPhenotype()); phenotypeNameHash.put(patient.getPhenotype(), patient.getPhenotype()); /* We will also retrieve the mutation that we already have * Delete the first we find from the otherVariants list * (It can be present more than once.) */ boolean found = false; for (SequenceCharacteristic patientVariant : patient.getMutations()) { if (patientVariant.getId().equals(variant.getId()) && !found) { found = true; continue; } patientSummaryDTO.getVariantDTOList().add(this.variantToVariantDTO((Variant) patientVariant)); } Submission submission = patient.getSubmission(); MolgenisUser submitter = submission.getSubmitters().get(0); patientSummaryDTO.setSubmitterDepartment(submitter.getDepartment()); patientSummaryDTO.setSubmitterInstitute(submitter.getAffiliation_Name()); patientSummaryDTO.setSubmitterCity(submitter.getCity()); patientSummaryDTO.setSubmitterCountry(submitter.getCountry()); patientSummaryDTO.setPublicationDTOList(new ArrayList<PublicationDTO>()); if (CollectionUtils.isNotEmpty(patient.getPatientreferences())) { List<PublicationDTO> publicationDTOList = publicationService.publicationListToPublicationDTOList(patient.getPatientreferences()); for (PublicationDTO publicationDTO : publicationDTOList) { patientSummaryDTO.getPublicationDTOList().add(publicationDTO); publicationDTOHash.put(publicationDTO.getId(), publicationDTO); } } mutationSummaryDTO.getPatientSummaryDTOList().add(patientSummaryDTO); } mutationSummaryDTO.setPhenotypeNameList(new ArrayList<String>()); mutationSummaryDTO.getPhenotypeNameList().addAll(phenotypeNameHash.values()); mutationSummaryDTO.setPublicationDTOList(new ArrayList<PublicationDTO>()); mutationSummaryDTO.getPublicationDTOList().addAll(publicationDTOHash.values()); mutationSummaryDTO.setPubmedURL(PublicationService.PUBMED_URL); return mutationSummaryDTO; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public List<MutationSummaryDTO> observationElementListToMutationSummaryDTOList(final List<ObservationElement> mutationList) { List<Variant> result = new ArrayList<Variant>(); for (ObservationElement e : mutationList) { if (e instanceof Variant) { result.add((Variant) e); } else if (e instanceof Patient) { String sql = "SELECT s FROM Patient p JOIN p.mutations s WHERE p = :patient"; TypedQuery<Variant> query = this.em.createQuery(sql, Variant.class); query.setParameter("patient", e); result.addAll(query.getResultList()); } } return this.variantListToMutationSummaryDTOList(result); } public List<MutationSummaryDTO> variantListToMutationSummaryDTOList(final List<Variant> mutations) { List<MutationSummaryDTO> result = new ArrayList<MutationSummaryDTO>(); for (Variant mutation : mutations) { MutationSummaryDTO mutationSummaryVO = this.variantToMutationSummaryDTO(mutation); result.add(mutationSummaryVO); } return result; } public List<MutationSummaryDTO> sequenceCharacteristicListToMutationSummaryDTOList(final List<SequenceCharacteristic> mutations) { List<MutationSummaryDTO> result = new ArrayList<MutationSummaryDTO>(); for (SequenceCharacteristic mutation : mutations) { MutationSummaryDTO mutationSummaryVO = this.sequenceCharacteristicToMutationSummaryDTO(mutation); result.add(mutationSummaryVO); } return result; } public PatientSummaryDTO patientToPatientSummaryDTO(final Patient patient) { PatientSummaryDTO patientSummaryDTO = new PatientSummaryDTO(); patientSummaryDTO.setPatientId(patient.getId()); patientSummaryDTO.setPhenotypeMajor(patient.getPhenotype()); // find alternate IDs for (AlternateId alternateId : patient.getAlternateId()) { if ("molgenis_patient_id".equals(alternateId.getDefinition())) patientSummaryDTO.setPatientIdentifier(alternateId.getName()); else if ("local_patient_no".equals(alternateId.getDefinition())) patientSummaryDTO.setPatientLocalId(alternateId.getName()); } /* Add variants */ List<VariantDTO> variantDTOList = this.variantListToVariantDTOList(patient.getMutations()); patientSummaryDTO.setVariantDTOList(variantDTOList); if (variantDTOList.size() > 0) patientSummaryDTO.setGdnaStart(variantDTOList.get(0).getGdnaStart()); Submission submission = patient.getSubmission(); MolgenisUser submitter = submission.getSubmitters().get(0); patientSummaryDTO.setSubmitterDepartment(submitter.getDepartment()); patientSummaryDTO.setSubmitterInstitute(submitter.getAffiliation_Name()); patientSummaryDTO.setSubmitterCity(submitter.getCity()); patientSummaryDTO.setSubmitterCountry(submitter.getCountry()); /* Add literature references */ if (CollectionUtils.isNotEmpty(patient.getPatientreferences())) { patientSummaryDTO.setPublicationDTOList(publicationService.publicationListToPublicationDTOList(patient.getPatientreferences())); } patientSummaryDTO.setPubmedURL(PublicationService.PUBMED_URL); return patientSummaryDTO; } public List<PatientSummaryDTO> patientListToPatientSummaryDTOList(final List<Patient> patients) { List<PatientSummaryDTO> result = new ArrayList<PatientSummaryDTO>(); for (Patient patient : patients) { result.add(this.patientToPatientSummaryDTO(patient)); } Collections.sort(result); return result; } public ProteinDomainDTO proteinDomainToProteinDomainDTO(final ProteinDomain proteinDomain, final Boolean noIntrons) { try { ProteinDomainDTO proteinDomainDTO = new ProteinDomainDTO(); proteinDomainDTO.setDomainId(proteinDomain.getId()); proteinDomainDTO.setDomainName(proteinDomain.getName()); proteinDomainDTO.setGdnaEnd(proteinDomain.getEndGdna()); proteinDomainDTO.setGdnaStart(proteinDomain.getStartGdna()); proteinDomainDTO.setOrientation("-1".equals(proteinDomain.getStrand()) ? "R" : "F"); //TODO: What about "0"??? /* Find exons */ proteinDomainDTO.setExonDTOList(new ArrayList<ExonDTO>()); String sql = "SELECT e FROM Exon e WHERE e.isIntron = :isIntron AND ((:startPos <= e.startGdna AND e.endGdna <= :endPos AND e.strand = '+1') OR (:endPos <= e.endGdna AND e.startGdna <= :startPos AND e.strand = '-1'))"; TypedQuery<Exon> query = this.em.createQuery(sql, Exon.class); query.setParameter("isIntron", !noIntrons); query.setParameter("startPos", proteinDomain.getStartGdna()); query.setParameter("endPos", proteinDomain.getEndGdna()); for (Exon exon : query.getResultList()) { proteinDomainDTO.getExonDTOList().add(this.exonToExonDTO(exon)); } // find exons/introns in the region of this protein domain /* proteinDomainDTO.setExonDTOList(new ArrayList<ExonDTO>()); Query<SequenceRelation> query = this.db.query(SequenceRelation.class); if ("-1".equals(proteinDomainDTO.getOrientation())) { query = query.lessOrEqual(SequenceRelation.FMIN, proteinDomainDTO.getGdnaStart()); query = query.greaterOrEqual(SequenceRelation.FMAX, proteinDomainDTO.getGdnaEnd()); } else { query = query.greaterOrEqual(SequenceRelation.FMIN, proteinDomainDTO.getGdnaStart()); query = query.lessOrEqual(SequenceRelation.FMAX, proteinDomainDTO.getGdnaEnd()); } List<SequenceRelation> exonRelations = query.find(); for (SequenceRelation relation : exonRelations) { SequenceCharacteristic feature = relation.getSequenceFeature(); if ("exon".equals(feature.getFeatureType().getName())) proteinDomainDTO.getExonDTOList().add(this.sequenceCharacteristicToExonDTO(feature)); if (!noIntrons && "intron".equals(feature.getFeatureType().getName())) proteinDomainDTO.getExonDTOList().add(this.sequenceCharacteristicToExonDTO(feature)); } */ return proteinDomainDTO; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } /* public ProteinDomainDTO sequenceCharacteristicToProteinDomainDTO(final SequenceCharacteristic proteinDomain, final Boolean noIntrons) { try { ProteinDomainDTO proteinDomainDTO = new ProteinDomainDTO(); proteinDomainDTO.setDomainId(proteinDomain.getId()); proteinDomainDTO.setDomainName(proteinDomain.getName()); // find start and end position List<SequenceRelation> relations = Arrays.asList(proteinDomain.getSequenceFeatureSequenceRelationCollection().toArray(new SequenceRelation[0])); for (SequenceRelation relation : relations) { SequenceCharacteristic target = relation.getSequenceTarget(); if ("chromosome".equals(target.getFeatureType().getName())) { proteinDomainDTO.setGdnaEnd(relation.getFmax()); proteinDomainDTO.setGdnaStart(relation.getFmin()); proteinDomainDTO.setOrientation(relation.getStrand()); } } // find exons/introns in the region of this protein domain proteinDomainDTO.setExonDTOList(new ArrayList<ExonDTO>()); Query<SequenceRelation> query = this.db.query(SequenceRelation.class); if ("-1".equals(proteinDomainDTO.getOrientation())) { query = query.lessOrEqual(SequenceRelation.FMIN, proteinDomainDTO.getGdnaStart()); query = query.greaterOrEqual(SequenceRelation.FMAX, proteinDomainDTO.getGdnaEnd()); } else { query = query.greaterOrEqual(SequenceRelation.FMIN, proteinDomainDTO.getGdnaStart()); query = query.lessOrEqual(SequenceRelation.FMAX, proteinDomainDTO.getGdnaEnd()); } List<SequenceRelation> exonRelations = query.find(); for (SequenceRelation relation : exonRelations) { SequenceCharacteristic feature = relation.getSequenceFeature(); if ("exon".equals(feature.getFeatureType().getName())) proteinDomainDTO.getExonDTOList().add(this.sequenceCharacteristicToExonDTO(feature)); if (/*!noIntrons && "intron".equals(feature.getFeatureType().getName())) proteinDomainDTO.getExonDTOList().add(this.sequenceCharacteristicToExonDTO(feature)); } return proteinDomainDTO; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } */ public List<ProteinDomainDTO> proteinDomainListToProteinDomainDTOList(final List<ProteinDomain> proteinDomainList) { List<ProteinDomainDTO> result = new ArrayList<ProteinDomainDTO>(); for (ProteinDomain proteinDomain : proteinDomainList) result.add(this.proteinDomainToProteinDomainDTO(proteinDomain, true)); return result; } /* public List<ProteinDomainDTO> sequenceCharacteristicListToProteinDomainDTOList(final List<SequenceCharacteristic> proteinDomainList) { List<ProteinDomainDTO> result = new ArrayList<ProteinDomainDTO>(); for (SequenceCharacteristic proteinDomain : proteinDomainList) result.add(this.sequenceCharacteristicToProteinDomainDTO(proteinDomain, true)); return result; } */ /** * get the notation of the codon change for a given mutation * @param mutation * @return codon change * @throws DatabaseException */ // private String getCodonChange(SequenceCharacteristic mutation) throws DatabaseException // { // if (mutation.getAa_Position() == null || mutation.getAa_Position() == 0 || StringUtils.isEmpty(mutation.getCodonchange())) // return ""; // // GeneDTO geneDTO = this.getGene(); // String splicedSeq = SequenceUtils.splice(geneDTO.getNuclSequence()); // return SequenceUtils.getCodon(splicedSeq, mutation.getAa_Position()) + ">" + mutation.getCodonchange(); // } /** * Get the left flanking nucleotide sequence of given exon * @param exonDTO * @return Left flanking sequence */ private String getNuclSequenceFlankLeft(final ExonDTO exonDTO, final Gene gene) { Integer gdnaStart = Math.abs(exonDTO.getGdnaStart().intValue() - gene.getStartGdna()); Integer flankEnd = Math.abs(gdnaStart); Integer flankStart = Math.abs(flankEnd - 10); return StringUtils.substring(gene.getResidues(), flankStart, flankEnd); } /** * Get the right flanking nucleotide sequence of given exon * @param exon * @return Right flanking sequence */ private String getNuclSequenceFlankRight(final ExonDTO exonDTO, final Gene gene) { Integer gdnaStart = Math.abs(exonDTO.getGdnaStart().intValue() - gene.getStartGdna()); Integer gdnaEnd = gdnaStart + exonDTO.getLength(); Integer flankStart = gdnaEnd; Integer flankEnd = flankStart + 10; return StringUtils.substring(gene.getResidues(), flankStart, flankEnd); } /** * Get all exons sorted by their gDNA position * @return list of ExonDTO's */ public List<ExonDTO> findAllExons() { try { List<Exon> exonList = this.db.query(Exon.class).find(); List<ExonDTO> exonDTOList = this.exonListToExonDTOList(exonList); Collections.sort(exonDTOList); return exonDTOList; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } /** * Get all genes sorted by their gDNA position * @return list of GeneDTO's */ public List<GeneDTO> findAllGenes() { try { List<Gene> geneList = this.db.query(Gene.class).find(); List<GeneDTO> geneDTOList = this.geneListToGeneDTOList(geneList); Collections.sort(geneDTOList); return geneDTOList; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } /** * Get all introns sorted by their gDNA position * @return list of ExonDTO's */ /* public List<ExonDTO> findAllIntrons() { try { List<SequenceCharacteristic> exonList = this.db.query(SequenceCharacteristic.class).equals(SequenceCharacteristic.FEATURETYPE, this.ontologyTermCache.get("intron")).find(); List<ExonDTO> exonDTOList = this.sequenceCharacteristicListToExonDTOList(exonList); Collections.sort(exonDTOList); return exonDTOList; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } */ public ExonDTO findFirstExon(final ExonSearchCriteriaDTO criteria) { try { List<ExonDTO> exonDTOList = this.findAllExons(); for (ExonDTO exonDTO : exonDTOList) { if ((Boolean.TRUE.equals(criteria.getIsIntron()) && exonDTO.getIsIntron()) || (Boolean.FALSE.equals(criteria.getIsIntron()) && !exonDTO.getIsIntron())) return exonDTO; } // If we are here we did not find anything :-( return null; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public ExonDTO findPrevExon(final ExonSearchCriteriaDTO criteria) { if (criteria.getGdnaPosition() == null) return null; try { List<ExonDTO> exonDTOList = this.findAllExons(); for (int i = 0; i < exonDTOList.size(); i++) { ExonDTO exonDTO = exonDTOList.get(i); if (exonDTO.getId().equals(criteria.getExonId())) { if (i == 0) return exonDTOList.get(i); else return exonDTOList.get(i - 1); } } // If we are here we did not find anything :-( return null; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public ExonDTO findNextExon(final ExonSearchCriteriaDTO criteria) { if (criteria.getGdnaPosition() == null) return null; try { List<ExonDTO> exonDTOList = this.findAllExons(); for (int i = 0; i < exonDTOList.size(); i++) { ExonDTO exonDTO = exonDTOList.get(i); if (exonDTO.getId().equals(criteria.getExonId())) { if (i == exonDTOList.size() - 1) return exonDTOList.get(i); else return exonDTOList.get(i + 1); } } // If we are here we did not find anything :-( return null; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } public ExonDTO findLastExon(final ExonSearchCriteriaDTO criteria) { try { List<ExonDTO> exonDTOList = this.findAllExons(); Collections.reverse(exonDTOList); for (ExonDTO exonDTO : exonDTOList) { if ((Boolean.TRUE.equals(criteria.getIsIntron()) && exonDTO.getIsIntron()) || (Boolean.FALSE.equals(criteria.getIsIntron()) && !exonDTO.getIsIntron())) return exonDTO; } // If we are here we did not find anything :-( return null; } catch (Exception e) { e.printStackTrace(); throw new SearchServiceException(e.getMessage()); } } }