Ignore:
Timestamp:
May 17, 2011, 1:44:07 PM (8 years ago)
Author:
robert@…
Message:

Implemented importing of classifications

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/nl/tno/massSequencing/FastaController.groovy

    r49 r58  
    99        def fastaService
    1010        def sessionFactory
    11        
    12         /**************************************************************************
    13          *
    14          * Methods for handling uploaded sequence and quality files
    15          *
    16          *************************************************************************/
    17 
    18         /**
    19          * Shows a screen that processing is done
    20          */
    21         def showProcessScreen = {
    22                 def entityType = params.entityType
    23 
    24                 // Check whether files are given
    25                 def names = params.sequencefiles
    26 
    27                 if( !names ) {
    28                         flash.message = "No files uploaded for processing"
    29                         if( params.entityType && params.id)
    30                                 redirect( controller: params.entityType, action: 'show', 'id': params.id)
    31                         else
    32                                 redirect( url: "" )
    33                                
    34                         return
    35                 }
    36                
    37                 // If only 1 file is uploaded, it is given as String
    38                 ArrayList filenames = []
    39                 if( names instanceof String )
    40                         filenames << names
    41                 else
    42                         names.each { filenames << it }
    43                        
    44                 // Save filenames in session
    45                 session.processFilenames = names;
    46                
    47                 // Check for total size of the files in order to be able
    48                 // to show a progress bar
    49                 long filesize = 0;
    50                 names.each {
    51                         filesize += fileService.get( it )?.length()
    52                 }
    53                 session.processProgress = [
    54                         numFiles: names.size(),
    55                         numBytes: filesize,
    56                         filesProcessed: 0,
    57                         bytesProcessed: 0
    58                 ]
    59                        
    60                 [entityId: params.id, entityType: params.entityType, filenames: names, url: createLink( action: 'showProcessResult', id: params.id, params: [entityType: entityType] ) ]
    61         }
    62        
    63         /**
    64          * Processes uploaded files and tries to combine them with samples
    65          */
    66         def process = {
    67                 def entity
    68                 def assaySamples
    69                
    70                 switch( params.entityType ) {
    71                         case "run":
    72                                 entity = getRun( params.id );
    73                                 assaySamples = entity.assaySamples.findAll { it.assay.study.canRead( session.user ) };
    74                                 break;
    75                         case "assay":
    76                                 entity = getAssay( params.id );
    77                                 assaySamples = entity.assaySamples;
    78                                 break;
    79                         default:
    80                                 response.setStatus( 404, "No controller found" );
    81                                 render "";
    82                                 return;
    83                 }
    84 
    85                 if (!entity) {
    86                         response.setStatus( 404, flash.error )
    87                         render "";
    88                         return
    89                 }
    90 
    91                 // Check whether files are given
    92                 def names = session.processFilenames
    93 
    94                 if( !names ) {
    95                         response.setStatus( 500, "No files uploaded for processing" )
    96                         render "";
    97                         return
    98                 }
    99 
    100                 // If only 1 file is uploaded, it is given as String
    101                 ArrayList filenames = []
    102                 if( names instanceof String )
    103                         filenames << names
    104                 else
    105                         names.each { filenames << it }
    106 
    107                 /* Parses uploaded files, discards files we can not handle
    108                  *
    109                  * [
    110                  *              success: [
    111                  *                      [filename: 'abc.fasta', type: FASTA, numSequences: 190]
    112                  *                      [filename: 'cde.fasta', type: FASTA, numSequences: 140]
    113                  *                      [filename: 'abc.qual', type: QUAL, numSequences: 190, avgQuality: 38]
    114                  *                      [filename: 'cde.qual', type: QUAL, numSequences: 140, avgQuality: 29]
    115                  *              ],
    116                  *              failure: [
    117                  *                      [filename: 'testing.xls', message: 'Type not recognized']
    118                  *              ]
    119                  * ]
    120                  *
    121                  * The second parameter is a callback function to update progress indicators
    122                  */
    123                 def httpSession = session;
    124                 def parsedFiles = fastaService.parseFiles( filenames, { files, bytes, totalFiles, totalBytes ->
    125                         httpSession.processProgress.numFiles += totalFiles;
    126                         httpSession.processProgress.numBytes += totalBytes;
    127                         httpSession.processProgress.filesProcessed = files;
    128                         httpSession.processProgress.bytesProcessed = bytes;
    129                 } );
    130                
    131                 // Check which assaySamples to use (only the ones visible to the user)
    132                 assaySamples = assaySamples.findAll { it.assay.study.canWrite( session.user ) }
    133 
    134                 // Match files with samples in the database
    135                 def matchedFiles = fastaService.matchFiles( parsedFiles.success, assaySamples );
    136 
    137                 // Sort files on filename
    138                 matchedFiles.sort { a,b -> a.fasta?.originalfilename <=> b.fasta?.originalfilename }
    139 
    140                 // Saved file matches in session to use them later on
    141                 session.processedFiles = [ parsed: parsedFiles, matched: matchedFiles ];
    142 
    143                 render ""
    144         }
    145        
    146         def getProgress = {
    147                 if( !session.processProgress ) {
    148                         response.setStatus( 500, "No progress information found" );
    149                         render ""
    150                         return
    151                 }
    152                
    153                 render session.processProgress as JSON
    154         }
    155        
    156         /**
    157          * Show result of processing
    158          */
    159         def showProcessResult = {
    160                 // load study with id specified by param.id
    161                 def entity
    162                
    163                 switch( params.entityType ) {
    164                         case "run":
    165                                 entity = getRun( params.id )
    166                                 break;
    167                         case "assay":
    168                                 entity = getAssay( params.id )
    169                                 break;
    170                         default:
    171                                 response.setStatus( 404, "No entity found" );
    172                                 render "";
    173                                 return;
    174                 }
    175 
    176                 if (!entity) {
    177                         response.setStatus( 404, flash.error )
    178                         render "";
    179                         return
    180                 }
    181                
    182                 if( !session.processedFiles ) {
    183                         flash.error = "Processing of files failed. Maybe the session timed out."
    184                         redirect( controller: 'assay', action: 'show', 'id': params.id)
    185                         return
    186                 }
    187                
    188                 [entityType: params.entityType, entity: entity, id: params.id, parsedFiles: session.processedFiles.parsed, matchedFiles: session.processedFiles.matched, selectedRun: params.selectedRun ]
    189         }
    190 
    191         /**
    192          * Returns from the upload wizard without saving the data. The uploaded files are removed
    193          */
    194         def returnWithoutSaving = {
    195                 // Delete all uploaded files from disk
    196                 session.processedFiles?.parsed?.success?.each {
    197                         fileService.delete( it.filename );
    198                 }
    199 
    200                 // Redirect to the correct controller           
    201                 switch( params.entityType ) {
    202                         case "run":
    203                         case "assay":
    204                                 redirect( controller: params.entityType, action: "show", id: params.id );
    205                                 return;
    206                         default:
    207                                 response.setStatus( 404, "No entity found" );
    208                                 render "";
    209                                 return;
    210                 }
    211                
    212                
    213         }
    214        
    215         /**
    216          * Saves processed files to the database, based on the selections made by the user
    217          */
    218         def saveProcessedFiles = {
    219                 // load entity with id specified by param.id
    220                 def entity
    221                
    222                 switch( params.entityType ) {
    223                         case "run":
    224                                 entity = getRun( params.id );
    225                                 break;
    226                         case "assay":
    227                                 entity = getAssay( params.id );
    228                                 break;
    229                         default:
    230                                 response.setStatus( 404, "No entity found" );
    231                                 render "";
    232                                 return;
    233                 }
    234 
    235                 if (!entity) {
    236                         response.setStatus( 404, flash.error )
    237                         render "";
    238                         return
    239                 }
    240 
    241                 // Check whether files are given
    242                 def files = params.file
    243 
    244                 if( !files ) {
    245                         flash.message = "No files were selected."
    246                         redirect( controller: params.entityType, action: 'show', 'id': params.id)
    247                         return
    248                 }
    249 
    250                 File permanentDir = fileService.absolutePath( ConfigurationHolder.config.massSequencing.fileDir )
    251                 int numSuccesful = 0;
    252                 def errors = [];
    253                
    254                 // Loop through all files Those are the numeric elements in the 'files' array
    255                 def digitRE = ~/^\d+$/;
    256                 files.findAll { it.key.matches( digitRE ) }.each { file ->
    257                         def filevalue = file.value;
    258                        
    259                         // Check if the file is selected
    260                         if( filevalue.include == "on" ) {
    261                                 if( fileService.fileExists( filevalue.fasta ) ) {
    262                                         try {
    263                                                 def permanent = fastaService.savePermanent( filevalue.fasta, filevalue.qual, session.processedFiles );
    264                                                
    265                                                 // Save the data into the database
    266                                                 SequenceData sd = new SequenceData();
    267                                                
    268                                                 sd.sequenceFile = permanent.fasta
    269                                                 sd.qualityFile = permanent.qual
    270                                                 sd.numSequences = permanent.numSequences
    271                                                 sd.averageQuality = permanent.avgQuality
    272                                                        
    273                                                 def sample = AssaySample.get( filevalue.assaySample );
    274                                                 if( sample )
    275                                                         sample.addToSequenceData( sd );
    276                                                
    277                                                 if( !sd.validate() ) {
    278                                                         errors << "an error occurred while saving " + filevalue.fasta + ": validation of SequenceData failed.";
    279                                                 } else {
    280                                                         sd.save(flush:true);
    281                                                 }
    282                                                
    283                                                 numSuccesful++;
    284                                         } catch( Exception e ) {
    285                                                 errors << "an error occurred while saving " + filevalue.fasta + ": " + e.getMessage()
    286                                         }
    287                                 }
    288                         } else {
    289                                 // File doesn't need to be included in the system. Delete it also from disk
    290                                 fileService.delete( filevalue.fasta );
    291                         }
    292                 }
    293 
    294                 // Return all files that have not been moved
    295                 session.processedFiles?.parsed?.success?.each {
    296                         fileService.delete( it.filename );
    297                 }
    298                
    299                 // Return a message to the user
    300                 if( numSuccesful == 0 ) {
    301                         flash.error = "None of the files were imported, because "
    302                        
    303                         if( errors.size() > 0 ) {
    304                                 errors.each {
    305                                         flash.error += "<br />- " + it
    306                                 }
    307                         } else {
    308                                 flash.error = "none of the files were selected for import."
    309                         }
    310                 } else {
    311                         flash.message = numSuccesful + " files have been added to the system. "
    312 
    313                         if( errors.size() > 0 ) {
    314                                 flash.error += errors.size() + " errors occurred during import: "
    315                                 errors.each {
    316                                         flash.error += "<br />- " + it
    317                                 }
    318                         }
    319                 }
    320                
    321                 redirect( controller: params.entityType, action: "show", id: params.id )
    322         }
    32311       
    32412        def deleteData = {
Note: See TracChangeset for help on using the changeset viewer.