All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.automation.platelayer.PlateSampleLayer Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
package com.hfg.automation.platelayer;


import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.hfg.automation.AutomationXML;
import com.hfg.automation.WellRef;
import com.hfg.automation.plateop.VolumeMask;
import com.hfg.bio.HfgBioXML;
import com.hfg.exception.InvalidValueException;
import com.hfg.units.Quantity;
import com.hfg.units.QuantityType;
import com.hfg.util.CompareUtil;
import com.hfg.util.StringUtil;
import com.hfg.util.collection.CollectionUtil;
import com.hfg.util.collection.OrderedMap;
import com.hfg.util.collection.OrderedSet;
import com.hfg.xml.HfgXMLSerializable;
import com.hfg.xml.XMLNode;
import com.hfg.xml.XMLTag;

//------------------------------------------------------------------------------
/**
 Plate layer for specifying per-well volumes of a sample.
 
@author J. Alex Taylor, hairyfatguy.com
*/ //------------------------------------------------------------------------------ // com.hfg XML/HTML Coding Library // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com // [email protected] //------------------------------------------------------------------------------ public class PlateSampleLayer extends PlateLayerImpl implements SampleLayer { private Class mSampleClass; private Map> mSampleMap = new OrderedMap<>(); //########################################################################### // CONSTRUCTORS //########################################################################### //--------------------------------------------------------------------------- public PlateSampleLayer(Class inSampleClass) { mSampleClass = inSampleClass; } //-------------------------------------------------------------------------- public PlateSampleLayer(XMLNode inXML) { super(inXML); List wellTags = inXML.getSubtagsByName(AutomationXML.WELL); if (CollectionUtil.hasValues(wellTags)) { for (XMLNode wellTag : wellTags) { XMLTag sampleTag = wellTag.getRequiredSubtagByName(AutomationXML.SAMPLE); String sampleClassname = sampleTag.getAttributeValue(HfgBioXML.CLASS_ATT); if (! StringUtil.isSet(sampleClassname)) { throw new RuntimeException("No " + AutomationXML.CLASS_ATT + " specified on the layer's Sample XML tag!"); } S sample; if (sampleClassname.equals(String.class.getName())) { sample = (S) sampleTag.getUnescapedContent(); } else { try { Class clazz = Class.forName(sampleClassname); Constructor constructor = clazz.getConstructor(XMLNode.class); sample = (S) constructor.newInstance(sampleTag.getSubtags().get(0)); } catch (Exception e) { throw new RuntimeException("Error during Sample instantiation from its XML tag!", e); } } if (null == mSampleClass) { mSampleClass = (Class) sample.getClass(); } addSample(new WellRef(wellTag.getAttributeValue(AutomationXML.REF_ATT)), sample, new Quantity(wellTag.getAttributeValue(AutomationXML.VOL_ATT))); } } } //########################################################################### // PUBLIC METHODS //########################################################################### //--------------------------------------------------------------------------- public XMLNode toXMLNode() { XMLNode node = super.toXMLNode(); if (mSampleMap != null) { for (WellRef wellRef : mSampleMap.keySet()) { Map quantityMap = mSampleMap.get(wellRef); XMLNode wellTag = new XMLTag(AutomationXML.WELL); wellTag.setAttribute(AutomationXML.REF_ATT, wellRef); wellTag.setAttribute(AutomationXML.VOL_ATT, quantityMap.values().iterator().next()); XMLNode sampleTag = new XMLTag(AutomationXML.SAMPLE); sampleTag.setAttribute(AutomationXML.CLASS_ATT, mSampleClass.getName()); sampleTag.addSubtag(((HfgXMLSerializable) quantityMap.keySet().iterator().next()).toXMLNode()); wellTag.addSubtag(sampleTag); node.addSubtag(wellTag); } } return node; } //-------------------------------------------------------------------------- @Override public PlateSampleLayer clone() { PlateSampleLayer theClone = (PlateSampleLayer) super.clone(); theClone.mSampleMap = new OrderedMap<>(mSampleMap.size()); for (WellRef wellRef : mSampleMap.keySet()) { theClone.mSampleMap.put(wellRef, new OrderedMap<>(mSampleMap.get(wellRef))); } return theClone; } //--------------------------------------------------------------------------- @Override public int hashCode() { int hashCode = super.hashCode(); hashCode += 31 * getSampleClass().hashCode(); if (mSampleMap != null) { for (WellRef wellRef : mSampleMap.keySet()) { Map quantityMap = mSampleMap.get(wellRef); if (quantityMap != null) { for (S sample : quantityMap.keySet()) { Quantity quantity = quantityMap.get(sample); hashCode += 31 * wellRef.hashCode() * (sample != null ? sample.hashCode() : 1); if (quantity != null) { hashCode += 31 * quantity.hashCode(); } } } } } return hashCode; } //--------------------------------------------------------------------------- @Override public boolean equals(Object inObj2) { return (0 == compareTo(inObj2)); } //--------------------------------------------------------------------------- @Override public int compareTo(Object inObj2) { int result = -1; if (inObj2 != null && inObj2 instanceof PlateSampleLayer) { result = 0; if (this != inObj2) { PlateSampleLayer plateLayer2 = (PlateSampleLayer) inObj2; result = CompareUtil.compare(getSampleClass().toString(), plateLayer2.getSampleClass().toString()); if (0 == result) { result = CompareUtil.compare(mSampleMap.size(), plateLayer2.mSampleMap.size()); } if (0 == result) { for (WellRef wellRef : mSampleMap.keySet()) { result = CompareUtil.compare(mSampleMap.get(wellRef), (Map) plateLayer2.mSampleMap.get(wellRef)); } } } } return result; } //--------------------------------------------------------------------------- public Class getSampleClass() { return mSampleClass; } //--------------------------------------------------------------------------- public PlateSampleLayer addSample(WellRef inWellRef, S inSample) { return addSample(inWellRef, inSample, null); } //--------------------------------------------------------------------------- public PlateSampleLayer addSample(WellRef inWellRef, S inSample, Quantity inVolume) { Map sampleMap = mSampleMap.get(inWellRef); if (null == sampleMap) { sampleMap = new OrderedMap<>(3); mSampleMap.put(inWellRef, sampleMap); } sampleMap.put(inSample, inVolume); return this; } //--------------------------------------------------------------------------- public PlateSampleLayer addVolume(WellRef inWellRef, Quantity inVolume) { if (inVolume != null && !inVolume.getUnit().getQuantityType().equals(QuantityType.VOLUME)) { throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inVolume) + " isn't specified in volume units!"); } if (inVolume != null) { Map sampleMap = mSampleMap.get(inWellRef); if (null == sampleMap) { sampleMap = new OrderedMap<>(3); mSampleMap.put(inWellRef, sampleMap); } if (CollectionUtil.hasValues(sampleMap)) { S sample = sampleMap.keySet().iterator().next(); Quantity volume = sampleMap.get(sample); sampleMap.put(sample, volume != null ? volume.add(inVolume) : inVolume); } else { sampleMap.put(null, inVolume); } } return this; } //--------------------------------------------------------------------------- public Map getSampleVolumeMap(WellRef inWellRef) { return mSampleMap.get(inWellRef); } //--------------------------------------------------------------------------- public VolumeMask getVolumeMask() { VolumeMask volumeMask = new VolumeMask(); Collection occupiedWellRefs = getOccupiedWellRefs(); if (CollectionUtil.hasValues(occupiedWellRefs)) { for (WellRef wellRef : occupiedWellRefs) { Map volMap = getSampleVolumeMap(wellRef); Quantity totalVol = new Quantity(0, "μL"); for (Quantity quantity : volMap.values()) { if (quantity != null) { totalVol = totalVol.add(quantity); } } volumeMask.addVolume(wellRef, totalVol); } } return volumeMask; } //--------------------------------------------------------------------------- public Collection getSamples(WellRef inWellRef) { Map volumeMap = mSampleMap.get(inWellRef); return (volumeMap != null ? volumeMap.keySet() : null); } //--------------------------------------------------------------------------- @Override public Collection getOccupiedWellRefs() { Set wellRefs = null; if (CollectionUtil.hasValues(mSampleMap)) { wellRefs = new OrderedSet<>(mSampleMap.keySet()); } return wellRefs; } //--------------------------------------------------------------------------- @Override public WellSampleLayer getWellLayer(WellRef inWellRef) { WellSampleLayer wellLayer = null; Map sampleMap = mSampleMap.get(inWellRef); if (CollectionUtil.hasValues(sampleMap)) { wellLayer = new WellSampleLayer<>(getSampleClass()); for (S sample : sampleMap.keySet()) { wellLayer.addSample(sample, sampleMap.get(sample)); } wellLayer.setName(name()); } return wellLayer; } }