extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/cmd/LysateInfo.java

Code
Comments
Other
Rev Date Author Line
6207 12 Apr 21 nicklas 1 package net.sf.basedb.reggie.plugins.cmd;
6207 12 Apr 21 nicklas 2
6207 12 Apr 21 nicklas 3 import java.util.Date;
7232 02 Jun 23 nicklas 4 import java.util.List;
7232 02 Jun 23 nicklas 5
7232 02 Jun 23 nicklas 6 import net.sf.basedb.core.DbControl;
7232 02 Jun 23 nicklas 7 import net.sf.basedb.core.Extract;
7232 02 Jun 23 nicklas 8 import net.sf.basedb.core.ItemQuery;
6207 12 Apr 21 nicklas 9 import net.sf.basedb.core.Protocol;
7232 02 Jun 23 nicklas 10 import net.sf.basedb.reggie.Reggie;
7232 02 Jun 23 nicklas 11 import net.sf.basedb.reggie.dao.Subtype;
6217 19 Apr 21 nicklas 12 import net.sf.basedb.util.Values;
6207 12 Apr 21 nicklas 13
6207 12 Apr 21 nicklas 14 /**
6207 12 Apr 21 nicklas 15   Holds all information about a Lysate. Validation will
6207 12 Apr 21 nicklas 16   be done at construction and errors are reported to
6207 12 Apr 21 nicklas 17   the JsonSection. Check the 'valid' flag before using
6207 12 Apr 21 nicklas 18   the information.
6207 12 Apr 21 nicklas 19   
6207 12 Apr 21 nicklas 20   @since 4.32
6207 12 Apr 21 nicklas 21 */
6207 12 Apr 21 nicklas 22 public class LysateInfo 
6207 12 Apr 21 nicklas 23 {
7232 02 Jun 23 nicklas 24   public Extract mergeWith;
6711 27 Apr 22 nicklas 25   public String tubeLabel;
6207 12 Apr 21 nicklas 26   public Date partitionDate;
6207 12 Apr 21 nicklas 27   public Date lysateDate;
6714 29 Apr 22 nicklas 28   public Float originalVolume_ul;
6714 29 Apr 22 nicklas 29   public Float remainingVolume_ul;
6714 29 Apr 22 nicklas 30   public Float usedVolumePerChildItem_ul;
6714 29 Apr 22 nicklas 31   public Float usedFromSpecimen_mg;
6715 29 Apr 22 nicklas 32   public Integer usedNumberOfPieces;
6918 01 Dec 22 nicklas 33   public String storageLocation;
6207 12 Apr 21 nicklas 34
6207 12 Apr 21 nicklas 35   public Protocol protocol;
6207 12 Apr 21 nicklas 36   public boolean valid;
6207 12 Apr 21 nicklas 37   
6893 25 Nov 22 nicklas 38   public LysateInfo(JsonSection section, SpecimenInfo specimen, MainInfo main)
6207 12 Apr 21 nicklas 39   {
6207 12 Apr 21 nicklas 40     if (section != null)
6207 12 Apr 21 nicklas 41     {
7232 02 Jun 23 nicklas 42       if (specimen != null && specimen.mergeWith != null) 
7232 02 Jun 23 nicklas 43       {
7232 02 Jun 23 nicklas 44         mergeWith = findLysateForMerge(specimen, section);
7232 02 Jun 23 nicklas 45       }
7232 02 Jun 23 nicklas 46
6732 05 May 22 nicklas 47       tubeLabel = section.getOptionalEntry("Specimen-ID", NullValidator.warnIfNull(PatternValidator.SPECIMEN_ID.withPrefixSuffix(specimen != null?specimen.tubeLabel:null, "-Lys")));
7097 05 Apr 23 nicklas 48       partitionDate = section.getRequiredEntry("Partition date", DateValidator.YYYY_MM_DD.warnIfFutureOrOlder(main.refDate));
6893 25 Nov 22 nicklas 49       lysateDate = section.getRequiredEntry("Lysate date", DateValidator.YYYY_MM_DD.warnIfFutureOrOlder(partitionDate, main.refDate));
6714 29 Apr 22 nicklas 50       originalVolume_ul = section.getRequiredEntry("Original volume (ul)", FloatValidator.POSITIVE);
6714 29 Apr 22 nicklas 51       remainingVolume_ul = section.getOptionalEntry("Remaining volume (ul)", NullValidator.warnIfNull(FloatValidator.POSITIVE));
6714 29 Apr 22 nicklas 52       usedFromSpecimen_mg = section.getRequiredEntry("Used quantity (mg)", FloatValidator.POSITIVE);
6221 23 Apr 21 nicklas 53       protocol = section.getRequiredEntry("Protocol", ProtocolValidator.SAMPLE_HANDLING_PROTOCOL);
6715 29 Apr 22 nicklas 54       usedNumberOfPieces = section.getOptionalEntry("Used number of pieces", NullValidator.warnIfNull(IntValidator.POSITIVE.warnIf(1, 10)));
6714 29 Apr 22 nicklas 55
6918 01 Dec 22 nicklas 56       // TODO -- maybe this will change in the future
6918 01 Dec 22 nicklas 57       storageLocation = section.getOptionalEntry("Storage location", NullValidator.allowNull(String.class));
6714 29 Apr 22 nicklas 58
6714 29 Apr 22 nicklas 59       // Check volumes, used quantities, etc.
6718 02 May 22 nicklas 60       if (originalVolume_ul != null && remainingVolume_ul != null)
6217 19 Apr 21 nicklas 61       {
6714 29 Apr 22 nicklas 62         usedVolumePerChildItem_ul = (originalVolume_ul-remainingVolume_ul) / 3; // We divide it equally on RNA, DNA and FlowThrough
6718 02 May 22 nicklas 63         if (remainingVolume_ul+0.1 > originalVolume_ul)
6718 02 May 22 nicklas 64         {
6718 02 May 22 nicklas 65           section.addWarningMessage("Remaining volume ("+Values.formatNumber(remainingVolume_ul, 1, "µl")+") > "
6718 02 May 22 nicklas 66             + "Original volume ("+Values.formatNumber(originalVolume_ul, 1, "µl")+")");
6718 02 May 22 nicklas 67         }
6714 29 Apr 22 nicklas 68       }
6916 01 Dec 22 nicklas 69       if (specimen != null && specimen.originalQuantity_mg != null && usedFromSpecimen_mg != null)
6714 29 Apr 22 nicklas 70       {
6916 01 Dec 22 nicklas 71         if (usedFromSpecimen_mg > specimen.originalQuantity_mg)
6217 19 Apr 21 nicklas 72         {
6955 12 Dec 22 nicklas 73           section.addWarningMessage("Adjusting Lysate.Used quantity from "+usedFromSpecimen_mg+"mg to "+specimen.originalQuantity_mg+"mg");
6955 12 Dec 22 nicklas 74           usedFromSpecimen_mg = specimen.originalQuantity_mg;
6916 01 Dec 22 nicklas 75         }
6916 01 Dec 22 nicklas 76         else if (specimen.remainingQuantity_mg != null && Math.abs(specimen.originalQuantity_mg-usedFromSpecimen_mg-specimen.remainingQuantity_mg) > 0.1)
6916 01 Dec 22 nicklas 77         {
6916 01 Dec 22 nicklas 78           section.addWarningMessage("Lysate.Used quantity ("+Values.formatNumber(usedFromSpecimen_mg, 1, "mg")+
6714 29 Apr 22 nicklas 79             ") <> Specimen.originalQuantity ("+Values.formatNumber(specimen.originalQuantity_mg, 1, "mg")+
6714 29 Apr 22 nicklas 80             ") - Specimen.remainingQuantity ("+Values.formatNumber(specimen.remainingQuantity_mg, 1, "mg")+")");
6217 19 Apr 21 nicklas 81         }
6217 19 Apr 21 nicklas 82       }
6207 12 Apr 21 nicklas 83     }
6207 12 Apr 21 nicklas 84     valid = section != null && !section.hasError();
6207 12 Apr 21 nicklas 85   }
6207 12 Apr 21 nicklas 86   
7232 02 Jun 23 nicklas 87   /**
7232 02 Jun 23 nicklas 88     If there is a Specimen to be merged, try to find a single child Lysate
7232 02 Jun 23 nicklas 89     item that should also be merged.
7232 02 Jun 23 nicklas 90   */
7232 02 Jun 23 nicklas 91   private Extract findLysateForMerge(SpecimenInfo specimen, JsonSection section)
7232 02 Jun 23 nicklas 92   {
7232 02 Jun 23 nicklas 93     DbControl dc = section.getFile().dc();
7232 02 Jun 23 nicklas 94     ItemQuery<Extract> query = specimen.mergeWith.getExtracts();
7232 02 Jun 23 nicklas 95     query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
7232 02 Jun 23 nicklas 96     query.restrict(Subtype.LYSATE.restriction(dc, null));
7232 02 Jun 23 nicklas 97     
7232 02 Jun 23 nicklas 98     Extract merge = null;
7232 02 Jun 23 nicklas 99     List<Extract> extracts = query.list(dc);
7232 02 Jun 23 nicklas 100     if (extracts.size() == 1)
7232 02 Jun 23 nicklas 101     {
7232 02 Jun 23 nicklas 102       merge = extracts.get(0);
7232 02 Jun 23 nicklas 103     }
7232 02 Jun 23 nicklas 104     else if (extracts.size() == 0)
7232 02 Jun 23 nicklas 105     {
7232 02 Jun 23 nicklas 106       // TODO -- we could allow this without an error and create a new child Lysate
7232 02 Jun 23 nicklas 107       // but there is no current use case for this scenario
7232 02 Jun 23 nicklas 108       section.addErrorMessage("Found a Specimen for merge but it has no child Lysate: "+specimen.mergeWith.getName());
7232 02 Jun 23 nicklas 109     }
7232 02 Jun 23 nicklas 110     else
7232 02 Jun 23 nicklas 111     {
7232 02 Jun 23 nicklas 112       section.addErrorMessage("Found a Specimen for merge but there are "+extracts.size()+" child Lysates: "+specimen.mergeWith.getName());
7232 02 Jun 23 nicklas 113     }
7232 02 Jun 23 nicklas 114     return merge;
7232 02 Jun 23 nicklas 115   }
6207 12 Apr 21 nicklas 116 }