Changeset 5740
- Timestamp:
- Nov 20, 2019, 8:30:18 AM (3 years ago)
- Location:
- extensions/net.sf.basedb.reggie/trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/net.sf.basedb.reggie/trunk
- Property svn:mergeinfo changed
/extensions/net.sf.basedb.reggie/branches/4.23-stable merged: 5675-5681,5738 /extensions/net.sf.basedb.reggie/tags/4.23.3 (added) merged: 5739
- Property svn:mergeinfo changed
-
extensions/net.sf.basedb.reggie/trunk/resources/index.js
r5683 r5740 359 359 msg += '<div class="snake-quote-source">Indiana Jones - Raiders of the Lost Ark</div>'; 360 360 Forms.showNotification('caseName', msg, 'snake-quote', 'pointer-above'); 361 } 362 361 var url = 'Session.servlet?ID='+App.getSessionId(); 362 url += '&cmd=ReggieTheSnakeWasSummoned'; 363 Wizard.asyncJsonRequest(url); 364 } 363 365 364 366 return index; -
extensions/net.sf.basedb.reggie/trunk/resources/libprep/mrna_protocol.js
r5552 r5740 184 184 totalVolume = mrna.DilutionVolume; 185 185 } 186 else if (totalVolume > mrna.DilutionVolume)186 else if (totalVolume - 0.05 > mrna.DilutionVolume) // Use 0.05 to avoid issues with 50.0000000001 > 50.0 187 187 { 188 188 remarks[remarks.length] = 'Large mix; Use '+Reggie.formatNumber(mrna.DilutionVolume, 'µl', 1); -
extensions/net.sf.basedb.reggie/trunk/resources/libprep/select_rna.js
r5552 r5740 1696 1696 } 1697 1697 1698 if (info && info.id && info.bioWell &&!rna.stratagene)1698 if (info && info.id && !rna.stratagene) 1699 1699 { 1700 1700 rna.usedQuantity = Math.max(Math.min(info.remainingQuantity, rna.qc ? QUANTITY_QC : QUANTITY_REGULAR), QUANTITY_MINIMAL); // µg … … 1738 1738 else 1739 1739 { 1740 warningMsg[warningMsg.length] = 'No quantity';1740 if (!rna.external) warningMsg[warningMsg.length] = 'No quantity'; 1741 1741 } 1742 1742 if (info.rqs) … … 1750 1750 if (info.rin < QUALITY_SCORE_WARNING_LIMIT) warningMsg[warningMsg.length] = 'Low RIN value'; 1751 1751 } 1752 else if (!info.preNormalized )1752 else if (!info.preNormalized && !rna.external) 1753 1753 { 1754 1754 warningMsg[warningMsg.length] = 'No RQS/RIN value'; … … 1759 1759 text += '<div class="volumes"><span class="volume">'+Numbers.formatNumber(volRNA, 1)+'</span> + <span class="water">'+Numbers.formatNumber(water, 1)+'µl</span></div>'; 1760 1760 } 1761 else 1762 { 1763 if (!rna.external) warningMsg[warningMsg.length] = 'No NDConc value'; 1764 } 1765 if (info.QiacubeDate) 1766 { 1767 text += '<div class="qiacube-date">'+info.QiacubeDate+'</div>'; 1768 } 1769 else if (info.DilutionDate) 1770 { 1771 text += '<div class="dilution-date">'+info.DilutionDate+'</div>'; 1772 } 1761 1773 else 1762 1774 { 1763 warningMsg[warningMsg.length] = 'No NDConc value'; 1764 } 1765 if (info.QiacubeDate) 1766 { 1767 text += '<div class="qiacube-date">'+info.QiacubeDate+'</div>'; 1768 } 1769 else if (info.DilutionDate) 1770 { 1771 text += '<div class="dilution-date">'+info.DilutionDate+'</div>'; 1772 } 1773 else 1774 { 1775 warningMsg[warningMsg.length] = info.preNormalized ? 'No DilutionDate value' : 'No QiacubeDate value'; 1775 if (!rna.external) warningMsg[warningMsg.length] = info.preNormalized ? 'No DilutionDate value' : 'No QiacubeDate value'; 1776 1776 } 1777 1777 if (info.AutoProcessing) -
extensions/net.sf.basedb.reggie/trunk/resources/personal/map-external-data.js
r5663 r5740 30 30 { 31 31 var frm = document.forms['reggie']; 32 var fromPnr = frm.mapFrom.value == 'PersonalNo' ;32 var fromPnr = frm.mapFrom.value == 'PersonalNo' || frm.mapFrom.value == 'PAD'; 33 33 34 34 Doc.showHide('exportPersonalNo', !fromPnr); 35 Doc.showHide('alsoExportPad', !fromPnr); 35 36 Doc.showHide('exportPatientId', fromPnr); 36 37 Doc.showHide('alsoExportCaseId', fromPnr); … … 63 64 preview += Strings.encodeTags(line) + '\n'; 64 65 } 65 if (mapFrom == null && line.match(/^[QCS]\d+\t.*$/)) // We look for lines starting with 'Q', 'C' or 'S' followed by {digits} and a {tab}66 if (mapFrom == null) 66 67 { 67 var firstChar = line.charAt(0); 68 if (firstChar == 'Q') 68 if (line.match(/^[QCS]\d+\t.*$/))// We look for lines starting with 'Q', 'C' or 'S' followed by {digits} and a {tab} 69 69 { 70 mapFrom = 'PatientId'; 70 var firstChar = line.charAt(0); 71 if (firstChar == 'Q') 72 { 73 mapFrom = 'PatientId'; 74 } 75 else if (firstChar == 'C') 76 { 77 mapFrom = 'CaseId'; 78 } 79 else if (firstChar == 'S') 80 { 81 mapFrom = 'SpecimenId'; 82 } 71 83 } 72 else if ( firstChar == 'C')84 else if (lineNo == 0 && line.match(/^[^\t]*pad/i)) // If the first header column contains 'pad' (ignoring case) we assume it contains PAD values 73 85 { 74 mapFrom = 'CaseId'; 75 } 76 else if (firstChar == 'S') 77 { 78 mapFrom = 'SpecimenId'; 86 mapFrom = 'PAD'; 79 87 } 80 88 } … … 108 116 url += '&exportCaseId='+(frm.exportCaseId.checked ? 1 : 0); 109 117 url += '&exportSpecimenId='+(frm.exportSpecimenId.checked ? 1 : 0); 118 url += '&exportPad='+(frm.exportPad.checked ? 1 : 0); 110 119 url += '&sortOutput='+(frm.sortOutputOrder.checked ? 1 : 0); 111 120 Wizard.showLoadingAnimation('Working...', 'map-data-progress'); -
extensions/net.sf.basedb.reggie/trunk/resources/personal/map-external-data.jsp
r5663 r5740 101 101 <select name="mapFrom" id="mapFrom"> 102 102 <option value="PersonalNo">Personal number 103 <option value="PAD">PAD 103 104 <option value="PatientId">Patient release ID 104 105 <option value="CaseId">Case release ID … … 115 116 <td class="input" style="padding-top: 4px; padding-bottom: 4px;"> 116 117 <div id="exportPersonalNo" style="display: none;"><input type="checkbox" checked disabled>Personal number</div> 118 <div id="alsoExportPad" style="display: none;"><label><input type="checkbox" name="exportPad" id="exportPad">PAD</label></div> 117 119 <div id="exportPatientId" style="display: none;"><input type="checkbox" checked disabled>Patient release ID</div> 118 120 <div id="alsoExportCaseId" style="display: none;"><label><input type="checkbox" name="exportCaseId" id="exportCaseId">Case release ID</label></div> -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/activity/ActivityDef.java
r5728 r5740 242 242 */ 243 243 public static final ActivityDef IMPORTED_RNA_ALIQUOTS = new ActivityDef("imported-rna-aliquots", "Imported 1 aliquot for RNAseq analysis", "Imported {COUNT} aliquots for RNAseq analysis"); 244 244 245 /** 246 Reggie the Snake was summoned. 247 */ 248 public static final ActivityDef REGGIE_THE_SNAKE_WAS_SUMMONED = new ActivityDef("reggie-the-snake-was-summoned", "🐍 Reggie the Snake was summoned", "🐍🐍 Reggie the Snake was summoned {COUNT} times"); 245 249 246 250 private final String id; -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/activity/ActivityEntry.java
r5421 r5740 50 50 { 51 51 return LocalDateTime.ofInstant(getEventDate().toInstant(), ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS); 52 } 53 54 /** 55 Get the age of the event in seconds. 56 @since 4.23.3 57 */ 58 public default int getAgeInSeconds() 59 { 60 return (int)((System.currentTimeMillis() - getEventDate().getTime()) / 1000); 52 61 } 53 62 -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/activity/ActivityLog.java
r5617 r5740 394 394 int ageInDays = (int)ChronoUnit.DAYS.between(a.getEventDay(), today); 395 395 boolean remove = ageInDays > maxAgeInDays || (ageInDays > 1 && numPassed >= maxEntries); 396 if (a.getMessage().contains("Reggie the Snake") && a.getAgeInSeconds() > 180) 397 { 398 // Reggie the Snake never stays more than 3 minutes 399 remove = true; 400 } 396 401 if (!remove) numPassed++; 397 402 return remove; … … 403 408 to the disc at regular intervals. 404 409 */ 405 static class SaveActivityLog410 public static class SaveActivityLog 406 411 extends TimerTask 407 412 { 408 SaveActivityLog()413 public SaveActivityLog() 409 414 {} 410 415 -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/ExportServlet.java
r5663 r5740 51 51 import net.sf.basedb.core.Type; 52 52 import net.sf.basedb.core.query.Annotations; 53 import net.sf.basedb.core.query.Expression;54 53 import net.sf.basedb.core.query.Expressions; 55 54 import net.sf.basedb.core.query.Hql; … … 513 512 } 514 513 515 @SuppressWarnings({"unchecked", "rawtypes"})516 514 @Override 517 515 protected void doPost(HttpServletRequest req, HttpServletResponse resp) … … 538 536 539 537 String mapFrom = Values.getString(req.getParameter("mapFrom"), "PersonalNo"); 540 String mapFromFriendlyName = "personal number";541 538 boolean exportCaseId = Values.getBoolean(req.getParameter("exportCaseId")); 542 539 boolean exportSpecimenId = Values.getBoolean(req.getParameter("exportSpecimenId")); 540 boolean exportPad = Values.getBoolean(req.getParameter("exportPad")); 543 541 boolean sortOutput = Values.getBoolean(req.getParameter("sortOutput")); 544 542 545 543 SnapshotManager manager = new SnapshotManager(); 546 Object[] headerOut = new Object[2]; 547 ValueConverter<BioSource, String>[] dataConvert = new ValueConverter[1]; 548 List<Object[]> dataOut = new ArrayList<>(); 549 550 ItemQuery<BioSource> findPat = BioSource.getQuery(); 551 Subtype.PATIENT.addFilter(dc, findPat); 552 findPat.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 544 List<OutputColumn> outColumns = new ArrayList<>(); 545 PatientLoader loader = null; 546 if ("PatientId".equals(mapFrom)) 547 { 548 loader = PatientLoader.fromPatientId(dc); 549 outColumns.add(new PatientToPersonalNumberConverter(dc, manager)); 550 if (exportPad) outColumns.add(ReleaseIdToPadConverter.fromPatientId(dc, manager)); 551 } 552 else if ("CaseId".equals(mapFrom)) 553 { 554 loader = PatientLoader.fromCaseId(dc); 555 outColumns.add(new PatientToPersonalNumberConverter(dc, manager)); 556 if (exportPad) outColumns.add(ReleaseIdToPadConverter.fromCaseId(dc, manager)); 557 } 558 else if ("SpecimenId".equals(mapFrom)) 559 { 560 loader = PatientLoader.fromSpecimenId(dc); 561 outColumns.add(new PatientToPersonalNumberConverter(dc, manager)); 562 if (exportPad) outColumns.add(ReleaseIdToPadConverter.fromSpecimenId(dc, manager)); 563 } 564 else if ("PAD".equals(mapFrom)) 565 { 566 PatientLoaderFromPad padLoader = new PatientLoaderFromPad(dc); 567 loader = padLoader; 568 outColumns.add(new PatientToReleaseIdConverter()); 569 if (exportCaseId) outColumns.add(padLoader.toCaseId()); 570 if (exportSpecimenId) outColumns.add(padLoader.toSpecimenId()); 571 } 572 else // "PersonalNo" 573 { 574 loader = PatientLoader.fromPersonalNumber(dc); 575 outColumns.add(new PatientToReleaseIdConverter()); 576 if (exportCaseId) outColumns.add(new PatientToCaseReleaseIdConverter(dc)); 577 if (exportSpecimenId) outColumns.add(new PatientToSpecimenReleaseIdConverter(dc)); 578 } 553 579 554 // Modify the query and output headers depending on the "mapFrom" parameter555 // we should be able to execute it with a value from the file and find a patient item556 Expression mapFromParameter = Expressions.parameter("mapFrom");557 if ("PatientId".equals(mapFrom))558 {559 mapFromFriendlyName = "patient release ID";560 findPat.restrict(Restrictions.eq(Hql.property("externalId"), mapFromParameter));561 dataConvert[0] = new PatientToPersonalNumberConverter(dc, manager);562 headerOut[0] = "PersonalNumber";563 }564 else if ("CaseId".equals(mapFrom))565 {566 mapFromFriendlyName = "case release ID";567 findPat.join(Hql.innerJoin("childCreationEvents", "cce"));568 findPat.join(Hql.innerJoin("cce", "event", "evt"));569 findPat.join(Hql.innerJoin("evt", "bioMaterial", "cse")); // 'cse' should now reference a case570 findPat.restrict(Restrictions.eq(Hql.property("cse", "externalId"), mapFromParameter));571 dataConvert[0] = new PatientToPersonalNumberConverter(dc, manager);572 headerOut[0] = "PersonalNumber";573 }574 else if ("SpecimenId".equals(mapFrom))575 {576 mapFromFriendlyName = "specimen release ID";577 findPat.join(Hql.innerJoin("childCreationEvents", "cce"));578 findPat.join(Hql.innerJoin("cce", "event", "evt"));579 findPat.join(Hql.innerJoin("evt", "bioMaterial", "cse")); // 'cse' should now reference a case580 findPat.join(Hql.innerJoin("cse", "childCreationEvents", "cce2"));581 findPat.join(Hql.innerJoin("cce2", "event", "evt2"));582 findPat.join(Hql.innerJoin("evt2", "bioMaterial", "spm")); // 'spm' should now reference a specimen/nospecimen583 findPat.restrict(Restrictions.eq(Hql.property("spm", "externalId"), mapFromParameter));584 dataConvert[0] = new PatientToPersonalNumberConverter(dc, manager);585 headerOut[0] = "PersonalNumber";586 }587 else // "PersonalNo"588 {589 findPat.join(Annotations.innerJoin(null, Annotationtype.PERSONAL_NUMBER.load(dc), "pnr"));590 findPat.restrict(Restrictions.eq(Hql.alias("pnr"), mapFromParameter));591 592 int numCols = 2 + (exportCaseId ? 1 : 0) + (exportSpecimenId ? 1 : 0);593 if (numCols > headerOut.length) // We need more output columns594 {595 headerOut = new Object[numCols];596 dataConvert = new ValueConverter[numCols-1]; // The last column need to converter597 }598 int col = 0;599 dataConvert[col] = new PatientToReleaseIdConverter();600 headerOut[col++] = "PatientId";601 if (exportCaseId)602 {603 headerOut[col] = "CaseId";604 dataConvert[col++] = new PatientToCaseReleaseIdConverter(dc);605 }606 if (exportSpecimenId)607 {608 headerOut[col] = "SpecimenId";609 dataConvert[col++] = new PatientToSpecimenReleaseIdConverter(dc);610 }611 }612 580 613 581 InputStream uploadIn = null; … … 640 608 } 641 609 642 int lastCol = headerOut.length - 1; 610 int lastCol = outColumns.size(); 611 Object[] headerOut = new Object[lastCol+1]; 612 for (int colNo = 0; colNo < lastCol; colNo++) 613 { 614 headerOut[colNo] = outColumns.get(colNo).getHeader(); 615 } 643 616 headerOut[lastCol] = dataIn[1]; 644 617 645 int lineIn = 0;646 618 int lineOut = 0; 647 619 int linesSkipped = 0; 620 InputLine inputLine = new InputLine(); 621 List<Object[]> dataOut = new ArrayList<>(); 648 622 649 623 String data = uploadReader.readLine(); … … 651 625 { 652 626 parsedCharacters += data.length() + 1; 653 lineIn++;654 progress.display((int)(100*parsedCharacters / totalBytes), "Working... " + lineIn+ " lines parsed so far...");627 inputLine.lineNo++; 628 progress.display((int)(100*parsedCharacters / totalBytes), "Working... " + inputLine.lineNo + " lines parsed so far..."); 655 629 656 630 dataIn = data.split("\t", 2); 657 631 if (dataIn.length != 2) 658 632 { 659 throw new IOException("On line " + lineIn+ ": The file need at least 2 data columns");633 throw new IOException("On line " + inputLine.lineNo + ": The file need at least 2 data columns"); 660 634 } 661 635 662 StringfromId = Values.getStringOrNull(dataIn[0]);663 if ( fromId == null)636 inputLine.fromId = Values.getStringOrNull(dataIn[0]); 637 if (inputLine.fromId == null) 664 638 { 665 throw new IOException("On line " + lineIn + ": " + mapFromFriendlyName+ " is missing");639 throw new IOException("On line " + inputLine.lineNo + ": " + loader.getMapFromFriendlyName() + " is missing"); 666 640 } 667 668 findPat.setParameter("mapFrom", fromId, Type.STRING);669 List<BioSource> patients = findPat.list(dc);670 if ( patients.size() == 0)641 642 inputLine.patient = loader.convert(inputLine); 643 644 if (inputLine.patient == null) 671 645 { 672 646 linesSkipped++; 673 647 if (linesSkipped > 100 && lineOut == 0) 674 648 { 675 throw new IOException("On line " + lineIn + ": No patients found after " + lineIn+ " lines. Is this the correct file?");649 throw new IOException("On line " + inputLine.lineNo + ": No patients found after " + inputLine.lineNo + " lines. Is this the correct file?"); 676 650 } 677 }678 else if (patients.size() > 1)679 {680 throw new IOException("On line " + lineIn + ": Found " + patients.size() + " patients with same " + mapFromFriendlyName + ": " + fromId);681 651 } 682 652 else 683 653 { 684 BioSource pat = patients.get(0);685 654 Object[] output = new Object[headerOut.length]; 686 for (int c = 0; c < lastCol; c++)655 for (int colNo = 0; colNo < lastCol; colNo++) 687 656 { 688 output[c ] = dataConvert[c].convert(pat);657 output[colNo] = outColumns.get(colNo).convert(inputLine); 689 658 } 690 659 output[lastCol] = dataIn[1]; … … 697 666 if (lineOut == 0) 698 667 { 699 throw new IOException("On line " + lineIn+ ": No patients found. Is this the correct file?");668 throw new IOException("On line " + inputLine.lineNo + ": No patients found. Is this the correct file?"); 700 669 } 701 670 … … 714 683 tmpWriter.flush(); 715 684 tmpOut.flush(); 716 jsonMessages.add("Parsed " + lineIn+ " lines from input file");685 jsonMessages.add("Parsed " + inputLine.lineNo + " lines from input file"); 717 686 jsonMessages.add("Wrote " + lineOut + " lines to output file"); 718 687 if (linesSkipped > 0) … … 724 693 jsonMessages.add("A patient was found for all lines"); 725 694 } 726 json.put("numLinesIn", lineIn);695 json.put("numLinesIn", inputLine.lineNo); 727 696 json.put("numLinesOut", lineOut); 728 697 json.put("numNotFound", linesSkipped); … … 1506 1475 1507 1476 /** 1477 Represents a line from the input file. 1478 TODO -- add more data here ? 1479 */ 1480 static class InputLine 1481 { 1482 int lineNo; 1483 String fromId; 1484 BioSource patient; 1485 } 1486 1487 /** 1488 Implementations need to take an input line and 1489 find a single patient for that line. 1490 */ 1491 static abstract class PatientLoader 1492 implements ValueConverter<InputLine, BioSource> 1493 { 1494 static PatientLoader fromPersonalNumber(DbControl dc) 1495 { 1496 ItemQuery<BioSource> query = BioSource.getQuery(); 1497 query.join(Annotations.innerJoin(null, Annotationtype.PERSONAL_NUMBER.load(dc), "pnr")); 1498 query.restrict(Restrictions.eq(Hql.alias("pnr"), Expressions.parameter("fromId"))); 1499 return new PatientLoaderByQuery(dc, query, "personal number"); 1500 } 1501 1502 static PatientLoader fromPatientId(DbControl dc) 1503 { 1504 ItemQuery<BioSource> query = BioSource.getQuery(); 1505 query.restrict(Restrictions.eq(Hql.property("externalId"), Expressions.parameter("fromId"))); 1506 return new PatientLoaderByQuery(dc, query, "patient release ID"); 1507 } 1508 1509 static PatientLoader fromCaseId(DbControl dc) 1510 { 1511 ItemQuery<BioSource> query = BioSource.getQuery(); 1512 query.join(Hql.innerJoin("childCreationEvents", "cce")); 1513 query.join(Hql.innerJoin("cce", "event", "evt")); 1514 query.join(Hql.innerJoin("evt", "bioMaterial", "cse")); // 'cse' should now reference a case 1515 query.restrict(Restrictions.eq(Hql.property("cse", "externalId"), Expressions.parameter("fromId"))); 1516 return new PatientLoaderByQuery(dc, query, "case release ID"); 1517 } 1518 1519 static PatientLoader fromSpecimenId(DbControl dc) 1520 { 1521 ItemQuery<BioSource> query = BioSource.getQuery(); 1522 query.join(Hql.innerJoin("childCreationEvents", "cce")); 1523 query.join(Hql.innerJoin("cce", "event", "evt")); 1524 query.join(Hql.innerJoin("evt", "bioMaterial", "cse")); // 'cse' should now reference a case 1525 query.join(Hql.innerJoin("cse", "childCreationEvents", "cce2")); 1526 query.join(Hql.innerJoin("cce2", "event", "evt2")); 1527 query.join(Hql.innerJoin("evt2", "bioMaterial", "spm")); // 'spm' should now reference a specimen/nospecimen 1528 query.restrict(Restrictions.eq(Hql.property("spm", "externalId"), Expressions.parameter("fromId"))); 1529 return new PatientLoaderByQuery(dc, query, "specimen release ID"); 1530 } 1531 1532 final String mapFromFriendlyName; 1533 final DbControl dc; 1534 1535 PatientLoader(DbControl dc, String mapFromFriendlyName) 1536 { 1537 this.dc = dc; 1538 this.mapFromFriendlyName = mapFromFriendlyName; 1539 } 1540 1541 public String getMapFromFriendlyName() 1542 { 1543 return mapFromFriendlyName; 1544 } 1545 } 1546 1547 /** 1548 Patient loader implementation that can find the patient by executing a 1549 query using the source id as a parameter. 1550 */ 1551 static class PatientLoaderByQuery 1552 extends PatientLoader 1553 { 1554 1555 private final ItemQuery<BioSource> patientQuery; 1556 1557 PatientLoaderByQuery(DbControl dc, ItemQuery<BioSource> patientQuery, String mapFromFriendlyName) 1558 { 1559 super(dc, mapFromFriendlyName); 1560 this.patientQuery = patientQuery; 1561 Subtype.PATIENT.addFilter(dc, patientQuery); 1562 patientQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 1563 } 1564 1565 @Override 1566 public BioSource convert(InputLine ctx) 1567 { 1568 patientQuery.setParameter("fromId", ctx.fromId, Type.STRING); 1569 List<BioSource> patients = patientQuery.list(dc); 1570 if (patients.size() > 1) 1571 { 1572 throw new RuntimeException("On line " + ctx.lineNo + ": Found " + patients.size() + " patients with same " + mapFromFriendlyName + ": " + ctx.fromId); 1573 } 1574 return patients.size() == 0 ? null : patients.get(0); 1575 } 1576 } 1577 1578 /** 1579 Patient loader implementation when the source value is a PAD value. This implementation 1580 is used instead of the PatientLoaderByQuery for improved performance when 1581 output columns for case and/or specimen release ID are required. The implementation 1582 executes an initial query to find the specimen item(s) with the given PAD and then 1583 uses the specimen to find other items. This avoids executing the slow query against 1584 the PAD annotation more than once. 1585 */ 1586 static class PatientLoaderFromPad 1587 extends PatientLoader 1588 { 1589 1590 private final ItemQuery<Sample> specimenQuery; 1591 private final ItemQuery<BioSource> patientQuery; 1592 private List<Integer> currentSpecimen; 1593 1594 public PatientLoaderFromPad(DbControl dc) 1595 { 1596 super(dc, "PAD"); 1597 1598 specimenQuery = Sample.getQuery(); 1599 specimenQuery.restrict( 1600 Restrictions.or( 1601 Subtype.SPECIMEN.restriction(dc, null), 1602 Subtype.NO_SPECIMEN.restriction(dc, null) 1603 )); 1604 specimenQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 1605 specimenQuery.join(Annotations.innerJoin(null, Annotationtype.PAD.load(dc), "pad")); 1606 specimenQuery.restrict(Restrictions.eq(Hql.alias("pad"), Expressions.parameter("fromId"))); 1607 1608 patientQuery = BioSource.getQuery(); 1609 Subtype.PATIENT.addFilter(dc, patientQuery); 1610 patientQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 1611 patientQuery.join(Hql.innerJoin("childCreationEvents", "cce")); 1612 patientQuery.join(Hql.innerJoin("cce", "event", "evt")); 1613 patientQuery.join(Hql.innerJoin("evt", "bioMaterial", "cse")); // 'cse' should now reference a case 1614 patientQuery.join(Hql.innerJoin("cse", "childCreationEvents", "cce2")); 1615 patientQuery.join(Hql.innerJoin("cce2", "event", "evt2")); 1616 patientQuery.join(Hql.innerJoin("evt2", "bioMaterial", "spm")); // 'spm' should now reference a specimen/nospecimen 1617 patientQuery.restrict(Restrictions.in(Hql.alias("spm"), Expressions.parameter("specimen"))); 1618 patientQuery.setDistinct(true); 1619 } 1620 1621 @Override 1622 public String getMapFromFriendlyName() 1623 { 1624 return "PAD"; 1625 } 1626 1627 @Override 1628 public BioSource convert(InputLine ctx) 1629 { 1630 specimenQuery.setParameter("fromId", ctx.fromId, Type.STRING); 1631 currentSpecimen = specimenQuery.idList(dc); 1632 1633 if (currentSpecimen.size() == 0) return null; 1634 1635 patientQuery.setParameter("specimen", currentSpecimen, Type.INT); 1636 List<BioSource> patients = patientQuery.list(dc); 1637 if (patients.size() > 1) 1638 { 1639 throw new RuntimeException("On line " + ctx.lineNo + ": Found " + patients.size() + " patients with same PAD: " + ctx.fromId); 1640 } 1641 return patients.size() == 0 ? null : patients.get(0); 1642 } 1643 1644 /** 1645 Create an output implementation for the specimen release id. 1646 */ 1647 public OutputColumn toSpecimenId() 1648 { 1649 ItemQuery<Sample> query = Sample.getQuery(); 1650 query.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("specimen"))); 1651 return new PadToReleaseIdConverter("SpecimenId", dc, query, this); 1652 } 1653 1654 /** 1655 Create an output implementation for the case release id. 1656 */ 1657 public OutputColumn toCaseId() 1658 { 1659 ItemQuery<Sample> query = Sample.getQuery(); 1660 Subtype.CASE.addFilter(dc, query); 1661 query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 1662 query.join(Hql.innerJoin("childCreationEvents", "cce")); 1663 query.join(Hql.innerJoin("cce", "event", "evt")); 1664 query.join(Hql.innerJoin("evt", "bioMaterial", "spm")); // 'spm' should now reference a specimen/nospecimen 1665 query.restrict(Restrictions.in(Hql.alias("spm"), Expressions.parameter("specimen"))); 1666 return new PadToReleaseIdConverter("CaseId", dc, query, this); 1667 } 1668 } 1669 1670 1671 /** 1672 Implementation need to generate an output column 1673 for a given line. 1674 */ 1675 static abstract class OutputColumn 1676 implements ValueConverter<InputLine, String> 1677 { 1678 1679 private final String header; 1680 OutputColumn(String header) 1681 { 1682 this.header = header; 1683 } 1684 1685 public String getHeader() 1686 { 1687 return header; 1688 } 1689 } 1690 1691 /** 1508 1692 Get the external (release) ID from the patient. 1509 1693 */ 1510 1694 static class PatientToReleaseIdConverter 1511 implements ValueConverter<BioSource, String>1695 extends OutputColumn 1512 1696 { 1513 1697 PatientToReleaseIdConverter() 1514 {} 1515 1516 @Override 1517 public String convert(BioSource patient) 1518 { 1519 return patient.getExternalId(); 1698 { 1699 super("PatientId"); 1700 } 1701 1702 @Override 1703 public String convert(InputLine ctx) 1704 { 1705 return ctx.patient.getExternalId(); 1520 1706 } 1521 1707 } … … 1526 1712 */ 1527 1713 static class PatientToCaseReleaseIdConverter 1528 implements ValueConverter<BioSource, String>1714 extends OutputColumn 1529 1715 { 1530 1716 private final DbControl dc; … … 1534 1720 PatientToCaseReleaseIdConverter(DbControl dc) 1535 1721 { 1722 super("CaseId"); 1536 1723 this.dc = dc; 1537 1724 this.toRelaseId = new ToReleaseIdFormatter(); … … 1545 1732 1546 1733 @Override 1547 public String convert( BioSource patient)1548 { 1549 caseQuery.setEntityParameter("pat", patient);1734 public String convert(InputLine ctx) 1735 { 1736 caseQuery.setEntityParameter("pat", ctx.patient); 1550 1737 List<Sample> cases = caseQuery.list(dc); 1551 1738 return Values.getString(cases, ",", true, toRelaseId); … … 1558 1745 */ 1559 1746 static class PatientToSpecimenReleaseIdConverter 1560 implements ValueConverter<BioSource, String>1747 extends OutputColumn 1561 1748 { 1562 1749 private final DbControl dc; … … 1566 1753 PatientToSpecimenReleaseIdConverter(DbControl dc) 1567 1754 { 1755 super("SpecimenId"); 1568 1756 this.dc = dc; 1569 1757 this.toRelaseId = new ToReleaseIdFormatter(); … … 1582 1770 1583 1771 @Override 1584 public String convert( BioSource patient)1585 { 1586 specimenQuery.setEntityParameter("pat", patient);1772 public String convert(InputLine ctx) 1773 { 1774 specimenQuery.setEntityParameter("pat", ctx.patient); 1587 1775 List<Sample> specimen = specimenQuery.list(dc); 1588 1776 return Values.getString(specimen, ",", true, toRelaseId); … … 1594 1782 */ 1595 1783 static class PatientToPersonalNumberConverter 1596 implements ValueConverter<BioSource, String>1784 extends OutputColumn 1597 1785 { 1598 1786 … … 1602 1790 PatientToPersonalNumberConverter(DbControl dc, SnapshotManager manager) 1603 1791 { 1792 super("PersonalNumber"); 1604 1793 this.dc = dc; 1605 1794 this.manager = manager; … … 1607 1796 1608 1797 @Override 1609 public String convert(BioSource patient) 1610 { 1611 return (String)Annotationtype.PERSONAL_NUMBER.getAnnotationValue(dc, manager, patient); 1612 } 1798 public String convert(InputLine ctx) 1799 { 1800 return (String)Annotationtype.PERSONAL_NUMBER.getAnnotationValue(dc, manager, ctx.patient); 1801 } 1802 } 1803 1804 /** 1805 Maps a release id from patient, case or specimen to PAD 1806 (one or more) on specimen items. Use one of the factor methods 1807 to get an instance for the proper release id type. 1808 */ 1809 static class ReleaseIdToPadConverter 1810 extends OutputColumn 1811 { 1812 private final DbControl dc; 1813 private final SnapshotManager manager; 1814 private final ItemQuery<Sample> specimenQuery; 1815 1816 /** 1817 Get the PAD when the source id is a specimen release id. 1818 */ 1819 static ReleaseIdToPadConverter fromSpecimenId(DbControl dc, SnapshotManager manager) 1820 { 1821 ItemQuery<Sample> query = Sample.getQuery(); 1822 query.restrict(Restrictions.eq(Hql.property("externalId"), Expressions.parameter("fromId"))); 1823 return new ReleaseIdToPadConverter(dc, manager, query); 1824 } 1825 1826 /** 1827 Get the PAD(s) when the source id is a case release id. 1828 */ 1829 static ReleaseIdToPadConverter fromCaseId(DbControl dc, SnapshotManager manager) 1830 { 1831 ItemQuery<Sample> query = Sample.getQuery(); 1832 query.join(Hql.innerJoin("parent", "cse")); 1833 query.restrict(Restrictions.eq(Hql.property("cse", "externalId"), Expressions.parameter("fromId"))); 1834 return new ReleaseIdToPadConverter(dc, manager, query); 1835 } 1836 1837 /** 1838 Get the PAD(s) when the source id is a patient release id. 1839 */ 1840 static ReleaseIdToPadConverter fromPatientId(DbControl dc, SnapshotManager manager) 1841 { 1842 ItemQuery<Sample> query = Sample.getQuery(); 1843 query.join(Hql.innerJoin("parent", "cse")); 1844 query.join(Hql.innerJoin("cse", "parent", "pat")); 1845 query.restrict(Restrictions.eq(Hql.property("pat", "externalId"), Expressions.parameter("fromId"))); 1846 return new ReleaseIdToPadConverter(dc, manager, query); 1847 } 1848 1849 private ReleaseIdToPadConverter(DbControl dc, SnapshotManager manager, ItemQuery<Sample> specimenQuery) 1850 { 1851 super("PAD"); 1852 this.dc = dc; 1853 this.manager = manager; 1854 this.specimenQuery = specimenQuery; 1855 specimenQuery.restrict( 1856 Restrictions.or( 1857 Subtype.SPECIMEN.restriction(dc, null), 1858 Subtype.NO_SPECIMEN.restriction(dc, null) 1859 )); 1860 specimenQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); 1861 } 1862 1863 @Override 1864 public String convert(InputLine ctx) 1865 { 1866 specimenQuery.setParameter("fromId", ctx.fromId, Type.STRING); 1867 List<Sample> specimen = specimenQuery.list(dc); 1868 String pad = null; 1869 if (specimen.size() > 1) 1870 { 1871 Set<String> allPad = new TreeSet<>(); 1872 for (Sample s : specimen) 1873 { 1874 allPad.add((String)Annotationtype.PAD.getAnnotationValue(dc, manager, s)); 1875 } 1876 pad = Values.getString(allPad, ",", true); 1877 } 1878 else if (specimen.size() == 1) 1879 { 1880 pad = (String)Annotationtype.PAD.getAnnotationValue(dc, manager, specimen.get(0)); 1881 } 1882 return pad; 1883 } 1884 1885 } 1886 1887 /** 1888 Output release id for case or specimen items that has been previously found by the 1889 PatientLoaderFromPad implementation. 1890 */ 1891 static class PadToReleaseIdConverter 1892 extends OutputColumn 1893 { 1894 1895 1896 private final DbControl dc; 1897 private final ItemQuery<Sample> query; 1898 private final PatientLoaderFromPad padLoader; 1899 1900 private PadToReleaseIdConverter(String header, DbControl dc, ItemQuery<Sample> query, PatientLoaderFromPad padLoader) 1901 { 1902 super(header); 1903 this.dc = dc; 1904 this.query = query; 1905 this.padLoader = padLoader; 1906 } 1907 1908 @Override 1909 public String convert(InputLine ctx) 1910 { 1911 if (padLoader.currentSpecimen.size() == 0) return null; 1912 1913 query.setParameter("specimen", padLoader.currentSpecimen, Type.INT); 1914 List<Sample> items = query.list(dc); 1915 String idValues = null; 1916 if (items.size() > 1) 1917 { 1918 Set<String> allId = new TreeSet<>(); 1919 for (Sample s : items) 1920 { 1921 allId.add(s.getExternalId()); 1922 } 1923 idValues = Values.getString(allId, ",", true); 1924 } 1925 else if (items.size() == 1) 1926 { 1927 idValues = items.get(0).getExternalId(); 1928 } 1929 return idValues; 1930 } 1931 1613 1932 } 1614 1933 -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/SessionServlet.java
r5404 r5740 17 17 import org.json.simple.JSONObject; 18 18 19 import net.sf.basedb.core.Application; 19 20 import net.sf.basedb.core.DbControl; 20 21 import net.sf.basedb.core.Directory; … … 25 26 import net.sf.basedb.reggie.JsonUtil; 26 27 import net.sf.basedb.reggie.Reggie; 28 import net.sf.basedb.reggie.activity.ActivityDef; 27 29 import net.sf.basedb.reggie.activity.ActivityEntry; 28 30 import net.sf.basedb.reggie.activity.ActivityLog; … … 206 208 } 207 209 } 210 else if ("ReggieTheSnakeWasSummoned".equals(cmd)) 211 { 212 sc = Reggie.getSessionControl(req); 213 dc = sc.newDbControl(); 214 ActivityDef.REGGIE_THE_SNAKE_WAS_SUMMONED.merge(dc, 1).setUser("Indiana Jones"); 215 dc.commit(); 216 // Makes Reggie the Snake go away after at least 200 seconds 217 Application.getScheduler().schedule(new ActivityLog.SaveActivityLog(), 200000, true); 218 } 208 219 209 220 }
Note: See TracChangeset
for help on using the changeset viewer.