Changeset 2156 for trunk/grails-app/services/dbnp
- Timestamp:
- Jan 30, 2012, 3:41:51 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/services/dbnp/studycapturing/AssayService.groovy
r2120 r2156 63 63 'Sampling Event Data' : getUsedTemplateFields( samples*."parentEvent".unique() ), 64 64 'Sample Data' : getUsedTemplateFields( samples ), 65 'Event Group' : [[name: 'name', comment: 'Name of Event Group', displayName: 'name']], 65 'Event Group' : [ 66 [name: 'name', comment: 'Name of Event Group', displayName: 'name'] 67 ], 66 68 'Module Measurement Data': moduleMeasurements, 67 69 'Module Error': moduleError … … 186 188 } 187 189 188 def moduleError = '', moduleMeasurementData = [:] 190 def moduleError = '', moduleMeasurementData = [:], moduleMeasurementMetaData = [:] 189 191 190 192 if (measurementTokens) { 191 193 192 194 try { 193 moduleMeasurementData = requestModuleMeasurements(assay, measurementTokens, samples, remoteUser)195 moduleMeasurementData = requestModuleMeasurements(assay, measurementTokens, samples, remoteUser) 194 196 } catch (e) { 195 moduleMeasurementData = ['error' : ['Module error, module not available or unknown assay'] * samples.size() ] 197 moduleMeasurementData = ['error' : [ 198 'Module error, module not available or unknown assay'] 199 * samples.size() ] 196 200 e.printStackTrace() 197 201 moduleError = e.message 198 202 } 199 200 } 201 202 [ 'Subject Data' : getFieldValues(samples, fieldMap['Subject Data'], 'parentSubject'), 203 'Sampling Event Data' : getFieldValues(samples, fieldMap['Sampling Event Data'], 'parentEvent'), 204 'Sample Data' : getFieldValues(samples, fieldMap['Sample Data']), 205 'Event Group' : eventFieldMap, 206 'Module Measurement Data' : moduleMeasurementData, 207 'Module Error' : moduleError 208 ] 203 } 204 205 [ 'Subject Data' : getFieldValues(samples, fieldMap['Subject Data'], 'parentSubject'), 206 'Sampling Event Data' : getFieldValues(samples, fieldMap['Sampling Event Data'], 'parentEvent'), 207 'Sample Data' : getFieldValues(samples, fieldMap['Sample Data']), 208 'Event Group' : eventFieldMap, 209 'Module Measurement Data' : moduleMeasurementData, 210 'Module Error' : moduleError 211 ] 209 212 } 210 213 … … 225 228 def value = assay.parent.getFieldValue( it.name ) 226 229 if( value ) 227 studyData[ it.name ] = [value] 230 studyData[ it.name ] = [value]* numValues 228 231 } 229 232 … … 249 252 def value = assay.getFieldValue( it.name ) 250 253 if( value ) 251 assayData[ it.name ] = [value] 254 assayData[ it.name ] = [value]* numValues 252 255 } 253 256 … … 304 307 def tokenString = '' 305 308 306 inputMeasurementTokens.each{ 307 tokenString+="&measurementToken=${it.encodeAsURL()}" 308 } 309 309 inputMeasurementTokens.each{ tokenString+="&measurementToken=${it.encodeAsURL()}" } 310 311 /* Contact module to fetch measurement data */ 310 312 def path = moduleUrl + "/rest/getMeasurementData/query" 311 312 313 def query = "assayToken=$assay.assayUUID$tokenString" 313 314 314 315 if (samples) { 315 316 query += '&' + samples*.sampleUUID.collect { "sampleToken=$it" }.join('&') 316 317 } 317 318 … … 373 374 374 375 return map; 376 } 377 378 /** 379 * Retrieves module measurement meta data through a rest call to the module 380 * 381 * @param assay Assay for which the module measurements should be retrieved 382 * @param measurementTokens List with the names of the fields to be retrieved. Format: [ 'measurementName1', 'measurementName2' ] 383 * @return 384 */ 385 def requestModuleMeasurementMetaDatas(assay, inputMeasurementTokens, SecUser remoteUser = null) { 386 387 def measurementTokenMetaData = [:] 388 389 def moduleUrl = assay.module.url 390 391 def tokenString = '' 392 inputMeasurementTokens.each{ tokenString+="&measurementToken=${it.encodeAsURL()}" } 393 394 def pathMeasurementMetaData = moduleUrl + "/rest/getMeasurementMetaData/" 395 def queryMeasurementMetaData = "assayToken=$assay.assayUUID$tokenString" 396 397 try { 398 moduleCommunicationService.callModuleMethod(moduleUrl, pathMeasurementMetaData, queryMeasurementMetaData, "POST", remoteUser).each { metaDataArray -> 399 if (metaDataArray['name']){ 400 measurementTokenMetaData[metaDataArray['name']] = metaDataArray //convert list to an associative array 401 } 402 } 403 } catch (e) { 404 e.printStackTrace() 405 throw new Exception("An error occured while trying to get the measurement meta data from the $assay.module.name. \ 406 This means the module containing the measurement data is not available right now. Please try again \ 407 later or notify the system administrator if the problem persists. URL: $path?$query.") 408 } 409 410 return measurementTokenMetaData 411 } 412 413 /** 414 * Injects meta-data(s) into rowData before creating a CSV or tab 415 */ 416 def mergeModuleDataWithMetadata(data, metadata = null){ 417 418 if (metadata == null){ 419 return data 420 } 421 422 //check if there is meta-data available for the features in the data 423 if (!(data[1].intersect(metadata.keySet()))){ 424 return data 425 } 426 427 //find out where the measurements start in the data 428 def addLabelsAtColumnPosition = null 429 data[0].eachWithIndex { cat, i -> 430 if (cat == 'Module Measurement Data'){ 431 addLabelsAtColumnPosition = i 432 } 433 } 434 435 //check if we have a position to inject the labels 436 if (addLabelsAtColumnPosition == null){ 437 return data //returning data as we were unable to find any measurements. Or at least where the start. 438 } 439 440 //find out all (unique) feature properties 441 def featureProperties = [] 442 metadata.values().each { featureProperties += it.keySet() } 443 featureProperties = featureProperties.unique() 444 445 //prepare the additional rows with meta-data 446 def additionalRows = [] 447 featureProperties.each { mdfp -> 448 def addRow = [] 449 (1..addLabelsAtColumnPosition).each { 450 //add some empty fields before the labels of the meta-data properties 451 addRow.add(null) 452 } 453 addRow.add(mdfp) 454 data[1].eachWithIndex { feature, i -> 455 if (i >= addLabelsAtColumnPosition) { addRow.add(metadata[feature][mdfp]) } 456 } 457 additionalRows.add(addRow) 458 } 459 460 //add the additional row and add a null to the feature label column in the data rows 461 if (additionalRows){ 462 def tempData = [] 463 data.eachWithIndex { row, iRow -> 464 465 //this is an existing row (not meta-data), so we add a null under the feature label column 466 def tempR = [] 467 row.eachWithIndex { rowElement, iRowElement -> 468 if ((iRow != 0) && (iRowElement == addLabelsAtColumnPosition)){ 469 tempR.add(null) //add an empty element under the meta-data label 470 } 471 tempR.add(rowElement) 472 } 473 tempData.add(tempR) 474 475 //as the additional rows have already been formatted in the correct way we only have to add them under the row that holds the categories 476 if (iRow == 1){ 477 additionalRows.each { additionalRow -> 478 tempData.add(additionalRow) 479 } 480 } 481 } 482 //overwrite data with the tempRowData 483 data = tempData 484 } 485 486 return data 375 487 } 376 488 … … 457 569 } else { 458 570 // Append empty string for each entity if the field doesn't exist 459 categoryValues[ field ] += [""] 571 categoryValues[ field ] += [""]* numValues[ idx ] 460 572 } 461 573 } … … 519 631 // A map with keys being the sampleIds, and the values are the indices of that sample in the values list 520 632 def idMap = [:] 521 633 522 634 // A map with the key being an index in the value list, and the value is the index the values should be copied to 523 635 def convertMap = [:] … … 534 646 } 535 647 } 536 648 537 649 /* 538 650 * Example output: … … 544 656 * loop through the values and remove the row that has been merged. 545 657 */ 546 547 convertMap.sort { a, b -> b.key <=> a.key }.each { 658 659 convertMap.sort { a, b -> b.key <=> a.key }.each { 548 660 def row = it.key; 549 661 def mergeWith = it.value; 550 662 551 663 if( row != mergeWith ) { 552 664 // Combine the data on row [row] with the data on row [mergeWith] 553 554 mergedData.each { 665 666 mergedData.each { 555 667 def cat = it.key; def fields = it.value; 556 668 fields.each { fieldData -> 557 def fieldName = fieldData.key; 669 def fieldName = fieldData.key; 558 670 def fieldValues = fieldData.value; 559 671 560 672 // If one of the fields to merge is empty, use the other one 561 673 // Otherwise the values should be the same (e.g. study, subject, sample data) 562 674 fieldValues[ mergeWith ] = ( fieldValues[ mergeWith ] == null || fieldValues[ mergeWith ] == "" ) ? fieldValues[ row ] : fieldValues[ mergeWith ] 563 675 564 676 // Remove the row from this list 565 677 fieldValues.remove( row ); … … 568 680 } 569 681 } 570 682 571 683 // Remove sample id if required 572 684 if( removeIdColumn ) 573 685 mergedData[ "Sample Data" ].remove( "id" ); 574 686 575 687 return mergedData 576 688 } … … 605 717 if (columnData.every { it.value.every { it.value instanceof ArrayList } }) { 606 718 607 def headers = [[], []]719 def headers = [[], []] 608 720 609 721 columnData.each { category -> … … 613 725 // put category keys into first row separated by null values 614 726 // wherever there are > 1 columns per category 615 headers[0] += [category.key] + [null]* (category.value.size() - 1)727 headers[0] += [category.key]+ [null]* (category.value.size() - 1) 616 728 617 729 // put non-category column headers into 2nd row … … 691 803 692 804 outputStream << rowData.collect { row -> 805 693 806 row.collect{ 694 807 … … 761 874 def value = rowData[ri][ci] 762 875 763 value = (value instanceof Number | value?.class in [boolean.class, String.class, Date.class]) ? value : value?.toString() 876 value = (value instanceof Number | value?.class in [ 877 boolean.class, 878 String.class, 879 Date.class 880 ]) ? value : value?.toString() 764 881 765 882 // write the value (or an empty String if null) to the cell
Note: See TracChangeset
for help on using the changeset viewer.