Changeset 21 for trunk


Ignore:
Timestamp:
Mar 22, 2011, 3:04:40 PM (8 years ago)
Author:
robert@…
Message:

Solved issues with fuzzy matching (#23)

Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/services/nl/tno/metagenomics/SampleExcelService.groovy

    r19 r21  
    8585                if( !includeRun )
    8686                        fields = fields - runName
    87                        
     87               
     88                       
     89                // Do matching using fuzzy search. The 0.8 treshold makes sure that no match if chosen if
     90                // there is actually no match at all.
     91                def matches = fuzzySearchService.mostSimilarUnique( headers, possibleFields, 0.8 );
     92               
    8893                headers.eachWithIndex { header, idx ->
    89                         // Do matching using fuzzy search. The 0.8 treshold makes sure that no match if chosen if
    90                         // there is actually no match at all.
    91                         if( !header || header.toString().trim() == "" )
    92                                 bestMatches[idx] = null
    93                         else
    94                                 bestMatches[idx] = fuzzySearchService.mostSimilar( header, possibleFields, 0.8 );
     94                        bestMatches[idx] = matches[idx].candidate;
    9595                }
    9696               
  • trunk/grails-app/services/nl/tno/metagenomics/imports/FuzzySearchService.groovy

    r2 r21  
    44
    55    static transactional = true
     6       
     7        /**
     8         * Matches the patterns with the candidates, and returns the best candidates for all patterns, but returning
     9         * the candidates only once
     10         *
     11         * @param patterns              List with patterns to search for
     12         * @param candidates    List with candidates to search in
     13         * @param treshold              Treshold the matches have to be above
     14         * @return                             
     15         */
     16        static def mostSimilarUnique( patterns, candidates, treshold ) {
     17                def matches = []
     18               
     19                // Find the best matching candidate for each pattern
     20                patterns.each { pattern ->
     21                        def topScore = 0
     22                        def bestFit = null
     23                       
     24                        candidates.each { candidate ->
     25                                def score = stringSimilarity(pattern, candidate);
     26                                if( score >= treshold )
     27                                        matches << [ 'pattern': pattern, 'candidate': candidate, 'score': score ];
     28                        }
     29                }
     30               
     31                // Sort the list on descending score
     32                matches = matches.sort( { a, b -> b.score <=> a.score } as Comparator )
     33               
     34                // Loop through the scores and select the best matching for every candidate
     35                def results = patterns.collect { [ 'pattern': it, 'candidate': null ] }
     36                def selectedCandidates = [];
     37                def filledPatterns = [];
     38               
     39                matches.each { match ->
     40                        if( !filledPatterns.contains( match.pattern ) && !selectedCandidates.contains( match.candidate ) ) {
     41                                results.find { result -> result.pattern == match.pattern }?.candidate = match.candidate;
     42                               
     43                                selectedCandidates << match.candidate;
     44                                filledPatterns << match.pattern;
     45                        }
     46                }
     47               
     48                return results
     49        }
    650
    751        // classes for fuzzy string matching
  • trunk/grails-app/views/assay/parseTagExcel.gsp

    r2 r21  
    1717                        <g:each in="${headers}" var="header" status="i">
    1818                                <td>
    19                                         <g:select name="matches.${i}" from="${possibleFields}" value="${bestMatches[i]}" />
     19                                        <g:select name="matches.${i}" from="${possibleFields}" value="${bestMatches[i]}" onChange="fixDuplicateSelections(this);" />
    2020                                </td>
    2121                        </g:each>
  • trunk/grails-app/views/assay/show.gsp

    r13 r21  
    1414                <g:javascript src="showSampleDialogUniversal.js" />
    1515                <g:javascript src="addFilesDialog.js" />
     16                <g:javascript src="enterTagsDialog.js" />
    1617
    1718                <g:javascript src="fileuploader.new.js" />
  • trunk/grails-app/views/run/parseTagExcel.gsp

    r7 r21  
    1717                        <g:each in="${headers}" var="header" status="i">
    1818                                <td>
    19                                         <g:select name="matches.${i}" from="${possibleFields}" value="${bestMatches[i]}" />
     19                                        <g:select name="matches.${i}" from="${possibleFields}" value="${bestMatches[i]}" onChange="fixDuplicateSelections(this);" />
    2020                                </td>
    2121                        </g:each>
  • trunk/grails-app/views/run/show.gsp

    r15 r21  
    99                <g:javascript src="jquery.ui.tabbeddialog.js" />
    1010                <g:javascript src="addFilesDialog.js" />
     11                <g:javascript src="enterTagsDialog.js" />
    1112
    1213                <g:javascript src="run.show.enterTagsDialog.js" />
  • trunk/web-app/js/assay.show.enterTagsDialog.js

    r9 r21  
    1 $(function() {
    2         $( "#enterTagsDialog" ).tabbedDialog({
    3                 height: 450,
    4                 width: 750,
    5                 modal: true,
    6                 autoOpen: false,
    7                 buttons: {
    8                         "Save": function() {
    9                                 var $tabs = $('#enterTagsDialog').tabs();
    10                                 var selectedTab = $tabs.tabs('option', 'selected' );
    11                                
    12                                 if( selectedTab == 0 ) {                // Tab 'manual input' selected
    13                                         $( 'form[name=updateTagsManually]' ).submit();
    14                                 } else if( selectedTab == 1 ) { // Tab 'excel input' selected
    15                                         // Check whether we are in step 1 (uploading a file) or step 2 (matching columns)
    16                                         // Step 1 has a form[name=uploadExcel], step 2 has a form[name=matchColumns]
    17                                         if( $( 'form[name=uploadExcel]' ).length == 1 ) {
    18                                                 // Step 1: save shouldn't be used. The upload is handled in the onUpload handler of
    19                                                 // the upload object. See also handleTagExcel method
    20                                                 return;
    21                                         } else {
    22                                                 $( 'form[name=matchColumns]' ).submit();
    23                                         }
    24                                 }
    25                         },
    26                         "Close": function() { $(this).dialog( "close" ) }
    27                 }               
    28         });
    29 });
    30 
    31 function showEnterTagsDialog() {
    32         $( "#enterTagsDialog" ).dialog( "open" );
    33 }
    34 
    351/**
    362 * Handles the file upload of an excel file with tag data
  • trunk/web-app/js/run.show.enterTagsDialog.js

    r9 r21  
    1 $(function() {
    2         $( "#enterTagsDialog" ).tabbedDialog({
    3                 height: 450,
    4                 width: 750,
    5                 modal: true,
    6                 autoOpen: false,
    7                 buttons: {
    8                         "Save": function() {
    9                                 var $tabs = $('#enterTagsDialog').tabs();
    10                                 var selectedTab = $tabs.tabs('option', 'selected' );
    11                                
    12                                 if( selectedTab == 0 ) {                // Tab 'manual input' selected
    13                                         $( 'form[name=updateTagsManually]' ).submit();
    14                                 } else if( selectedTab == 1 ) { // Tab 'excel input' selected
    15                                         // Check whether we are in step 1 (uploading a file) or step 2 (matching columns)
    16                                         // Step 1 has a form[name=uploadExcel], step 2 has a form[name=matchColumns]
    17                                         if( $( 'form[name=uploadExcel]' ).length == 1 ) {
    18                                                 // Step 1: save shouldn't be used. The upload is handled in the onUpload handler of
    19                                                 // the upload object. See also handleTagExcel method
    20                                                 return;
    21                                         } else {
    22                                                 $( 'form[name=matchColumns]' ).submit();
    23                                         }
    24                                 }
    25                         },
    26                         "Close": function() { $(this).dialog( "close" ) }
    27                 }               
    28         });
    29 });
    30 
    31 function showEnterTagsDialog() {
    32         $( "#enterTagsDialog" ).dialog( "open" );
    33 }
    34 
    351/**
    362 * Handles the file upload of an excel file with tag data
Note: See TracChangeset for help on using the changeset viewer.