Last active
December 12, 2018 14:53
-
-
Save HedgehogCode/44fba21697954944f17e28c378315eee to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package org.knime.image.labkit.base.nodes; | |
| import gnu.trove.map.hash.TLongIntHashMap; | |
| import net.imglib2.AbstractWrappedInterval; | |
| import net.imglib2.Interval; | |
| import net.imglib2.Localizable; | |
| import net.imglib2.Point; | |
| import net.imglib2.RandomAccess; | |
| import net.imglib2.RandomAccessibleInterval; | |
| import net.imglib2.Sampler; | |
| import net.imglib2.img.basictypeaccess.IntAccess; | |
| import net.imglib2.type.numeric.integer.IntType; | |
| import net.imglib2.util.IntervalIndexer; | |
| public class DifferenceRandomAccessibleIntType extends AbstractWrappedInterval<RandomAccessibleInterval<IntType>> | |
| implements RandomAccessibleInterval<IntType> { | |
| private final TLongIntHashMap values; | |
| public DifferenceRandomAccessibleIntType(final RandomAccessibleInterval<IntType> source) { | |
| super(source); | |
| values = new TLongIntHashMap(); | |
| } | |
| public DifferenceRandomAccessibleIntType(final RandomAccessibleInterval<IntType> source, | |
| final TLongIntHashMap difference) { | |
| super(source); | |
| values = difference; | |
| } | |
| @Override | |
| public RandomAccess<IntType> randomAccess() { | |
| return new DifferenceRandomAccess(); | |
| } | |
| @Override | |
| public RandomAccess<IntType> randomAccess(final Interval interval) { | |
| return new DifferenceRandomAccess(interval); | |
| } | |
| private class DifferenceRandomAccess extends Point implements RandomAccess<IntType> { | |
| private final IntType value = new IntType(new IntAccess() { | |
| @Override | |
| public int getValue(final int ignored) { | |
| final long index = IntervalIndexer.positionToIndex(DifferenceRandomAccess.this, sourceInterval); | |
| if (values.containsKey(index)) { | |
| return values.get(index); | |
| } else { | |
| sourceRA.setPosition(DifferenceRandomAccess.this); | |
| return sourceRA.get().get(); | |
| } | |
| } | |
| @Override | |
| public void setValue(final int ignored, final int value) { | |
| final long index = IntervalIndexer.positionToIndex(DifferenceRandomAccess.this, sourceInterval); | |
| sourceRA.setPosition(DifferenceRandomAccess.this); | |
| if (sourceRA.get().get() == value) { | |
| values.remove(index); | |
| } else { | |
| values.put(index, value); | |
| } | |
| } | |
| }); | |
| private final RandomAccess<IntType> sourceRA; | |
| private DifferenceRandomAccess() { | |
| super(sourceInterval.numDimensions()); | |
| sourceRA = sourceInterval.randomAccess(); | |
| } | |
| private DifferenceRandomAccess(final Interval interval) { | |
| super(sourceInterval.numDimensions()); | |
| sourceRA = sourceInterval.randomAccess(interval); | |
| } | |
| private DifferenceRandomAccess(final Localizable localizable) { | |
| super(localizable); | |
| sourceRA = sourceInterval.randomAccess(); | |
| } | |
| @Override | |
| public RandomAccess<IntType> copyRandomAccess() { | |
| return new DifferenceRandomAccess(this); | |
| } | |
| @Override | |
| public IntType get() { | |
| return value; | |
| } | |
| @Override | |
| public Sampler<IntType> copy() { | |
| throw new UnsupportedOperationException(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * ------------------------------------------------------------------------ | |
| * | |
| * Copyright by KNIME AG, Zurich, Switzerland | |
| * Website: http://www.knime.com; Email: contact@knime.com | |
| * | |
| * This program is free software; you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License, Version 3, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This program 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 General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, see <http://www.gnu.org/licenses>. | |
| * | |
| * Additional permission under GNU GPL version 3 section 7: | |
| * | |
| * KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs. | |
| * Hence, KNIME and ECLIPSE are both independent programs and are not | |
| * derived from each other. Should, however, the interpretation of the | |
| * GNU GPL Version 3 ("License") under any applicable laws result in | |
| * KNIME and ECLIPSE being a combined program, KNIME AG herewith grants | |
| * you the additional permission to use and propagate KNIME together with | |
| * ECLIPSE with only the license terms in place for ECLIPSE applying to | |
| * ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the | |
| * license terms of ECLIPSE themselves allow for the respective use and | |
| * propagation of ECLIPSE together with KNIME. | |
| * | |
| * Additional permission relating to nodes for KNIME that extend the Node | |
| * Extension (and in particular that are based on subclasses of NodeModel, | |
| * NodeDialog, and NodeView) and that only interoperate with KNIME through | |
| * standard APIs ("Nodes"): | |
| * Nodes are deemed to be separate and independent programs and to not be | |
| * covered works. Notwithstanding anything to the contrary in the | |
| * License, the License does not apply to Nodes, you are not required to | |
| * license Nodes under the License, and you are granted a license to | |
| * prepare and propagate Nodes, in each case even if such Nodes are | |
| * propagated with or for interoperation with KNIME. The owner of a Node | |
| * may freely choose the license terms applicable to such Node, including | |
| * when such Node is propagated with or for interoperation with KNIME. | |
| * --------------------------------------------------------------------- | |
| * | |
| * History | |
| * Dec 10, 2018 (bw): created | |
| */ | |
| package org.knime.image.labkit.base.nodes; | |
| import java.io.ByteArrayInputStream; | |
| import java.io.ByteArrayOutputStream; | |
| import java.io.IOException; | |
| import java.io.ObjectInputStream; | |
| import java.io.ObjectOutputStream; | |
| import java.io.Serializable; | |
| import java.util.ArrayList; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.Set; | |
| import org.apache.xmlbeans.impl.util.Base64; | |
| import org.knime.core.node.InvalidSettingsException; | |
| import org.knime.core.node.NodeSettingsRO; | |
| import org.knime.core.node.NodeSettingsWO; | |
| import org.knime.core.node.NotConfigurableException; | |
| import org.knime.core.node.defaultnodesettings.SettingsModel; | |
| import org.knime.core.node.port.PortObjectSpec; | |
| import gnu.trove.map.hash.TLongIntHashMap; | |
| /** | |
| * | |
| * @author bw | |
| */ | |
| public class SettingsModelAwesomeLabeling extends SettingsModel { | |
| private final String m_configName; | |
| // TODO change object to the type we want to save in the settings | |
| private Map<RowColKey, Overlay> m_labelings; | |
| SettingsModelAwesomeLabeling(final String configName) { | |
| m_configName = configName; | |
| m_labelings = new HashMap<>(); | |
| } | |
| @Override | |
| protected <T extends SettingsModel> T createClone() { | |
| final SettingsModelAwesomeLabeling clone = new SettingsModelAwesomeLabeling(m_configName); | |
| clone.m_labelings.putAll(m_labelings); | |
| return (T)clone; | |
| } | |
| @Override | |
| protected String getModelTypeID() { | |
| return "SMID_labeling"; | |
| } | |
| @Override | |
| protected String getConfigName() { | |
| return m_configName; | |
| } | |
| @Override | |
| protected void loadSettingsForDialog(final NodeSettingsRO settings, final PortObjectSpec[] specs) | |
| throws NotConfigurableException { | |
| try { | |
| loadSettings(settings); | |
| } catch (final InvalidSettingsException ex) { | |
| m_labelings = new HashMap<>(); | |
| } | |
| } | |
| @Override | |
| protected void saveSettingsForDialog(final NodeSettingsWO settings) throws InvalidSettingsException { | |
| saveSettings(settings); | |
| } | |
| @Override | |
| protected void validateSettingsForModel(final NodeSettingsRO settings) throws InvalidSettingsException { | |
| // TODO Auto-generated method stub | |
| } | |
| @Override | |
| protected void loadSettingsForModel(final NodeSettingsRO settings) throws InvalidSettingsException { | |
| loadSettings(settings); | |
| } | |
| @Override | |
| protected void saveSettingsForModel(final NodeSettingsWO settings) { | |
| saveSettings(settings); | |
| } | |
| private void saveSettings(final NodeSettingsWO settings) { | |
| try (final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); | |
| final ObjectOutputStream objOut = new ObjectOutputStream(byteOut);) { | |
| objOut.writeObject(m_labelings); | |
| settings.addString(m_configName, new String(Base64.encode(byteOut.toByteArray()))); | |
| } catch (final IOException e) { | |
| // TODO better error message? | |
| throw new IllegalStateException(e); | |
| } | |
| } | |
| private void loadSettings(final NodeSettingsRO settings) throws InvalidSettingsException { | |
| final byte[] data = Base64.decode(settings.getString(m_configName).getBytes()); | |
| try (final ByteArrayInputStream byteIn = new ByteArrayInputStream(data); | |
| final ObjectInputStream objIn = new ObjectInputStream(byteIn)) { | |
| m_labelings = (Map<RowColKey, Overlay>)objIn.readObject(); | |
| } catch (final IOException | ClassNotFoundException e) { | |
| // TODO Auto-generated catch block | |
| throw new InvalidSettingsException(e); | |
| } | |
| } | |
| @Override | |
| public String toString() { | |
| // TODO Auto-generated method stub | |
| return null; | |
| } | |
| public Overlay getLabeling(final String rowKey, final String colName) { | |
| final RowColKey key = new RowColKey(rowKey, colName); | |
| if (m_labelings.containsKey(key)) { | |
| return m_labelings.get(key); | |
| } else { | |
| Overlay difference = new Overlay(new ArrayList<>(), new TLongIntHashMap()); | |
| m_labelings.put(key, difference); | |
| return difference; | |
| } | |
| } | |
| public void setLabeling(final String rowKey, final String colName, final Overlay labeling) { | |
| m_labelings.put(new RowColKey(rowKey, colName), labeling); | |
| } | |
| static class Overlay implements Serializable { | |
| private static final long serialVersionUID = 1L; | |
| private final List<Set<String>> m_labels; | |
| private final TLongIntHashMap m_difference; | |
| Overlay(final List<Set<String>> labels, final TLongIntHashMap difference) { | |
| m_labels = labels; | |
| m_difference = difference; | |
| } | |
| List<Set<String>> getLabels() { | |
| return m_labels; | |
| } | |
| TLongIntHashMap getDifference() { | |
| return m_difference; | |
| } | |
| } | |
| static class RowColKey implements Serializable { | |
| private final String m_rowKey; | |
| private final String m_colName; | |
| RowColKey(final String rowKey, final String colName) { | |
| m_rowKey = rowKey; | |
| m_colName = colName; | |
| } | |
| @Override | |
| public boolean equals(final Object obj) { | |
| if (!(obj instanceof RowColKey)) { | |
| return false; | |
| } | |
| final RowColKey o = (RowColKey)obj; | |
| return m_rowKey.equals(o.m_rowKey) && m_colName.equals(o.m_colName); | |
| } | |
| @Override | |
| public int hashCode() { | |
| final int prime = 31; | |
| int result = 1; | |
| result = prime * result + ((m_rowKey == null) ? 0 : m_rowKey.hashCode()); | |
| result = prime * result + ((m_colName == null) ? 0 : m_colName.hashCode()); | |
| return result; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment