Ignore:
Timestamp:
Nov 28, 2011, 9:18:01 AM (11 years ago)
Author:
robert@…
Message:

Last fixes and extra bugfix in import controller

Location:
trunk/grails-app/domain/nl/tno/massSequencing
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/domain/nl/tno/massSequencing/AssaySample.groovy

    r64 r75  
    11package nl.tno.massSequencing
     2import nl.tno.massSequencing.classification.*
    23
    34import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
     
    1213        // Grails datasource is used for executing custom SQL statement
    1314        def dataSource
     15        def sessionFactory
    1416       
    1517        // To be computed at run time (and saved in cache)
     
    7678         */
    7779        public int numClassifiedSequences() {
    78                 return Sequence.countByAssaySample( this );
     80                int numSeqs = 0;
     81                if( this.sequenceData ) {
     82                        sequenceData.each {
     83                                def sequenceDataNum = Sequence.countBySequenceData( it );
     84                                numSeqs += sequenceDataNum ?: 0;
     85                        }
     86                }
     87               
     88                return numSeqs
    7989        }
    8090       
     
    280290                otherAssaySample.numSequences   = numSequences;
    281291
     292                otherAssaySample.save( flush: true );
     293               
    282294                // Move attached data
    283295                def dataList = [] + sequenceData?.toList()
     
    293305                                        // Clone the sequencedata object
    294306                                        def sd = dataList[ j ]?.clone();
    295                                        
     307
    296308                                        if( sd )
    297309                                                otherAssaySample.addToSequenceData( sd );
    298 
     310                                       
    299311                                        // Copy all sequence classifications to the new sequenceData
    300                                         Sequence.executeUpdate( "UPDATE Sequence s SET s.sequenceData = :new WHERE s.sequenceData = :old ", [ 'old': dataList[ j ], 'new': sd ] )
     312                                        //log.debug "Removing sequences from sequencedata " + dataList[ j ]?.id + " to " + sd?.id
     313                                        //Sequence.executeUpdate( "UPDATE Sequence s SET s.sequenceData = :new WHERE s.sequenceData = :old ", [ 'old': dataList[ j ], 'new': sd ] )
     314                                        //Sequence.executeUpdate( "DELETE FROM Sequence s WHERE s.sequenceData = :old ", [ 'old': dataList[ j ] ] )
    301315                               
    302316                                        // Remove the old sequencedata object
     
    310324                        otherAssaySample.run.removeFromAssaySamples( otherAssaySample );
    311325                }
    312                
     326
    313327                // Remove this sample from the run.
    314328                if( run ) {
     
    319333                        otherAssaySample.run = null;
    320334                }
     335               
    321336        }
    322337       
  • trunk/grails-app/domain/nl/tno/massSequencing/Sequence.groovy

    r59 r75  
    33import nl.tno.massSequencing.classification.Taxon
    44
    5 class Sequence {
     5class Sequence implements Serializable {
    66        // Unique name of this sequence
    77        String name
     
    2222       
    2323        static mapping = {
     24                id composite: ['name']
    2425                name index: 'name_idx'
    2526                classification index: 'taxon_idx'
    26                 sequenceData index: 'sequenceData_idx'
     27                sequenceData index: 'sequenceData_idx', cascade: "all-delete-orphan"
     28               
    2729        }
    2830}
  • trunk/grails-app/domain/nl/tno/massSequencing/classification/Taxon.groovy

    r70 r75  
    169169         * @return                              First taxon that is found and matches the criteria or null if nothing is found
    170170         */
    171         public static Taxon findTaxonByPath( def path, int startLevel = 0 ) {
     171        public static Taxon findTaxonByPath( def path, int startLevel = 0, taxonCache ) {
    172172                if( path.size() == 0 )
    173173                        return null;
     174                       
     175                // Check taxon cache
     176                def cacheTaxon = findTaxonInCache( taxonCache, path );
     177                if( cacheTaxon )
     178                        return cacheTaxon;
    174179                       
    175180                def leafLevel = path.size() - 1 + startLevel;
     
    203208                        }
    204209                       
     210                        storeTaxonInCache( taxonCache, path, leaf );
     211                       
    205212                        return leaf;
    206213                }
    207214               
    208215                return null;
     216        }
     217       
     218        public static emptyTaxonCache() {
     219                return [ "top": [:], "sub": [:] ];
     220        }
     221       
     222        protected static Taxon findTaxonInCache( cache, path ) {
     223                if( path.size() <= 3 ) {
     224                        return cache[ "top" ][ cacheKey( path ) ];
     225                } else {
     226                        def topCacheKey = cacheKey( path[0..2] );
     227                       
     228                        if( !cache[ "sub" ][ topCacheKey ] )
     229                                return null;
     230                       
     231                        return findTaxonInCache( cache[ "sub" ][ topCacheKey ], path[ 3..-1] );
     232                }
     233        }
     234       
     235        protected static void storeTaxonInCache( cache, path, taxon ) {
     236                // Keep a 'layered' cache: the first three levels are kept in this cache. The
     237                // next levels are kept in a separate cache, one map for each subtree, so
     238                // each map will have a size that we can still deal with
     239                //      [
     240                //      "top": [ "bacteria": x, "bacteria;firmicutes": y ],
     241                //      "sub": [ "bacteria;firmicutes;abc":
     242                //                              [ "def;ghi" : z, "def;gkl": m ]
     243                //                      ]
     244                if( path.size() <= 3 ) {
     245                        cache[ "top" ][ cacheKey( path ) ] = taxon;
     246                } else {
     247                        def topCacheKey = cacheKey( path[0..2] );
     248                        def restPath = path[3..-1]
     249                       
     250                        if( cache[ "sub" ][ topCacheKey ] == null ) {
     251                                cache[ "sub" ][ topCacheKey ] = emptyTaxonCache();
     252                        }
     253                       
     254                        storeTaxonInCache( cache[ "sub" ][ topCacheKey ], restPath, taxon )
     255                }
     256               
     257        }
     258       
     259        protected static cacheKey( path ) {
     260                return  path.join( ";" );
    209261        }
    210262       
     
    215267         * @param path                  An array or list with the names of the taxa in the path, ordered by level
    216268         * @param startLevel    Which level is the first entry in the list. Defaults to zero. Can be used in order to find taxa
    217          *                                              without the whole tree being specified (e.g. without the root element)
     269         *                                              without the whole tree being specified (e.g. without the root element)
     270         * @param taxonCache    Hashmap with cached data about taxa found
    218271         * @return                              First taxon that is found and matches the criteria or a new taxon if it didn't exist
    219272         */
    220         static Taxon findOrCreateTaxonByPath( def path, int startLevel = 0 ) {
    221                 def taxon = findTaxonByPath( path, startLevel );
     273        static Taxon findOrCreateTaxonByPath( def path, int startLevel = 0, def taxonCache = null ) {
     274                def taxon = findTaxonByPath( path, startLevel, taxonCache );
    222275               
    223276                if( taxon )
     
    233286                // However, we don't have to check the highest level, so we start at depth - 2
    234287                for( def level = depth - 2; level >= 0 && !found ; level-- ) {
    235                         parentNode = findTaxonByPath( path[ 0 .. level ], startLevel );
     288                        parentNode = findTaxonByPath( path[ 0 .. level ], startLevel, taxonCache );
    236289                       
    237290                        // If this taxon is found, it is the highest level
Note: See TracChangeset for help on using the changeset viewer.