/******************************************************************************* * Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University * as Operator of the SLAC National Accelerator Laboratory. * Copyright (c) 2011 Brookhaven National Laboratory. * EPICS archiver appliance is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. *******************************************************************************/ package org.epics.archiverappliance.utils.simulation; import java.util.Collections; import org.epics.archiverappliance.config.ArchDBRTypes; import org.epics.archiverappliance.data.SampleValue; import org.epics.archiverappliance.data.ScalarStringSampleValue; import org.epics.archiverappliance.data.ScalarValue; import org.epics.archiverappliance.data.VectorStringSampleValue; import org.epics.archiverappliance.data.VectorValue; /** * Generates a sine wave with a default period of one hour and a specifiable offset. * Used for data generation in the unit tests. * * @author mshankar * */ public class SineGenerator implements SimulationValueGenerator { private int phasediffindegress = 0; // By default, we let the simulation stream (or other containing stream) choose the number of samples it wants. private int numberofsamples = -1; public SineGenerator(int phasediffindegress) { this.phasediffindegress = phasediffindegress; } public SineGenerator(int phasediffindegress, int numberofsamples) { this.phasediffindegress = phasediffindegress; this.numberofsamples = numberofsamples; } @Override public int getNumberOfSamples(ArchDBRTypes type) { return numberofsamples; } private static final int NUM_COPIES = 10; @Override public SampleValue getSampleValue(ArchDBRTypes type, int secondsIntoYear) { // We want to fit 360 degrees into an hour (3600 seconds) so each second is 1/10th of a degree. double indegrees = secondsIntoYear/10.0 + phasediffindegress; double inradians = indegrees*Math.PI/180.0; double sineval = Math.sin(inradians); switch(type) { case DBR_SCALAR_STRING: return new ScalarStringSampleValue(Double.toString(sineval)); case DBR_SCALAR_SHORT: return new ScalarValue<Short>((short) (Short.MAX_VALUE*sineval)); case DBR_SCALAR_FLOAT: return new ScalarValue<Float>((float) sineval); case DBR_SCALAR_ENUM: return new ScalarValue<Short>((short) (Short.MAX_VALUE*sineval)); case DBR_SCALAR_BYTE: return new ScalarValue<Byte>((byte) (Byte.MAX_VALUE*sineval)); case DBR_SCALAR_INT: return new ScalarValue<Integer>((int) (Integer.MAX_VALUE*sineval)); case DBR_SCALAR_DOUBLE: return new ScalarValue<Double>(sineval); case DBR_WAVEFORM_STRING: return new VectorStringSampleValue(Collections.nCopies(NUM_COPIES, Double.toString(sineval))); case DBR_WAVEFORM_SHORT: return new VectorValue<Short>(Collections.nCopies(NUM_COPIES,(short) (Short.MAX_VALUE*sineval))); case DBR_WAVEFORM_FLOAT: return new VectorValue<Float>(Collections.nCopies(NUM_COPIES,(float) sineval)); case DBR_WAVEFORM_ENUM: return new VectorValue<Short>(Collections.nCopies(NUM_COPIES,(short) (Short.MAX_VALUE*sineval))); case DBR_WAVEFORM_BYTE: return new VectorValue<Byte>(Collections.nCopies(NUM_COPIES,(byte) (Byte.MAX_VALUE*sineval))); case DBR_WAVEFORM_INT: return new VectorValue<Integer>(Collections.nCopies(NUM_COPIES, (int) (Integer.MAX_VALUE*sineval))); case DBR_WAVEFORM_DOUBLE: return new VectorValue<Double>(Collections.nCopies(NUM_COPIES, sineval)); case DBR_V4_GENERIC_BYTES: return new ScalarStringSampleValue(Double.toString(sineval)); default: throw new UnsupportedOperationException("The sine generator does not support " + type.name()); } } }