com.hfg.automation.platelayer.PlateSampleLayer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
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;
}
}