/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * Last commit: $Rev: 1552 $ by $Author: glycoslave $ on $Date:: 2009-07-20 #$ */ package test.eurocarbdb.dataaccess.core.seq; // stdlib imports import java.util.List; // 3rd party imports import org.testng.annotations.*; import org.hibernate.Criteria; // import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.MatchMode; // eurocarb imports import org.eurocarbdb.util.graph.Graph; import org.eurocarbdb.sugar.Sugar; import org.eurocarbdb.sugar.Anomer; import org.eurocarbdb.sugar.Linkage; import org.eurocarbdb.sugar.Residue; import org.eurocarbdb.sugar.Monosaccharide; import org.eurocarbdb.sugar.GlycosidicLinkage; import org.eurocarbdb.sugar.impl.SimpleMonosaccharide; import org.eurocarbdb.dataaccess.Eurocarb; import org.eurocarbdb.dataaccess.EntityManager; import org.eurocarbdb.dataaccess.core.GlycanSequence; import org.eurocarbdb.dataaccess.core.seq.SubstructureQuery; import org.eurocarbdb.dataaccess.core.seq.SubstructureQueryResult; import org.eurocarbdb.dataaccess.core.seq.SubstructureQuery.Option; import org.eurocarbdb.dataaccess.core.seq.SubstructureQueryCriterion; import test.eurocarbdb.dataaccess.CoreApplicationTest; // static imports import static java.lang.System.out; /** * Tests {@link SubstructureQuery}. * * @author mjh * @version $Rev: 1552 $ */ @Test ( groups={"sugar.search.substructure"} //, dependsOnGroups={"ecdb.db.populated"} , sequential=true ) public class SubstructureQueryTest extends CoreApplicationTest { /*~~~~~~~~~~~~~~~~~~~~~~~~~~ TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /** * search struct s1: *<pre> * Man1 * / \ * a1-3 a1-6 * / \ * Man2 Man3 *</pre> */ @Test public void substructureQuery1() throws Exception { System.out.println("--- query 1 ---"); setup(); Sugar s1 = new Sugar(); Monosaccharide r1 = monosac("Man"), r2 = monosac("Man"), r3 = monosac("Man"); s1.addRootResidue( r1 ); s1.addResidue( r1, linkage('a', 3, 1), r2 ); s1.addResidue( r1, linkage('a', 6, 1), r3 ); assert s1.countResidues() == 3; SubstructureQuery q1 = new SubstructureQuery( s1 ); q1.execute(); reportResults( q1 ); teardown(); } /** * search struct: *<pre> * Man1 * / \ * a1-3 a1-6 * / \ * Man2 Man3 * | * GlcNAc4 * | * Gal5 * *</pre> */ @Test public void substructureQuery2() throws Exception { System.out.println("--- query 2 ---"); setup(); Sugar s2 = new Sugar(); Monosaccharide r1 = monosac("Man"), r2 = monosac("Man"), r3 = monosac("Man"), r4 = monosac("GlcNAc"), r5 = monosac("Gal"); s2.addRootResidue( r1 ); s2.addResidue( r1, linkage('a', 3, 1), r2 ); s2.addResidue( r1, linkage('a', 6, 1), r3 ); s2.addResidue( r3, linkage(), r4 ); s2.addResidue( r4, linkage(), r5 ); assert s2.countResidues() == 5; SubstructureQuery q2 = new SubstructureQuery( s2 ); q2.execute(); reportResults( q2 ); teardown(); } /** find all structures with a non-reducing-terminal Man-Glc-Gal.<br/> * * search struct: *<pre> * Man1 * | * GlcNAc2 * | * Gal3 (leaf) * *</pre> */ @Test public void substructureQuery3() throws Exception { System.out.println("--- query 3 ---"); setup(); Sugar s3 = new Sugar(); s3.addRootResidue( monosac("Man") ); s3.addResidue( s3.lastResidue(), linkage(), monosac("Glc") ); s3.addResidue( s3.lastResidue(), linkage(), monosac("Gal") ); assert s3.countResidues() == 3; SubstructureQuery q3 = new SubstructureQuery( s3 ); q3.setOption( Option.Must_Include_All_Non_Reducing_Terminii ); q3.execute(); reportResults( q3 ); teardown(); } /** * find all structures with a non-reducing-terminal Gal-Gal.<br/> * search struct: *<pre> * Gal1 * | * Gal2 (leaf) * *</pre> */ @Test public void substructureQuery4() throws Exception { System.out.println("--- query 4 ---"); setup(); Sugar s4 = new Sugar(); s4.addRootResidue( monosac("Gal") ); s4.addResidue( s4.lastResidue(), linkage(), monosac("Gal") ); assert s4.countResidues() == 2; SubstructureQuery q4 = new SubstructureQuery( s4 ); q4.setOption( Option.Must_Include_All_Non_Reducing_Terminii ); q4.execute(); reportResults( q4 ); teardown(); } @Test public void substructureQuerySql() { setup(); Sugar s2 = new Sugar(); Monosaccharide r1 = monosac("Man"), r2 = monosac("Man"), r3 = monosac("Man"), r4 = monosac("GlcNAc"), r5 = monosac("Gal"); s2.addRootResidue( r1 ); s2.addResidue( r1, linkage('a', 3, 1), r2 ); s2.addResidue( r1, linkage('a', 6, 1), r3 ); s2.addResidue( r3, linkage(), r4 ); s2.addResidue( r4, linkage(), r5 ); assert s2.countResidues() == 5; SubstructureQuery q = new SubstructureQuery( s2 ); out.println("---"); out.println( "SQL:" ); out.println( q.getQueryString() ); out.println(); SubstructureQueryCriterion substruct_crit = q.getQueryCriterion(); out.println("---"); out.println( "criterion:" ); out.println( substruct_crit.toSqlString() ); out.println(); /* count of substruct results only */ out.println("---"); out.println("Criteria-based rowCount: " ); EntityManager em = Eurocarb.getEntityManager(); Object x = em.createQuery( GlycanSequence.class ) .setProjection( Projections.rowCount() ) .add( substruct_crit ) .uniqueResult() ; out.println(" " + x ); out.println(); /* BC lookup + substruct lookup */ out.println("---"); out.println("Criteria-based substruct query + biological context search: " ); List<GlycanSequence> results = (List<GlycanSequence>) em.createQuery( GlycanSequence.class ) .add( substruct_crit ) .createAlias("glycanContexts", "gc") .createAlias("gc.biologicalContext", "bc") .createAlias("bc.taxonomy", "t") .add( Restrictions.like( "t.taxon", "xenopus", MatchMode.START ) ) .setMaxResults( 10 ) .list() ; if ( results != null && results.size() > 0 ) { for ( GlycanSequence gs : results ) { out.println(" " + gs ); } } else { out.println(" (query successful but no results)"); } teardown(); } /* helper methods */ static Monosaccharide monosac( String name ) { // return lib.getInstanceOf( Monosaccharide.class, name ); return SimpleMonosaccharide.forName( name ); } static GlycosidicLinkage linkage( char anomer, int parent_term, int child_term ) { return new GlycosidicLinkage( Anomer.forName(anomer), parent_term, child_term ); } static void reportResults( SubstructureQuery q ) { List<SubstructureQueryResult> sequences = q.getResults(); int count_results = sequences.size(); if ( count_results > 0 ) { int first_ten = (count_results > 10) ? 10 : sequences.size(); StringBuilder sb = new StringBuilder(); out.println( "listing first " + first_ten + " of " + count_results + " total substructure result(s) only:" ); for ( int i = 0; i < first_ten; i++ ) { GlycanSequence gs = sequences.get(i).getMatchedGlycanSequence(); out.println( "substructure result " + ( i + 1 ) + " " + gs.toString() /* + ( VERBOSE_LOGGING ? ": \n" + gs.getSugarSequence().getSugar().getGraph() : "" ) */ ); } } else { out.println( "(no results for query)" ); } } static GlycosidicLinkage linkage() { return new GlycosidicLinkage(); } /* public static void main( String[] args ) throws Exception { SubstructureQueryTest q = new SubstructureQueryTest(); q.substructureQuery1(); q.substructureQuery2(); q.substructureQuery3(); q.substructureQuery4(); } */ } // end class