com.hfg.automation.plateop.VolumeMask 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.plateop;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.hfg.automation.AutomationXML;
import com.hfg.automation.PlateLayout;
import com.hfg.automation.WellRange;
import com.hfg.automation.WellRef;
import com.hfg.automation.platelayer.PlateDataLayer;
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.xml.XMLNode;
import com.hfg.xml.XMLTag;
//------------------------------------------------------------------------------
/**
Mask for being able to specify per-well volumes for a plate operation.
@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 VolumeMask implements Cloneable
{
private Map mVolumeMap;
//###########################################################################
// CONSTRUCTORS
//###########################################################################
//--------------------------------------------------------------------------
public VolumeMask()
{
}
//--------------------------------------------------------------------------
public VolumeMask(PlateDataLayer inVolumeDataLayer)
{
for (WellRef wellRef : inVolumeDataLayer.getOccupiedWellRefs())
{
setVolume(wellRef, inVolumeDataLayer.getData(wellRef));
}
}
//--------------------------------------------------------------------------
public VolumeMask(XMLNode inXML)
{
inXML.verifyTagName(AutomationXML.VOLUME_MASK);
List wellTags = inXML.getSubtagsByName(AutomationXML.WELL);
if (CollectionUtil.hasValues(wellTags))
{
for (XMLNode wellTag : wellTags)
{
setVolume(new WellRef(wellTag.getAttributeValue(AutomationXML.REF_ATT)),
new Quantity(wellTag.getAttributeValue(AutomationXML.VOL_ATT)));
}
}
}
//###########################################################################
// PUBLIC METHODS
//###########################################################################
//---------------------------------------------------------------------------
public XMLNode toXMLNode()
{
XMLNode node = new XMLTag(AutomationXML.VOLUME_MASK);
if (CollectionUtil.hasValues(mVolumeMap))
{
for (WellRef wellRef : mVolumeMap.keySet())
{
XMLNode wellTag = new XMLTag(AutomationXML.WELL);
wellTag.setAttribute(AutomationXML.REF_ATT, wellRef);
wellTag.setAttribute(AutomationXML.VOL_ATT, mVolumeMap.get(wellRef));
node.addSubtag(wellTag);
}
}
return node;
}
//--------------------------------------------------------------------------
@Override
public VolumeMask clone()
{
VolumeMask theClone;
try
{
theClone = (VolumeMask) super.clone();
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException(e);
}
if (mVolumeMap != null)
{
theClone.mVolumeMap = new OrderedMap<>(mVolumeMap);
}
return theClone;
}
//---------------------------------------------------------------------------
public Collection getOccupiedWellRefs()
{
List wellRefs = null;
if (CollectionUtil.hasValues(mVolumeMap))
{
wellRefs = new ArrayList<>(mVolumeMap.keySet());
// TODO: sort? need access to a PlateLayout
}
return wellRefs;
}
//---------------------------------------------------------------------------
public VolumeMask setVolume(WellRef inWellRef, Quantity inVolume)
{
if (inVolume != null)
{
if (!inVolume.getUnit().getQuantityType().equals(QuantityType.VOLUME))
{
throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inVolume) + " isn't specified in volume units!");
}
if (null == mVolumeMap)
{
mVolumeMap = new OrderedMap<>();
}
mVolumeMap.put(inWellRef, inVolume);
}
else if (mVolumeMap != null)
{
mVolumeMap.remove(inWellRef);
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask setVolume(WellRange inWellRange, Quantity inVolume)
{
if (inVolume != null)
{
if (!inVolume.getUnit().getQuantityType().equals(QuantityType.VOLUME))
{
throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inVolume) + " isn't specified in volume units!");
}
if (null == mVolumeMap)
{
mVolumeMap = new OrderedMap<>();
}
Iterator iterator = inWellRange.wellRefIterator();
while (iterator.hasNext())
{
mVolumeMap.put(iterator.next(), inVolume);
}
}
else if (mVolumeMap != null)
{
Iterator iterator = inWellRange.wellRefIterator();
while (iterator.hasNext())
{
mVolumeMap.remove(iterator.next());
}
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask addVolume(Collection inWellRefs, Quantity inVolume)
{
if (CollectionUtil.hasValues(inWellRefs))
{
for (WellRef wellRef : inWellRefs)
{
addVolume(wellRef, inVolume);
}
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask addVolume(VolumeMask inVolumeMask)
{
if (inVolumeMask != null
&& CollectionUtil.hasValues(inVolumeMask.getOccupiedWellRefs()))
{
for (WellRef wellRef : inVolumeMask.getOccupiedWellRefs())
{
addVolume(wellRef, inVolumeMask.getVolume(wellRef));
}
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask subtractFrom(Quantity inVolume)
{
if (CollectionUtil.hasValues(getOccupiedWellRefs()))
{
for (WellRef wellRef : getOccupiedWellRefs())
{
setVolume(wellRef, inVolume.subtract(getVolume(wellRef)));
}
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask addVolume(WellRef inWellRef, Quantity inVolume)
{
if (inVolume != null)
{
if (!inVolume.getUnit().getQuantityType().equals(QuantityType.VOLUME))
{
throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inVolume) + " isn't specified in volume units!");
}
if (null == mVolumeMap)
{
mVolumeMap = new OrderedMap<>();
mVolumeMap.put(inWellRef, inVolume);
}
else
{
Quantity existingVolume = mVolumeMap.get(inWellRef);
if (null == existingVolume)
{
mVolumeMap.put(inWellRef, inVolume);
}
else
{
mVolumeMap.put(inWellRef, existingVolume.add(inVolume));
}
}
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask subtractVolume(VolumeMask inVolumeMask)
{
for (WellRef wellRef : inVolumeMask.getOccupiedWellRefs())
{
subtractVolume(wellRef, inVolumeMask.getVolume(wellRef));
}
return this;
}
//---------------------------------------------------------------------------
public VolumeMask subtractVolume(WellRef inWellRef, Quantity inValue)
{
if (inValue != null)
{
Quantity negativeQuantity = new Quantity(- inValue.floatValue(), inValue.getUnit());
addVolume(inWellRef, negativeQuantity);
}
return this;
}
//---------------------------------------------------------------------------
public WellRange getOccupiedWellRange(PlateLayout inLayout)
{
WellRef firstWellRef = null;
WellRef lastWellRef = null;
if (mVolumeMap != null)
{
for (WellRef wellRef : inLayout.getWellRefs())
{
if (null == firstWellRef)
{
firstWellRef = wellRef;
}
lastWellRef = wellRef;
}
}
return firstWellRef != null ? new WellRange(firstWellRef, lastWellRef) : null;
}
//---------------------------------------------------------------------------
public boolean allVolumesAreIdentical()
{
boolean volsAreIdentical = true;
Quantity quantity = null;
if (CollectionUtil.hasValues(getOccupiedWellRefs()))
{
for (WellRef wellRef : getOccupiedWellRefs())
{
Quantity wellQuantity = getVolume(wellRef);
if (null == quantity)
{
quantity = wellQuantity;
}
else if (CompareUtil.compare(quantity, wellQuantity) != 0)
{
volsAreIdentical = false;
break;
}
}
}
return volsAreIdentical;
}
//---------------------------------------------------------------------------
public Quantity getVolume(WellRef inWellRef)
{
return (mVolumeMap != null ? mVolumeMap.get(inWellRef) : null);
}
}