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

plugins.nherve.toolbox.PersistenceToolbox Maven / Gradle / Ivy

/*
 * Copyright 2010, 2011 Institut Pasteur.
 * Copyright 2012 Institut National de l'Audiovisuel.
 *
 * This file is part of NHerveTools.
 *
 * NHerveTools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * NHerveTools 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 NHerveTools. If not, see .
 */
package plugins.nherve.toolbox;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.HashMap;
import java.util.Map;

import plugins.nherve.toolbox.image.feature.Signature;
import plugins.nherve.toolbox.image.feature.signature.BagOfSignatures;
import plugins.nherve.toolbox.image.feature.signature.DefaultVectorSignature;
import plugins.nherve.toolbox.image.feature.signature.DenseVectorSignature;
import plugins.nherve.toolbox.image.feature.signature.IndexSignature;
import plugins.nherve.toolbox.image.feature.signature.SignatureException;
import plugins.nherve.toolbox.image.feature.signature.SparseVectorSignature;

/**
 * The Class PersistenceToolbox.
 *
 * @author Nicolas HERVE - [email protected]
 */
public class PersistenceToolbox {

	/** The Constant BAG_TYPE. */
	public final static int BAG_TYPE = 2;

	/** The Constant cs. */
	private final static Charset cs = Charset.forName("UTF-8");

	/** The Constant csd. */
	private final static CharsetDecoder csd = cs.newDecoder();

	/** The Constant cse. */
	private final static CharsetEncoder cse = cs.newEncoder();

	/** The Constant DENSE_TYPE. */
	public final static int DENSE_TYPE = 0;

	/** The Constant DOUBLE_NB_BYTES. */
	public final static int DOUBLE_NB_BYTES = 8;

	/** The Constant FLOAT_NB_BYTES. */
	public final static int FLOAT_NB_BYTES = 4;

	public final static int INDEX_TYPE = 4;

	/** The Constant INT_NB_BYTES. */
	public final static int INT_NB_BYTES = 4;

	public final static int LONG_NB_BYTES = 8;

	/** The Constant BAG_TYPE. */
	public final static int NULL_TYPE = 3;

	/** The Constant SPARSE_TYPE. */
	public final static int SPARSE_TYPE = 1;

	public final static Map> HOOKS_BY_TYPE = new HashMap>();
	public final static Map, SignaturePersistenceHook> HOOKS_BY_CLASS = new HashMap, SignaturePersistenceHook>();

	/**
	 * Dump bag of signatures.
	 *
	 * @param fc
	 *            the fc
	 * @param s
	 *            the s
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpBagOfSignatures(FileChannel fc, BagOfSignatures s) throws IOException {
		dumpInt(fc, s.size());
		for (DefaultVectorSignature vs : s) {
			dumpSignature(fc, vs);
		}
	}

	/**
	 * Dump boolean.
	 *
	 * @param fc
	 *            the fc
	 * @param b
	 *            the b
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpBoolean(FileChannel fc, boolean b) throws IOException {
		if (b) {
			dumpInt(fc, 1);
		} else {
			dumpInt(fc, 0);
		}
	}

	/**
	 * Dump dense vector signature.
	 *
	 * @param fc
	 *            the fc
	 * @param s
	 *            the s
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpDenseVectorSignature(FileChannel fc, DenseVectorSignature s) throws IOException {
		dumpInt(fc, s.getSize());
		ByteBuffer bb = ByteBuffer.allocate(DOUBLE_NB_BYTES * s.getSize());
		DoubleBuffer db = bb.asDoubleBuffer();
		db.put(s.getData());
		db.flip();
		fc.write(bb);
	}

	/**
	 * Dump double.
	 *
	 * @param fc
	 *            the fc
	 * @param d
	 *            the d
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpDouble(FileChannel fc, double d) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(DOUBLE_NB_BYTES);
		DoubleBuffer db = bb.asDoubleBuffer();
		db.put(d);
		db.flip();
		fc.write(bb);
	}

	/**
	 * Dump float.
	 *
	 * @param fc
	 *            the fc
	 * @param f
	 *            the f
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpFloat(FileChannel fc, float f) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(FLOAT_NB_BYTES);
		FloatBuffer db = bb.asFloatBuffer();
		db.put(f);
		db.flip();
		fc.write(bb);
	}

	public static void dumpFullIntArray(FileChannel fc, int[] i) throws IOException {
		dumpInt(fc, i.length);
		dumpIntArray(fc, i);
	}

	public static void dumpFullLongArray(FileChannel fc, long[] i) throws IOException {
		dumpInt(fc, i.length);
		dumpLongArray(fc, i);
	}

	public static void dumpIndexSignature(FileChannel fc, IndexSignature s) throws IOException {
		dumpInt(fc, s.getSize());
		ByteBuffer bb = ByteBuffer.allocate(INT_NB_BYTES * s.getSize());
		IntBuffer db = bb.asIntBuffer();
		db.put(s.getData());
		db.flip();
		fc.write(bb);
	}

	/**
	 * Dump int.
	 *
	 * @param fc
	 *            the fc
	 * @param i
	 *            the i
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpInt(FileChannel fc, int i) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(INT_NB_BYTES);
		IntBuffer ib = bb.asIntBuffer();
		ib.put(i);
		ib.flip();
		fc.write(bb);
	}

	/**
	 * Dump int array.
	 *
	 * @param fc
	 *            the fc
	 * @param i
	 *            the i
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpIntArray(FileChannel fc, int[] i) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(i.length * INT_NB_BYTES);
		IntBuffer ib = bb.asIntBuffer();
		ib.put(i);
		ib.flip();
		fc.write(bb);
	}

	public static void dumpLong(FileChannel fc, long l) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(LONG_NB_BYTES);
		LongBuffer lb = bb.asLongBuffer();
		lb.put(l);
		lb.flip();
		fc.write(bb);
	}

	public static void dumpLongArray(FileChannel fc, long[] i) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(i.length * LONG_NB_BYTES);
		LongBuffer ib = bb.asLongBuffer();
		ib.put(i);
		ib.flip();
		fc.write(bb);
	}

	/**
	 * Dump signature.
	 *
	 * @param fc
	 *            the fc
	 * @param s
	 *            the s
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	@SuppressWarnings("unchecked")
	public static void dumpSignature(FileChannel fc, Signature s) throws IOException {
		if (s == null) {
			dumpInt(fc, NULL_TYPE);
		} else if (s instanceof DenseVectorSignature) {
			dumpInt(fc, DENSE_TYPE);
			dumpDenseVectorSignature(fc, (DenseVectorSignature) s);
		} else if (s instanceof IndexSignature) {
			dumpInt(fc, INDEX_TYPE);
			dumpIndexSignature(fc, (IndexSignature) s);
		} else if (s instanceof SparseVectorSignature) {
			dumpInt(fc, SPARSE_TYPE);
			dumpSparseVectorSignature(fc, (SparseVectorSignature) s);
		} else if (s instanceof BagOfSignatures) {
			dumpInt(fc, BAG_TYPE);
			dumpBagOfSignatures(fc, (BagOfSignatures) s);
		} else if (HOOKS_BY_CLASS.containsKey(s.getClass())) {
			SignaturePersistenceHook hook = HOOKS_BY_CLASS.get(s.getClass());
			dumpInt(fc, hook.getTypeCode());
			hook.dumpSignature(fc, (DefaultVectorSignature)s);
		} else {
			throw new IOException("dumpSignature(" + s.getClass().getName() + ") not yet implemented");
		}
	}

	/**
	 * Dump sparse vector signature.
	 *
	 * @param fc
	 *            the fc
	 * @param s
	 *            the s
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpSparseVectorSignature(FileChannel fc, SparseVectorSignature s) throws IOException {
		try {
			int nzb = s.getNonZeroBins();

			int[] i = new int[nzb];
			double[] d = new double[nzb];
			int n = 0;
			for (int c : s) {
				i[n] = c;
				d[n] = s.get(c);
				n++;
			}

			dumpInt(fc, s.getSize());
			dumpInt(fc, nzb);

			ByteBuffer bb1 = ByteBuffer.allocate(INT_NB_BYTES * nzb);
			IntBuffer ib = bb1.asIntBuffer();
			ib.put(i);
			ib.flip();
			fc.write(bb1);

			ByteBuffer bb2 = ByteBuffer.allocate(DOUBLE_NB_BYTES * nzb);
			DoubleBuffer db = bb2.asDoubleBuffer();
			db.put(d);
			db.flip();
			fc.write(bb2);
		} catch (SignatureException e) {
			throw new IOException(e);
		}
	}

	/**
	 * Dump string.
	 *
	 * @param fc
	 *            the fc
	 * @param s
	 *            the s
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void dumpString(FileChannel fc, String s) throws IOException {
		CharBuffer cb = CharBuffer.allocate(s.length());
		cb.put(s);
		cb.flip();
		ByteBuffer buff = cse.encode(cb);
		dumpInt(fc, buff.limit());
		fc.write(buff);
	}

	/**
	 * Gets the file.
	 *
	 * @param f
	 *            the f
	 * @param write
	 *            the write
	 * @return the file
	 * @throws FileNotFoundException
	 *             the file not found exception
	 */
	public static RandomAccessFile getFile(File f, boolean write) throws FileNotFoundException {
		if (write) {
			if (f.exists()) {
				f.delete();
			}
			f.getParentFile().mkdirs();
			return new RandomAccessFile(f, "rw");
		} else {
			return new RandomAccessFile(f, "r");
		}
	}

	/**
	 * Load bag of signatures.
	 *
	 * @param fc
	 *            the fc
	 * @return the bag of signatures
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static BagOfSignatures loadBagOfSignatures(FileChannel fc) throws IOException {
		int type = loadInt(fc);
		if (type == NULL_TYPE) {
			return null;
		}
		if (type != BAG_TYPE) {
			throw new IOException("Unknown BagOfSignatures type (" + type + ")");
		}
		int sz = loadInt(fc);
		BagOfSignatures bag = new BagOfSignatures();
		for (int i = 0; i < sz; i++) {
			bag.add(loadVectorSignature(fc));
		}
		return bag;
	}

	/**
	 * Load boolean.
	 *
	 * @param fc
	 *            the fc
	 * @return true, if successful
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static boolean loadBoolean(FileChannel fc) throws IOException {
		return loadInt(fc) == 1;
	}

	/**
	 * Load dense vector signature.
	 *
	 * @param fc
	 *            the fc
	 * @return the dense vector signature
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static DenseVectorSignature loadDenseVectorSignature(FileChannel fc) throws IOException {
		int sz = loadInt(fc);
		ByteBuffer bb = ByteBuffer.allocate(DOUBLE_NB_BYTES * sz);
		fc.read(bb);
		bb.flip();
		DoubleBuffer db = bb.asDoubleBuffer();
		double[] data = new double[sz];
		db.get(data);
		DenseVectorSignature v = new DenseVectorSignature(data);
		return v;
	}

	/**
	 * Load double.
	 *
	 * @param fc
	 *            the fc
	 * @return the double
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static double loadDouble(FileChannel fc) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(DOUBLE_NB_BYTES);
		fc.read(bb);
		bb.flip();
		DoubleBuffer db = bb.asDoubleBuffer();
		return db.get();
	}

	/**
	 * Load float.
	 *
	 * @param fc
	 *            the fc
	 * @return the float
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static float loadFloat(FileChannel fc) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(FLOAT_NB_BYTES);
		fc.read(bb);
		bb.flip();
		FloatBuffer db = bb.asFloatBuffer();
		return db.get();
	}

	public static int[] loadFullIntArray(FileChannel fc) throws IOException {
		int sz = loadInt(fc);
		return loadIntArray(fc, sz);
	}

	public static long[] loadFullLongArray(FileChannel fc) throws IOException {
		int sz = loadInt(fc);
		return loadLongArray(fc, sz);
	}

	public static IndexSignature loadIndexSignature(FileChannel fc) throws IOException {
		int sz = loadInt(fc);
		ByteBuffer bb = ByteBuffer.allocate(INT_NB_BYTES * sz);
		fc.read(bb);
		bb.flip();
		IntBuffer db = bb.asIntBuffer();
		int[] data = new int[sz];
		db.get(data);
		IndexSignature v = new IndexSignature(data);
		return v;
	}

	/**
	 * Load int.
	 *
	 * @param fc
	 *            the fc
	 * @return the int
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static int loadInt(FileChannel fc) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(INT_NB_BYTES);
		fc.read(bb);
		bb.flip();
		IntBuffer ib = bb.asIntBuffer();
		return ib.get();
	}

	public static int[] loadIntArray(FileChannel fc, int sz) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(PersistenceToolbox.INT_NB_BYTES * sz);
		fc.read(bb);
		bb.flip();
		IntBuffer ib = bb.asIntBuffer();
		int[] res = new int[sz];
		ib.get(res);
		return res;
	}

	public static long loadLong(FileChannel fc) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(LONG_NB_BYTES);
		fc.read(bb);
		bb.flip();
		LongBuffer ib = bb.asLongBuffer();
		return ib.get();
	}

	public static long[] loadLongArray(FileChannel fc, int sz) throws IOException {
		ByteBuffer bb = ByteBuffer.allocate(PersistenceToolbox.LONG_NB_BYTES * sz);
		fc.read(bb);
		bb.flip();
		LongBuffer ib = bb.asLongBuffer();
		long[] res = new long[sz];
		ib.get(res);
		return res;
	}

	/**
	 * Load sparse vector signature.
	 *
	 * @param fc
	 *            the fc
	 * @return the sparse vector signature
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static SparseVectorSignature loadSparseVectorSignature(FileChannel fc) throws IOException {
		try {
			int sz = loadInt(fc);
			int nzb = loadInt(fc);

			SparseVectorSignature v = new SparseVectorSignature(sz);

			ByteBuffer bb1 = ByteBuffer.allocate(INT_NB_BYTES * nzb);
			fc.read(bb1);
			bb1.flip();
			IntBuffer ib = bb1.asIntBuffer();
			ib.rewind();

			ByteBuffer bb2 = ByteBuffer.allocate(DOUBLE_NB_BYTES * nzb);
			fc.read(bb2);
			bb2.flip();
			DoubleBuffer db = bb2.asDoubleBuffer();
			db.rewind();

			while (db.hasRemaining() && ib.hasRemaining()) {
				v.set(ib.get(), db.get());
			}

			if (db.hasRemaining() || ib.hasRemaining()) {
				throw new IOException("IntBuffer and DoubleBuffer sizes mismatch");
			}

			return v;
		} catch (SignatureException e) {
			throw new IOException(e);
		}
	}

	/**
	 * Load string.
	 *
	 * @param fc
	 *            the fc
	 * @return the string
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static String loadString(FileChannel fc) throws IOException {
		int sz = loadInt(fc);
		ByteBuffer bb = ByteBuffer.allocate(sz);
		fc.read(bb);
		bb.flip();
		CharBuffer cb = csd.decode(bb);
		return cb.toString();
	}

	/**
	 * Load vector signature.
	 *
	 * @param fc
	 *            the fc
	 * @return the vector signature
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static DefaultVectorSignature loadVectorSignature(FileChannel fc) throws IOException {
		int type = loadInt(fc);
		switch (type) {
		case NULL_TYPE:
			return null;
		case DENSE_TYPE:
			return loadDenseVectorSignature(fc);
		case SPARSE_TYPE:
			return loadSparseVectorSignature(fc);
		}
		if (HOOKS_BY_TYPE.containsKey(type)) {
			return HOOKS_BY_TYPE.get(type).loadSignature(fc);
		}
		throw new IOException("Unknown VectorSignature type (" + type + ")");
	}

	public static void registerSignaturePersistenceHook(SignaturePersistenceHook hook) {
		HOOKS_BY_TYPE.put(hook.getTypeCode(), hook);
		HOOKS_BY_CLASS.put(hook.getSignatureClass(), hook);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy