Changeset 61 for trunk


Ignore:
Timestamp:
May 26, 2011, 2:48:32 PM (8 years ago)
Author:
robert@…
Message:

Implemented a screen to show percentages of classification (see #43, first part)

Location:
trunk
Files:
6 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/masssequencing/SandboxController.groovy

    r60 r61  
    153153               
    154154                response.outputStream.close()
     155        }
     156       
     157        def percentagesUnClassified = {
     158                def assaySamples = [ AssaySample.get( 102 ), AssaySample.get( 125 ), AssaySample.get( 129 ), AssaySample.get( 146 ), AssaySample.get( 104 ) ]
     159                println assaySamples
     160               
     161                //////////////////////////////////////////////////////////////////
     162                def percentages = Classification.percentagesClassified( assaySamples );
     163               
     164                //////////////////////////////////////////////////////////////////
     165               
     166                render percentages[ "percentages" ] as XML
    155167        }
    156168       
  • trunk/grails-app/domain/nl/tno/massSequencing/classification/Classification.groovy

    r59 r61  
    2929                version false
    3030        }
     31       
     32        public static percentagesClassified( AssaySample a ) {
     33                return percentagesClassified( [ a ] )[ 0 ]
     34        }
     35       
     36        /**
     37         *
     38         * @param assaySamples
     39         * @return
     40         */
     41        public static percentagesClassified( List assaySamples ) {
     42                // Create a hashmap with number of sequences and unclassified for each assaysample
     43                def classifications = Classification.executeQuery( "SELECT a.id, ( SELECT SUM(c.unclassified) FROM Classification c WHERE c.assaySample = a), (SELECT SUM(sd.numSequences) FROM SequenceData sd WHERE sd.sample = a) FROM AssaySample a WHERE a IN (:assaySamples) GROUP BY a.id", [ "assaySamples": assaySamples ] );
     44                def numSequences = [:]
     45                classifications.each {
     46                        def total = it[ 2 ] ?: 0;
     47                        def classified = it[ 1 ] ?: 0;
     48                       
     49                        numSequences[ it[ 0 ] ] = [ 'numSequences': total, 'numClassified': classified, 'numUnClassified': total - classified ];
     50                }
     51               
     52                // Retrieve classification levels for each assaySample
     53                def classificationLevels = Classification.executeQuery( "SELECT a.id, t.level, sum( c.unclassified ) FROM Classification c LEFT JOIN c.taxon t LEFT JOIN c.assaySample a WHERE a IN (:assaySamples) GROUP BY a.id, t.level ORDER BY a.id, t.level", [ "assaySamples": assaySamples ] );         
     54
     55                // Retrieve the maximum and minimum levels for these samples
     56                def levels = Classification.determineMinAndMaxLevels( assaySamples );
     57                def maxLevel = levels[ 0 ];
     58                def minLevel = levels[ 1 ];
     59               
     60                // Determine level names for the necessary levels
     61                levels = [:];
     62                minLevel.upto( maxLevel ) { level ->
     63                        def levelEnum = Taxon.Level.find { it.number() == level }
     64                        levels[ level ] = levelEnum?.description();
     65                }
     66               
     67                // First build a list of percentages for each assaysample, in order to have default values
     68                // in case there is no classification at all (at a specific level) for that assaysample
     69                def percentages = [:];
     70               
     71                assaySamples.each { assaySample ->
     72                        def currentLine = [
     73                                'assaySample': assaySample,
     74                                'numSequences': numSequences[ assaySample.id ].numSequences,
     75                                'data': [:]
     76                        ]
     77                       
     78                        minLevel.upto( maxLevel ) { level ->
     79                                currentLine.data[ level ] = [
     80                                        'description': levels[ level ],
     81                                        'percentageClassified': 0,
     82                                        'numUnclassified': numSequences[ assaySample.id ].numSequences,
     83                                        'level': level
     84                                ]
     85                        }
     86                       
     87                        percentages[ assaySample.id ] = currentLine;
     88                }
     89               
     90                // Now loop through all percentage lines. Each line contains:
     91                //              The assaySampleId
     92                //              A level number
     93                //              The number of sequences that have been classified at that level, but not at a higher level
     94                def currentAssaySampleId = -1;
     95                def numberUnclassified = 0;     // Number of sequences not classified at a higher level than the current level.
     96               
     97                classificationLevels.each { line ->
     98                        def assaySampleId = line[ 0 ];
     99                        def level = line[ 1 ];
     100                        def unclassifiedAtThisLevel = line[ 2 ];
     101                       
     102                        if( assaySampleId != currentAssaySampleId ) {
     103                                // Reset the number of sequences not classified at a higher level. The initial value
     104                                // it the number of sequences that have not been classified at all
     105                                numberUnclassified = numSequences[ assaySampleId ][ 'numUnClassified' ];
     106                                currentAssaySampleId = assaySampleId;
     107                        }
     108                       
     109                        // Compute the percentages.
     110                        def numTotalSequences = percentages[ assaySampleId ].numSequences;
     111                        percentages[ assaySampleId ].data[ level ].percentageClassified = 1 - ( numberUnclassified / numTotalSequences );
     112                        percentages[ assaySampleId ].data[ level ].numUnclassified = numberUnclassified;
     113                       
     114                        // Increase the number of unclassified sequences
     115                        numberUnclassified += unclassifiedAtThisLevel
     116                }
     117               
     118                return [ "percentages": percentages, "levels": levels ];
     119        }
     120       
     121        /**
     122         * Returns the minimum and maximum classification levels of the given list of assaysamples
     123         * @param assaySamples
     124         * @return      [ maxLevel, minLevel ]
     125         */
     126        public static determineMinAndMaxLevels( List assaySamples ) {
     127                return Classification.executeQuery( "SELECT MAX(t.level), MIN(t.level) FROM Classification c LEFT JOIN c.taxon t LEFT JOIN c.assaySample a WHERE a IN (:assaySamples)", [ "assaySamples": assaySamples ] )[ 0 ];
     128        }
     129
    31130}
  • trunk/grails-app/domain/nl/tno/massSequencing/classification/Taxon.groovy

    r60 r61  
    1010        */
    1111        enum Level {
    12                 DOMAIN(0), KINGDOM(1), PHYLUM(2), CLASS(3), ORDER(4), FAMILY(5), GENUS(6), SPECIES(7)
     12                DOMAIN(0, "Domain"), KINGDOM(1, "Kingdom"), PHYLUM(2, "Phylum"), CLASS(3, "Class"), ORDER(4, "Order"), FAMILY(5, "Family"), GENUS(6, "Genus"), SPECIES(7, "Species")
    1313               
    1414                private int levelNumber;
    15                 private Level( int number ) {
     15                private String description;
     16               
     17                private Level( int number, String description ) {
    1618                        levelNumber = number
     19                        this.description = description;
    1720                }
    1821               
    1922                public int number() { return levelNumber; }
     23                public String description() { return description; }
    2024        }
    2125       
  • trunk/grails-app/services/nl/tno/massSequencing/ClassificationService.groovy

    r60 r61  
    355355
    356356                // Find the maximum level present in this classification list
    357                 def levels = Classification.executeQuery( "SELECT MAX(t.level), MIN(t.level) FROM Classification c LEFT JOIN c.taxon t LEFT JOIN c.assaySample a WHERE a IN (:assaySamples)", [ "assaySamples": assaySamples ] )[ 0 ];
     357                def levels = Classification.determineMinAndMaxLevels( assaySamples );
    358358                def maxLevel = levels[ 0 ]
    359359                def minLevel = levels[ 1 ]
  • trunk/grails-app/views/run/show.gsp

    r60 r61  
    169169                                <a class="fasta disabled" href="#" onClick="return false;">Export as fasta</a><br />
    170170                        </g:else>
     171                       
     172                        <g:if test="${numReadableAssaySamples > 0}">
     173                                <a class="classification" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="percentageClassified" />', '#samples', 'Please select one or more samples to view classification' ); return false;">Percentage classified</a><br />
     174                        </g:if>
     175                        <g:else>
     176                                <a class="classification disabled" href="#" onClick="return false;">Percentage classified</a><br />
     177                        </g:else>
     178                       
    171179                </p>
    172180               
Note: See TracChangeset for help on using the changeset viewer.