Changeset 1790 for trunk/grails-app/services
- Timestamp:
- Apr 21, 2011, 3:49:23 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/services/dbnp/studycapturing/AssayService.groovy
r1752 r1790 16 16 import org.apache.poi.xssf.usermodel.XSSFWorkbook 17 17 import org.apache.poi.hssf.usermodel.HSSFWorkbook 18 import org.codehaus.groovy.grails.web.json.JSONObject; 18 import org.codehaus.groovy.grails.web.json.JSONObject 19 import org.dbnp.gdt.RelTime 20 import org.dbnp.gdt.TemplateFieldType; 19 21 20 22 class AssayService { … … 39 41 templateEntities*.giveFields().flatten().unique().findAll{ field -> 40 42 41 field && templateEntities.any { it && it.fieldExists(field.name) && it.getFieldValue(field.name) } 42 43 }.collect{[name: it.name, comment: it.comment]} 44 43 field && templateEntities.any { it?.fieldExists(field.name) && it.getFieldValue(field.name) != null } 44 45 }.collect{[name: it.name, comment: it.comment, displayName: it.name + (it.unit ? " ($it.unit)" : '')]} 45 46 } 46 47 … … 49 50 'Sampling Event Data' : getUsedTemplateFields( samples*."parentEvent".unique() ), 50 51 'Sample Data' : getUsedTemplateFields( samples ), 51 'Event Group' : [[name: 'name', comment: 'Name of Event Group' ]],52 52 'Event Group' : [[name: 'name', comment: 'Name of Event Group', displayName: 'name']], 53 53 54 // If module is not reachable, only the field 'module error' is returned, and is filled later on. 54 55 'Module Measurement Data': moduleCommunicationService.isModuleReachable(assay.module.url) ? requestModuleMeasurementNames(assay) : [ [ name: "Module error" ] ] … … 72 73 def collectAssayData(assay, fieldMap, measurementTokens) throws Exception { 73 74 74 def collectFieldValuesForTemplateEntities = { templateFieldNames, templateEntities ->75 def collectFieldValuesForTemplateEntities = { headerFields, templateEntities -> 75 76 76 77 // return a hash map with for each field name all values from the 77 78 // template entity list 78 templateFieldNames.inject([:]) { map, fieldName -> 79 80 map + [(fieldName): templateEntities.collect { 81 82 it?.fieldExists(fieldName) ? it.getFieldValue(fieldName) : '' 83 84 }] 85 86 } 87 88 } 89 90 def getFieldValues = { templateEntities, fieldNames, propertyName = '' -> 79 headerFields.inject([:]) { map, headerField -> 80 81 map + [(headerField.displayName): templateEntities.collect { 82 83 // default to an empty string 84 def val = '' 85 86 def field 87 try { 88 89 val = it.getFieldValue(headerField.name) 90 91 // Convert RelTime fields to human readable strings 92 field = it.getField(headerField.name) 93 if (field.type == TemplateFieldType.RELTIME) 94 val = new RelTime( val as long ) 95 96 } catch (NoSuchFieldException e) { /* pass */ } 97 98 val.toString()}] 99 } 100 } 101 102 def getFieldValues = { templateEntities, headerFields, propertyName = '' -> 91 103 92 104 def returnValue … … 96 108 if (propertyName == '') { 97 109 98 returnValue = collectFieldValuesForTemplateEntities( fieldNames, templateEntities)110 returnValue = collectFieldValuesForTemplateEntities(headerFields, templateEntities) 99 111 100 112 } else { … … 114 126 def uniqueProperties = templateEntities*."$propertyName".unique() 115 127 116 fieldValues = collectFieldValuesForTemplateEntities( fieldNames, uniqueProperties)128 fieldValues = collectFieldValuesForTemplateEntities(headerFields, uniqueProperties) 117 129 118 130 // prepare a lookup hashMap to be able to map an entities' … … 124 136 // prepare the return value so that it has an entry for field 125 137 // name. This will be the column name (second header line). 126 returnValue = fieldNames.inject([:]) { map, item -> map + [(item):[]] }138 returnValue = headerFields*.displayName.inject([:]) { map, item -> map + [(item):[]] } 127 139 128 140 // finally, fill map the unique field values to the (possibly … … 132 144 templateEntities.each{ te -> 133 145 134 fieldNames.each{146 headerFields*.displayName.each{ 135 147 136 148 returnValue[it] << fieldValues[it][propertyToFieldValueIndexMap[te[propertyName]]] … … 159 171 if (!names.every {!it}) eventFieldMap['name'] = names 160 172 161 } 162 163 [ 'Subject Data' : getFieldValues(samples, fieldMap['Subject Data']*.name, 'parentSubject'),164 'Sampling Event Data' : getFieldValues(samples, fieldMap['Sampling Event Data']*.name, 'parentEvent'),165 'Sample Data' : getFieldValues(samples, fieldMap['Sample Data']*.name),166 167 168 169 170 171 173 } 174 175 [ 'Subject Data' : getFieldValues(samples, fieldMap['Subject Data'], 'parentSubject'), 176 'Sampling Event Data' : getFieldValues(samples, fieldMap['Sampling Event Data'], 'parentEvent'), 177 'Sample Data' : getFieldValues(samples, fieldMap['Sample Data']), 178 'Event Group' : eventFieldMap, 179 180 // If module is not reachable, only the message 'module not reachable' is given for each sample 181 'Module Measurement Data': moduleCommunicationService.isModuleReachable(assay.module.url) ? 182 ( measurementTokens ? requestModuleMeasurements(assay, measurementTokens, samples) : [:] ) : 183 [ "Module error": [ "Module not reachable" ] * samples.size() ] 172 184 ] 173 185 } 174 186 175 187 /** 176 188 * Prepend data from study to the data structure … … 183 195 if( !assay ) 184 196 return inputData; 185 197 186 198 // Retrieve study data 187 199 def studyData =[:] 188 assay.parent?.giveFields().each { 200 assay.parent?.giveFields().each { 189 201 def value = assay.parent.getFieldValue( it.name ) 190 if( value ) 191 studyData[ it.name ] = [value] * numValues 202 if( value ) 203 studyData[ it.name ] = [value] * numValues 192 204 } 193 205 … … 207 219 if( !assay ) 208 220 return inputData; 209 221 210 222 // Retrieve assay data 211 223 def assayData = [:] 212 224 assay.giveFields().each { 213 225 def value = assay.getFieldValue( it.name ) 214 if( value ) 215 assayData[ it.name ] = [value] * numValues 226 if( value ) 227 assayData[ it.name ] = [value] * numValues 216 228 } 217 229 … … 250 262 * @param assay Assay for which the module measurements should be retrieved 251 263 * @param measurementTokens List with the names of the fields to be retrieved. Format: [ 'measurementName1', 'measurementName2' ] 252 * @param samples Samples for which the module 264 * @param samples Samples for which the module 253 265 * @return 254 266 */ … … 309 321 /** 310 322 * Merges the data from multiple studies into a structure that can be exported to an excel file. The format for each assay is 311 * 323 * 312 324 * [Category1: 313 325 * [Column1: [1,2,3], Column2: [4,5,6]], 314 326 * Category2: 315 327 * [Column3: [7,8,9], Column4: [10,11,12], Column5: [13,14,15]]] 316 * 328 * 317 329 * Where the category describes the category of data that is presented (e.g. subject, sample etc.) and the column names describe 318 330 * the fields that are present. Each entry in the lists shows the value for that column for an entity. In this case, 3 entities are described. 319 * Each field should give values for all entities, so the length of all value-lists should be the same. 331 * Each field should give values for all entities, so the length of all value-lists should be the same. 320 332 * 321 333 * Example: If the following input is given (2 assays) 322 * 334 * 323 335 * [ 324 336 * [Category1: … … 331 343 * [Column3: [20,21], Column8: [22,23]]] 332 344 * ] 333 * 345 * 334 346 * the output will be (5 entries for each column, empty values for fields that don't exist in some assays) 335 * 347 * 336 348 * [ 337 349 * [Category1: … … 342 354 * [Column3: [,,,20,21], Column8: [,,,22,23]] 343 355 * ] 344 * 345 * 356 * 357 * 346 358 * @param columnWiseAssayData List with each entry being the column wise data of an assay. The format for each 347 359 * entry is described above … … 363 375 } 364 376 } 365 377 366 378 return 0; 367 379 } 368 380 369 381 // Merge categories from all assays. Create a list for all categories 370 382 def categories = columnWiseAssayData*.keySet().toList().flatten().unique(); … … 373 385 // Only work with this category for all assays 374 386 def categoryData = columnWiseAssayData*.getAt( category ); 375 387 376 388 // Find the different fields in all assays 377 389 def categoryFields = categoryData.findAll{ it }*.keySet().toList().flatten().unique(); … … 396 408 mergedColumnWiseData[ category ] = categoryValues 397 409 } 398 410 399 411 return mergedColumnWiseData; 400 412 } 401 413 402 414 /** 403 415 * Converts column … … 501 513 502 514 /** 515 * Export row wise data in CSV to a stream. All values are surrounded with 516 * double quotes (" "). 517 * 518 * @param rowData List of lists containing for each row all cell values 519 * @param outputStream Stream to write to 520 * @return 521 */ 522 def exportRowWiseDataToCSVFile(rowData, outputStream) { 523 524 outputStream << rowData.collect { row -> 525 row.collect{ it ? "\"$it\"" : '""' }.join(',') 526 }.join('\n') 527 528 outputStream.close() 529 } 530 531 /** 503 532 * Export row wise data for multiple assays in Excel format (separate sheets) to a stream 504 533 * … … 525 554 * 526 555 * @param rowData List of lists containing for each row all cell values 527 * @param sheet Excel sheet to append the 556 * @param sheet Excel sheet to append the 528 557 * @return 529 558 */ … … 536 565 // create appropriate number of cells for this row 537 566 rowData[ri].size().times { row.createCell it } 538 567 539 568 row.eachWithIndex { Cell cell, ci -> 540 569 541 570 // Numbers and values of type boolean, String, and Date can be 542 571 // written as is, other types need converting to String 543 572 def value = rowData[ri][ci] 544 573 545 574 value = (value instanceof Number | value?.class in [boolean.class, String.class, Date.class]) ? value : value?.toString() 546 575 547 576 // write the value (or an empty String if null) to the cell 548 577 cell.setCellValue(value ?: '') 549 578 550 579 } 551 580 }
Note: See TracChangeset
for help on using the changeset viewer.