Changeset 6474
- Timestamp:
- Nov 4, 2021, 3:30:00 PM (15 months ago)
- Location:
- extensions/net.sf.basedb.reggie/trunk
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/net.sf.basedb.reggie/trunk
- Property svn:mergeinfo changed
/extensions/net.sf.basedb.reggie/branches/4.31-stable merged: 6256
- Property svn:mergeinfo changed
-
extensions/net.sf.basedb.reggie/trunk/resources/batch/import-external-specimen.js
r6353 r6474 55 55 html += '<th class="dottedleft">JSON file</th>' 56 56 html += '<th>Date</th>'; 57 html += '<th>Reads</th>'; 57 58 html += '<th>FASTQ files</th>'; 58 59 html += '<th class="icon"></th>' … … 89 90 html += '<td style="white-space: nowrap;">'; 90 91 if (jsonFile && jsonFile.lastModified) html += Reggie.reformatDate(jsonFile.lastModified); 92 html += '</td>'; 93 html += '<td>'; 94 if (jsonFile && jsonFile.PF_READS) html += Reggie.formatCount(jsonFile.PF_READS); 91 95 html += '</td>'; 92 96 html += '<td class="fastq" style="white-space: nowrap;">'; -
extensions/net.sf.basedb.reggie/trunk/resources/personal/map-external-data.js
r5740 r6474 56 56 var lineNo = 0; 57 57 var mapFrom = null; 58 var separator = null; 58 59 var preview = ''; 59 60 while (lineNo < lines.length && lineNo < 5) 60 61 { 61 62 var line = lines[lineNo]; 62 if (lineNo < 3)63 if (lineNo < 4) 63 64 { 64 65 preview += Strings.encodeTags(line) + '\n'; 65 66 } 67 if (separator == null) separator = map.detectSeparator(line); 66 68 if (mapFrom == null) 67 69 { 68 if (line.match(/^[QCS]\d+ \t.*$/))// We look for lines starting with 'Q', 'C' or 'S' followed by {digits} and a {tab}70 if (line.match(/^[QCS]\d+([\t,;].*)?$/))// We look for lines starting with 'Q', 'C' or 'S' followed by {digits} and a {tab/comma/semicolon} 69 71 { 70 72 var firstChar = line.charAt(0); … … 82 84 } 83 85 } 84 else if (lineNo == 0 && line.match(/^[^\t ]*pad/i)) // If the first header column contains 'pad' (ignoring case) we assume it contains PAD values86 else if (lineNo == 0 && line.match(/^[^\t,;]*pad/i)) // If the first header column contains 'pad' (ignoring case) we assume it contains PAD values 85 87 { 86 88 mapFrom = 'PAD'; … … 89 91 lineNo++; 90 92 } 91 if (lines.length > 3) preview += '<div id="more-lines">+' + (lines.length-3) + ' more lines...</div>'; 93 if (lines.length > 4) preview += '<div id="more-lines">+' + (lines.length-4) + ' more lines...</div>'; 94 frm.separator.value = separator ? separator.id : 'tab'; 92 95 frm.mapFrom.value = mapFrom || 'PersonalNo'; 93 96 Events.sendChangeEvent(frm.mapFrom); … … 95 98 } 96 99 100 /** 101 Detect the "best" separator to use by selecting the one 102 that appear the most times in the given text line. If no 103 separator is found null is returned. 104 */ 105 map.detectSeparator = function(text) 106 { 107 var separators = 108 [ 109 { 'id': 'tab', 'test': /\t/g, 'sep': '\t'}, 110 { 'id': 'comma', 'test': /,/g, 'sep': ','}, 111 { 'id': 'semicolon', 'test': /;/g, 'sep': ';'} 112 ]; 113 var maxCount = 0; 114 var bestMatch = 0; 115 for (var i=0; i < separators.length; i++) 116 { 117 var sep = separators[i]; 118 var m = text.match(sep.test); 119 if (m && m.length > maxCount) 120 { 121 maxCount = m.length; 122 bestMatch = i; 123 } 124 } 125 return maxCount == 0 ? null : separators[bestMatch]; 126 } 97 127 98 128 map.validateStep1 = function(event) … … 113 143 var url = '../Export.servlet?ID='+App.getSessionId(); 114 144 url += '&cmd=MapDataToReleases'; 145 url += '&separator='+frm.separator.value; 115 146 url += '&mapFrom='+Strings.encodeTags(frm.mapFrom.value); 116 147 url += '&exportCaseId='+(frm.exportCaseId.checked ? 1 : 0); -
extensions/net.sf.basedb.reggie/trunk/resources/personal/map-external-data.jsp
r5740 r6474 81 81 <td class="help" rowspan="2"><span id="file.message" class="message"></span> 82 82 <ul> 83 <li>Select a tab- separated text file in UTF-8 encoding.83 <li>Select a tab-, comma-, or semicolon-separated text file in UTF-8 encoding. 84 84 <li>The first line should contain column headers. 85 85 <li>The first column should contain the personal number, or a release id value as specified by the <b>Map from</b> option. … … 93 93 <td> 94 94 <div id="preview"><i>No file loaded...</i></div> 95 </td> 96 <td></td> 97 </tr> 98 <tr> 99 <td class="prompt">Separator</td> 100 <td> 101 <select name="separator" id="separator"> 102 <option value="tab">Tab 103 <option value="comma">Comma 104 <option value="semicolon">Semi-colon 105 </select> 95 106 </td> 96 107 <td></td> -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/BioplateType.java
r6049 r6474 109 109 /** 110 110 The definition of the "External library plate" type. It is locked to extracts 111 of subtype {@link Subtype#LIBRARY} and uses 8x12 geometry. TODO -- different geometry??111 of subtype {@link Subtype#LIBRARY} and uses 8x12 geometry. 112 112 @since 2.12 113 113 */ 114 114 public static final BioplateType EXTERNAL_LIBRARY = 115 115 new BioplateType("External library plate", Item.EXTRACT, Subtype.LIBRARY, LockMode.LOCKED_AFTER_ADD, Geometry.EIGHT_BY_TWELVE, "ExternalLibPlate", 4); 116 116 117 /** 118 The definition of the "External library strip" type. It is locked to extracts 119 of subtype {@link Subtype#LIBRARY} and uses 1x8 geometry. 120 @since 4.33.4 121 */ 122 public static final BioplateType EXTERNAL_LIBRARY_STRIP = 123 new BioplateType("External library strip", Item.EXTRACT, Subtype.LIBRARY, LockMode.LOCKED_AFTER_ADD, Geometry.ONE_BY_EIGHT, "ExternalLibStrip", 5); 124 125 117 126 /** 118 127 The definition of the "MIPs plate" type. It is locked to extracts -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Geometry.java
r3571 r6474 48 48 public static final Geometry ONE_BY_TWELVE = new Geometry("12-well (1 × 12)", 1, 12); 49 49 50 /** 51 Plate geometry with 1 row and 8 columns. 52 @since 4.33.4 53 */ 54 public static final Geometry ONE_BY_EIGHT = new Geometry("8-well (1 × 8)", 1, 8); 55 50 56 /** 51 57 Plate geometry with 8 rows and 2 columns. -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/grid/ImportFastqJobCreator.java
r6421 r6474 187 187 demuxName + " must have two values: " + rawFastqNames); 188 188 } 189 String fastqNameR1 = null; 190 String fastqNameR2 = null; 191 // NOTE! Order in the list is not specified so we don't know which is R1 and R2 192 // Search for _R1 and _R2 193 for (String fqName : rawFastqNames) 194 { 195 if (fqName.contains("_R1")) fastqNameR1 = fqName; 196 if (fqName.contains("_R2")) fastqNameR2 = fqName; 197 } 198 if (fastqNameR1 == null) 199 { 200 throw new InvalidDataException("Annotation RawFASTQ on " + 201 demuxName + " is missing an R1 fastq file: " + rawFastqNames); 202 } 203 if (fastqNameR2 == null) 204 { 205 throw new InvalidDataException("Annotation RawFASTQ on " + 206 demuxName + " is missing an R2 fastq file: " + rawFastqNames); 207 } 189 208 190 209 // Get SequencingRun so that we can get the path to the FASTQ folder. … … 272 291 // If not, we need to copy from ImportGateway 273 292 // If they don't exists at all we generate an error 274 int fileNo = 0;275 293 script.cmd("mkdir -p ${ImportArchive}"); 276 for (String fastqName : rawFastqNames) 277 { 278 fileNo++; 279 // NOTE! Order in the list is not specified so we don't know which is R1 and R2 280 script.cmd("FASTQ="+ScriptUtil.checkValidFilename(fastqName)); 281 script.progress(5+fileNo*5, "Copying FASTQ files: ${FASTQ}"); 282 script.cmd("if [ ! -f \"${ImportArchive}/${FASTQ}\" ]; then"); 283 script.cmd(" if [ ! -f \"${ImportGateway}/${FASTQ}\" ]; then"); 284 script.cmd(" echo \"Can't find FASTQ file ${FASTQ} in ${ImportGateway} or ${ImportArchive}\" 1>&2"); 294 script.cmd("FASTQ1="+ScriptUtil.checkValidFilename(fastqNameR1)); 295 script.cmd("FASTQ2="+ScriptUtil.checkValidFilename(fastqNameR2)); 296 for (int fileNo = 1; fileNo <= 2; fileNo++) 297 { 298 script.progress(5+fileNo*5, "Copying FASTQ files: ${FASTQ"+fileNo+"}"); 299 script.cmd("if [ ! -f \"${ImportArchive}/${FASTQ"+fileNo+"}\" ]; then"); 300 script.cmd(" if [ ! -f \"${ImportGateway}/${FASTQ"+fileNo+"}\" ]; then"); 301 script.cmd(" echo \"Can't find FASTQ file ${FASTQ"+fileNo+"} in ${ImportGateway} or ${ImportArchive}\" 1>&2"); 285 302 script.cmd(" exit 1"); 286 303 script.cmd(" fi"); 287 script.cmd(" cp \"${ImportGateway}/${FASTQ }\" \"${ImportArchive}/${FASTQ}\"");304 script.cmd(" cp \"${ImportGateway}/${FASTQ"+fileNo+"}\" \"${ImportArchive}/${FASTQ"+fileNo+"}\""); 288 305 if (!debug) 289 306 { 290 script.cmd(" rm -f \"${ImportGateway}/${FASTQ }\"");307 script.cmd(" rm -f \"${ImportGateway}/${FASTQ"+fileNo+"}\""); 291 308 } 292 309 script.cmd("fi"); 293 script.cmd("cp \"${ImportArchive}/${FASTQ }\" fastq");310 script.cmd("cp \"${ImportArchive}/${FASTQ"+fileNo+"}\" fastq"); 294 311 script.newLine(); 295 312 } 296 297 script.comment("Find FASTQ files");298 script.cmd("FASTQ1=`find fastq -name \"*_R1*.fastq.gz\" -print -quit 2> /dev/null`");299 script.cmd("FASTQ2=`find fastq -name \"*_R2*.fastq.gz\" -print -quit 2> /dev/null`");300 script.newLine();301 313 302 314 script.comment("Run Bowtie2"); 303 script.progress( 40, "Bowtie2: " + mergedName + " (${NumThreads} threads)");315 script.progress(20, "Bowtie2: " + mergedName + " (${NumThreads} threads)"); 304 316 String alignCmd = "./stdwrap.sh " + bowtie_path; 305 317 alignCmd += " -p ${NumThreads}"; … … 307 319 alignCmd += " --un-conc fastq.aligned/R%.fastq"; 308 320 alignCmd += " -x ${Gidx}"; 309 alignCmd += " -1 ${FASTQ1}";310 alignCmd += " -2 ${FASTQ2}";321 alignCmd += " -1 fastq/${FASTQ1}"; 322 alignCmd += " -2 fastq/${FASTQ2}"; 311 323 alignCmd += " -S fastq.aligned/aligned.sam"; 312 324 alignCmd += " > fastq.aligned/aligned.out"; … … 319 331 String trimCmd1 = "./stdwrap.sh ./trimmomatic PE"; 320 332 trimCmd1 += " -threads ${NumThreads}"; 321 trimCmd1 += " ${FASTQ1}";322 trimCmd1 += " ${FASTQ2}";333 trimCmd1 += " fastq/${FASTQ1}"; 334 trimCmd1 += " fastq/${FASTQ2}"; 323 335 trimCmd1 += " fastq.trimmomatic.1/"+R1_name; 324 336 trimCmd1 += " fastq.trimmomatic.1/un_"+R1_name; … … 443 455 if (m.matches()) 444 456 { 445 metrics.passedFilter = Values.getLong(m.group(1), -1); 457 metrics.reads = Values.getLong(m.group(1), -1); 458 metrics.passedFilter = metrics.reads; 446 459 } 447 460 } … … 494 507 int bowtie_fragment_count_limit = Values.getInt(cfg.getConfig("demux/bowtie-fragment-count-limit", mergeParameterSet, "20000")); 495 508 496 // We may have READS from the JSON import, but if not we should do the best and use the PF_READS value 497 Long reads = (Long)Annotationtype.READS.getAnnotationValue(dc, merged); 498 if (reads == null) 499 { 500 metrics.reads = metrics.passedFilter; 501 Annotationtype.READS.setAnnotationValue(dc, merged, metrics.reads); 502 } 503 else 504 { 505 metrics.reads = reads; 506 } 509 Annotationtype.READS.setAnnotationValue(dc, merged, metrics.reads); 507 510 Annotationtype.PF_READS.setAnnotationValue(dc, merged, metrics.passedFilter); 508 511 Annotationtype.ADAPTER_READS.setAnnotationValue(dc, merged, metrics.passedFilter - metrics.passedTrimmomatic[0]); -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/FutureSpecimenImporter.java
r6353 r6474 415 415 else 416 416 { 417 BioplateType plateType = BioplateType.EXTERNAL_LIBRARY; 417 BioplateType plateType = info.libPlateType; 418 if (plateType == null) plateType = BioplateType.EXTERNAL_LIBRARY; // Should not happen if LibraryInfo.valid==TRUE 418 419 plate = BioPlate.getNew(dc, plateType.getPlateGeometry(dc), plateType.get(dc)); 419 420 plate.setName(plateType.getNextPlateName(dc, true)); -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/DemuxInfo.java
r6240 r6474 39 39 software = demuxSection.getRequiredEntry("Software", SoftwareValidator.INSTANCE); 40 40 readString = demuxSection.getRequiredEntry("ReadString", PatternValidator.READ_STRING); 41 pfReads = mergeSection.getRequiredEntry("PF_READS", LongValidator.POSITIVE.warnIf( 10000000l, null)); // Warn if less than 10M reads41 pfReads = mergeSection.getRequiredEntry("PF_READS", LongValidator.POSITIVE.warnIf(20000000l, 50000000l)); // Warn if less than 20M or more than 50M reads 42 42 reads = pfReads; // 43 43 valid = !demuxSection.hasError() && !mergeSection.hasError(); -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/FastqInfo.java
r6457 r6474 3 3 import java.io.InputStream; 4 4 import java.util.Date; 5 import java.util.Locale; 5 6 6 7 import org.json.simple.JSONObject; … … 37 38 { 38 39 //R1.md5 = fastq.getOptionalEntry("R1 MD5", PatternValidator.MD5); 39 R1.expectedSize = fastq.getOptionalEntry("R1 1size", LongValidator.POSITIVE_OR_NULL);40 R1.expectedSize = fastq.getOptionalEntry("R1size", LongValidator.POSITIVE_OR_NULL); 40 41 } 41 42 if (R2 != null) … … 70 71 else if (f.expectedSize != null && f.actualSize != f.expectedSize) 71 72 { 72 section.addErrorMessage("FASTQ file size: "+f.name+"="+ f.actualSize+" (expected "+f.expectedSize+" bytes)");73 section.addErrorMessage("FASTQ file size: "+f.name+"="+String.format(Locale.US, "%,d", f.actualSize)+" bytes (expected "+String.format(Locale.US, "%,d", f.expectedSize)+" bytes)"); 73 74 } 74 75 } -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/IntValidator.java
r6217 r6474 104 104 catch (Exception ex) 105 105 { 106 section.addErrorMessage("Invalid integer in JSON: "+entryKey+"="+value);106 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+value); 107 107 } 108 108 } … … 111 111 if (minValue != null && result < minValue) 112 112 { 113 section.addErrorMessage("Invalid integer in JSON: "+entryKey+"="+value+" (expected >="+minValue+")");113 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+value+" (expected >="+minValue+")"); 114 114 result = null; 115 115 } 116 116 if (maxValue != null && result > maxValue) 117 117 { 118 section.addErrorMessage("Invalid integer in JSON: "+entryKey+"="+value+" (expected <="+maxValue+")");118 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+value+" (expected <="+maxValue+")"); 119 119 result = null; 120 120 } … … 123 123 if (allowed.indexOf(result) == -1) 124 124 { 125 section.addErrorMessage("Invalid integer in JSON: "+entryKey+"="+value+" (expected one of "+allowed+")");125 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+value+" (expected one of "+allowed+")"); 126 126 result = null; 127 127 } … … 132 132 if (softMin != null && result < softMin) 133 133 { 134 section.addWarningMessage(" Unexpected integer in JSON: "+entryKey+"="+value+" (expected >="+softMin+")");134 section.addWarningMessage("Low value for "+entryKey+" in JSON: "+value+" (expected >="+softMin+")"); 135 135 } 136 136 if (softMax != null && result > softMax) 137 137 { 138 section.addWarningMessage(" Unexpected integer in JSON: "+entryKey+"="+value+" (expected <="+softMax+")");138 section.addWarningMessage("High value for "+entryKey+" in JSON: "+value+" (expected <="+softMax+")"); 139 139 } 140 140 } -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/JsonFile.java
r6353 r6474 197 197 } 198 198 199 if (demuxInfo != null) 200 { 201 j.put("PF_READS", demuxInfo.pfReads); 202 } 203 199 204 if (hasError()) 200 205 { -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/LibraryInfo.java
r6346 r6474 47 47 public Protocol protocol; 48 48 public BioPlate libPlate; 49 public BioplateType libPlateType = BioplateType.EXTERNAL_LIBRARY; 49 50 50 51 public boolean valid; … … 55 56 { 56 57 plateId = section.getRequiredEntry("Plate name", PatternValidator.CMD_ID); 57 well = section.getRequiredEntry("Plate well", PlateWellValidator.PLATE_8x12); 58 ValidPlateCoordinateWithType plateWell = section.getRequiredEntry("Plate well", PlateOrStripValidator.INSTANCE); 59 if (plateWell != null) 60 { 61 well = plateWell.plateCoordinate; 62 libPlateType = plateWell.plateType; 63 } 58 64 59 65 if (plateId != null && well != null && ctx != null) … … 63 69 { 64 70 String coordinate = Coordinate.numericToAlpha(well.getRow()+1)+(well.getColumn()+1); 65 String msg = " LibPlate well ["+coordinate+"; ExternalRef="+plateId+"] duplicated in file: ";71 String msg = "Plate well ["+coordinate+"; ExternalRef="+plateId+"] duplicated in file: "; 66 72 section.addErrorMessage(msg+duplicate.getFile().getName()); 67 73 duplicate.addErrorMessage(msg+section.getFile().getName()); … … 69 75 } 70 76 71 if (plateId != null) libPlate = findExistingLibPlate(plateId, section);77 if (plateId != null) libPlate = findExistingLibPlate(plateId, libPlateType, section); 72 78 if (libPlate != null && well != null) 73 79 { … … 76 82 77 83 libDate = section.getRequiredEntry("Date", DateValidator.YYYY_MM_DD.warnIfFutureOrOlder(365)); 78 libSize = section.getRequiredEntry("Library size", IntValidator.POSITIVE.warnIf(150, 400));84 libSize = section.getRequiredEntry("Library size", IntValidator.POSITIVE.warnIf(150, 500)); 79 85 libMolarity = section.getRequiredEntry("Library molarity", FloatValidator.POSITIVE); 80 86 qubitConc = section.getRequiredEntry("Qubit concentration (ng/ul)", FloatValidator.POSITIVE); … … 82 88 83 89 barcode = section.getRequiredEntry("Barcode", BarcodeValidator.INSTANCE); 84 // TODO -- protocol85 90 protocol = section.getRequiredEntry("Protocol", ProtocolValidator.LIB_PROTOCOL); 86 91 } … … 88 93 } 89 94 90 private BioPlate findExistingLibPlate(String plateId, JsonSection section)95 private BioPlate findExistingLibPlate(String plateId, BioplateType plateType, JsonSection section) 91 96 { 92 97 BioPlate libPlate = null; … … 94 99 ItemQuery<BioPlate> query = BioPlate.getQuery(); 95 100 query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 96 BioplateType.EXTERNAL_LIBRARY.addFilter(dc, query, false); 101 if (plateType != null) 102 { 103 plateType.addFilter(dc, query, false); 104 } 97 105 query.join(Annotations.innerJoin(null, Annotationtype.EXTERNAL_REF.load(dc), "eref")); 98 106 query.restrict(Restrictions.eq(Hql.alias("eref"), Expressions.string(plateId))); … … 196 204 } 197 205 206 /** 207 Validator implementation that delegates to either STRIP_1x8 validator if 208 the coordinate is specified as 'digit:digit' or to PLATE_8x12 otherwise. 209 @since 4.33.4 210 */ 211 static class PlateOrStripValidator 212 implements ValueValidator<String, ValidPlateCoordinateWithType> 213 { 214 static final PlateOrStripValidator INSTANCE = new PlateOrStripValidator(); 215 216 @Override 217 public Class<String> getExpectedClass() 218 { 219 return String.class; 220 } 221 222 @Override 223 public ValidPlateCoordinateWithType isValid(DbControl dc, String value, JsonSection section, String entryKey) 224 { 225 ValidPlateCoordinateWithType result = new ValidPlateCoordinateWithType(); 226 PlateWellValidator validator; 227 if (value.matches("\\d\\:\\d")) 228 { 229 validator = PlateWellValidator.STRIP_1x8; 230 result.plateType = BioplateType.EXTERNAL_LIBRARY_STRIP; 231 } 232 else 233 { 234 validator = PlateWellValidator.PLATE_8x12; 235 result.plateType = BioplateType.EXTERNAL_LIBRARY; 236 } 237 result.plateCoordinate = validator.isValid(dc, value, section, entryKey); 238 return result; 239 } 240 } 241 242 /** 243 Holds the validated plate type and coordinate. 244 */ 245 static class ValidPlateCoordinateWithType 246 { 247 PlateCoordinate plateCoordinate; 248 BioplateType plateType; 249 } 198 250 } -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/LongValidator.java
r6457 r6474 2 2 3 3 import java.util.List; 4 import java.util.Locale; 4 5 5 6 import net.sf.basedb.core.DbControl; … … 119 120 catch (Exception ex) 120 121 { 121 section.addErrorMessage("Invalid long in JSON: "+entryKey+"="+value);122 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+value); 122 123 } 123 124 } … … 126 127 if (minValue != null && result < minValue) 127 128 { 128 section.addErrorMessage("Invalid long in JSON: "+entryKey+"="+value+" (expected >="+minValue+")");129 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+String.format(Locale.US, "%,d", value)+" (expected >="+String.format(Locale.US, "%,d", minValue)+")"); 129 130 result = null; 130 131 } 131 132 if (maxValue != null && result > maxValue) 132 133 { 133 section.addErrorMessage("Invalid long in JSON: "+entryKey+"="+value+" (expected <="+maxValue+")");134 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+String.format(Locale.US, "%,d", value)+" (expected <="+String.format(Locale.US, "%,d", maxValue)+")"); 134 135 result = null; 135 136 } … … 138 139 if (allowed.indexOf(result) == -1) 139 140 { 140 section.addErrorMessage("Invalid long in JSON: "+entryKey+"="+value+" (expected one of "+allowed+")");141 section.addErrorMessage("Invalid "+entryKey+" in JSON: "+value+" (expected one of "+allowed+")"); 141 142 result = null; 142 143 } … … 147 148 if (softMin != null && result < softMin) 148 149 { 149 section.addWarningMessage(" Unexpected long in JSON: "+entryKey+"="+value+" (expected >="+softMin+")");150 section.addWarningMessage("Low value for "+entryKey+" in JSON: "+String.format(Locale.US, "%,d", value)+" (expected >="+String.format(Locale.US, "%,d", softMin)+")"); 150 151 } 151 152 if (softMax != null && result > softMax) 152 153 { 153 section.addWarningMessage(" Unexpected long in JSON: "+entryKey+"="+value+" (expected <="+softMax+")");154 section.addWarningMessage("High value for "+entryKey+" in JSON: "+String.format(Locale.US, "%,d", value)+" (expected <="+String.format(Locale.US, "%,d", softMax)+")"); 154 155 } 155 156 } -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/PlateWellValidator.java
r6207 r6474 6 6 import net.sf.basedb.core.DbControl; 7 7 import net.sf.basedb.core.data.PlateCoordinate; 8 import net.sf.basedb.util.Coordinate; 8 9 9 10 /** 10 11 Validator for plate well coordinates that are expected to 11 12 be strings in the format "row:column", where 'row' and 'column' 12 are 1-based integer values up to a specified max number of13 rows/columns. If the coordinates are valid they are converted14 to 0-bases and returned as a PlateCoordinate instance.13 are either A1B1-style or 1-based integer values up to a specified 14 max number of rows/columns. If the coordinates are valid they are 15 converted to 0-bases and returned as a PlateCoordinate instance. 15 16 16 17 @since 4.32 … … 26 27 27 28 /** 29 Validator for strips with 1 row and 8 columns. 30 @since 4.33.4 31 */ 32 public static final PlateWellValidator STRIP_1x8 = new PlateWellValidator(1, 8); 33 34 /** 28 35 Validator fow Qiacube positions which are represented as 6 rows with 2 columns. 29 36 */ 30 37 public static final PlateWellValidator QIACUBE = new PlateWellValidator(6, 2); 31 38 32 private final Pattern pattern; 39 private final Pattern a1b1Pattern; 40 private final Pattern numericPattern; 33 41 private final int maxRows; 34 42 private final int maxCols; … … 36 44 public PlateWellValidator(int maxRows, int maxCols) 37 45 { 38 this.pattern = Pattern.compile("(\\d+)\\:(\\d+)"); 46 this.a1b1Pattern = Pattern.compile("([A-Z]+)\\:(\\d+)"); 47 this.numericPattern = Pattern.compile("(\\d+)\\:(\\d+)"); 39 48 this.maxRows = maxRows; 40 49 this.maxCols = maxCols; … … 44 53 public PlateCoordinate isValid(DbControl dc, String value, JsonSection section, String entryKey) 45 54 { 46 Matcher m = pattern.matcher(value); 47 if (!m.matches()) 55 Matcher mA1B1 = a1b1Pattern.matcher(value); 56 int row; 57 int col; 58 boolean useA1B1; 59 if (!mA1B1.matches()) 48 60 { 49 section.addErrorMessage("Invalid plate well in JSON: "+entryKey+"="+value); 50 return null; 61 Matcher mNumeric = numericPattern.matcher(value); 62 if (!mNumeric.matches()) 63 { 64 section.addErrorMessage("Invalid plate well in JSON: "+entryKey+"="+value); 65 return null; 66 } 67 row = Integer.parseInt(mNumeric.group(1)); 68 col = Integer.parseInt(mNumeric.group(2)); 69 useA1B1 = false; 51 70 } 52 int row = Integer.parseInt(m.group(1)); 53 int col = Integer.parseInt(m.group(2)); 71 else 72 { 73 row = Coordinate.alphaToNumeric(mA1B1.group(1)); 74 col = Integer.parseInt(mA1B1.group(2)); 75 useA1B1 = true; 76 } 77 54 78 boolean valid = true; 55 79 if (row < 1 || row > maxRows) 56 80 { 57 section.addErrorMessage("Row coordinate "+(row<1?"<1" : ">"+maxRows)+" in JSON: "+entryKey+"="+value); 81 if (useA1B1) 82 { 83 section.addErrorMessage("Row coordinate "+(row<1?"<A" : ">"+Coordinate.numericToAlpha(maxRows))+" in JSON: "+entryKey+"="+value); 84 } 85 else 86 { 87 section.addErrorMessage("Row coordinate "+(row<1?"<1" : ">"+maxRows)+" in JSON: "+entryKey+"="+value); 88 } 58 89 valid = false; 59 90 } -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/ExportServlet.java
r6336 r6474 538 538 ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PATIENT_CURATOR, ReggieRole.ADMINISTRATOR); 539 539 540 String separator = Values.getString(req.getParameter("separator"), "tab"); 540 541 String mapFrom = Values.getString(req.getParameter("mapFrom"), "PersonalNo"); 541 542 boolean exportCaseId = Values.getBoolean(req.getParameter("exportCaseId")); … … 544 545 boolean sortOutput = Values.getBoolean(req.getParameter("sortOutput")); 545 546 547 String separatorChar = "\t"; 548 if ("comma".equals(separator)) 549 { 550 separatorChar = ","; 551 } 552 else if ("semicolon".equals(separator)) 553 { 554 separatorChar = ";"; 555 } 556 546 557 SnapshotManager manager = new SnapshotManager(); 547 558 List<OutputColumn> outColumns = new ArrayList<>(); … … 605 616 String header = uploadReader.readLine(); 606 617 long parsedCharacters = header.length()+1; 607 String[] dataIn = header.split("\t", 2); 608 if (dataIn.length != 2) 609 { 610 throw new IOException("The file need at least 2 header columns"); 611 } 618 String[] dataIn = header.split(separatorChar, 2); 619 if (dataIn.length == 2) outColumns.add(new RestOfData(dataIn[1])); 612 620 613 621 int lastCol = outColumns.size(); 614 Object[] headerOut = new Object[lastCol +1];622 Object[] headerOut = new Object[lastCol]; 615 623 for (int colNo = 0; colNo < lastCol; colNo++) 616 624 { 617 625 headerOut[colNo] = outColumns.get(colNo).getHeader(); 618 626 } 619 headerOut[lastCol] = dataIn[1];620 627 621 628 int lineOut = 0; … … 631 638 progress.display((int)(100*parsedCharacters / totalBytes), "Working... " + inputLine.lineNo + " lines parsed so far..."); 632 639 633 dataIn = data.split("\t", 2); 634 if (dataIn.length != 2) 635 { 636 throw new IOException("On line " + inputLine.lineNo + ": The file need at least 2 data columns"); 637 } 638 639 inputLine.fromId = Values.getStringOrNull(dataIn[0]); 640 inputLine.cols = data.split(separatorChar, 2); 641 inputLine.fromId = Values.getStringOrNull(inputLine.cols[0]); 640 642 if (inputLine.fromId == null) 641 643 { … … 660 662 output[colNo] = outColumns.get(colNo).convert(inputLine); 661 663 } 662 output[lastCol] = dataIn[1];663 664 dataOut.add(output); 664 665 lineOut++; … … 679 680 tmpOut = new CipherOutputStream(Application.getStaticCache().write(outputFilePath, 5), cipher); 680 681 tmpWriter = new TableWriter(new OutputStreamWriter(tmpOut, "UTF-8")); 682 tmpWriter.setDataSeparator(separatorChar); 681 683 tmpWriter.tablePrintData(headerOut); 682 684 for (Object[] outLines : dataOut) … … 1486 1488 { 1487 1489 int lineNo; 1490 String[] cols; 1488 1491 String fromId; 1489 1492 BioSource patient; … … 1696 1699 1697 1700 /** 1701 Get the rest of the data on the line. 1702 @since 4.33.4 1703 */ 1704 static class RestOfData 1705 extends OutputColumn 1706 { 1707 1708 RestOfData(String restHeader) 1709 { 1710 super(restHeader); 1711 } 1712 1713 @Override 1714 public String convert(InputLine ctx) 1715 { 1716 return ctx.cols.length == 2 ? ctx.cols[1] : null; 1717 } 1718 } 1719 1720 /** 1698 1721 Get the external (release) ID from the patient. 1699 1722 */ -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/InstallServlet.java
r6461 r6474 360 360 jsonChecks.add(checkPlateGeometry(dc, Geometry.THREE_BY_TWO, createIfMissing)); 361 361 jsonChecks.add(checkPlateGeometry(dc, Geometry.ONE_BY_TWELVE, createIfMissing)); 362 jsonChecks.add(checkPlateGeometry(dc, Geometry.ONE_BY_EIGHT, createIfMissing)); 362 363 jsonChecks.add(checkPlateGeometry(dc, Geometry.NINE_BY_NINE, createIfMissing)); 363 364 jsonChecks.add(checkPlateGeometry(dc, Geometry.EIGHT_BY_TWELVE, createIfMissing)); … … 375 376 jsonChecks.add(checkBioplateType(dc, BioplateType.LIBRARY, createIfMissing)); 376 377 jsonChecks.add(checkBioplateType(dc, BioplateType.EXTERNAL_LIBRARY, createIfMissing)); 378 jsonChecks.add(checkBioplateType(dc, BioplateType.EXTERNAL_LIBRARY_STRIP, createIfMissing)); 377 379 jsonChecks.add(checkBioplateType(dc, BioplateType.NEOPREP, createIfMissing)); 378 380 jsonChecks.add(checkBioplateType(dc, BioplateType.MIPS, createIfMissing));
Note: See TracChangeset
for help on using the changeset viewer.