package math.functions; import java.awt.Window; import java.awt.event.ActionEvent; import org.trianacode.gui.windows.ScrollerWindow; import org.trianacode.taskgraph.Unit; import triana.types.EmptyingType; import triana.types.Histogram; import triana.types.SampleSet; import triana.types.Spectrum; import triana.types.VectorType; import triana.types.util.Str; /** * A ATanCont unit to find the angle of a vector (or complex number) from two input sequences that represent the x and y * components of the vector, attempting to resolve ambiguities about the multiple of 2 Pi in the angle by maintaining * continuity. * * @author B.F. Schutz * @version 1.0 alpha 04 Oct 1997 */ public class ATanCont extends Unit { /** * The UnitWindow for ATanCont */ ScrollerWindow myWindow; /** * Initial angle parameter */ double phase = 0.0; /** * A useful constant */ double TwoPi = 2.0 * Math.PI; /** * This returns a <b>brief!</b> description of what the unit does. The text here is shown in a pop up window when * the user puts the mouse over the unit icon for more than a second. */ public String getPopUpDescription() { return "Finds the angle of a vector (or complex number) from two input sequences"; } /** * ********************************************* ** USER CODE of ATanCont goes here *** * ********************************************* */ public void process() { Object input, input2; double[] inputdataX = {0.0}; double[] inputdataY = {0.0}; input = getInputAtNode(0); if (input instanceof EmptyingType) { return; } Class inputClass = input.getClass(); //setOutputType(inputClass); input2 = getInputAtNode(1); if (input instanceof VectorType) { inputdataX = ((VectorType) input).getData(); inputdataY = ((VectorType) input2).getData(); } else if (input instanceof SampleSet) { inputdataX = ((SampleSet) input).data; inputdataY = ((SampleSet) input2).data; } else if (input instanceof Spectrum) { inputdataX = ((Spectrum) input).data; inputdataY = ((Spectrum) input2).data; } else if (input instanceof Histogram) { inputdataX = ((Histogram) input).data; inputdataY = ((Histogram) input2).data; } int sizeOfData = inputdataX.length; double[] outputdata = inputdataX; // IT, for effieciency new double[sizeOfData]; double lastAngle = Math.atan2(inputdataX[0], inputdataY[0]); double thisAngle, diffAngle; double jump = phase; for (int i = 1; i < sizeOfData; i++) { thisAngle = Math.atan2(inputdataX[i], inputdataY[i]); diffAngle = thisAngle - lastAngle; if (diffAngle > Math.PI) { jump = jump - TwoPi; } else if (diffAngle < -Math.PI) { jump = jump + TwoPi; } outputdata[i] = thisAngle + jump; lastAngle = thisAngle; } if (input instanceof VectorType) { VectorType output = new VectorType(outputdata); output(output); } else if (input instanceof SampleSet) { SampleSet output = new SampleSet( ((SampleSet) input).samplingFrequency(), outputdata); output(output); } else if (input instanceof Spectrum) { Spectrum output = new Spectrum( ((Spectrum) input).samplingFrequency(), outputdata); output(output); } else if (input instanceof Histogram) { Histogram output = new Histogram( ((Histogram) input).binLabel, ((Histogram) input).hLabel, ((Histogram) input).delimiters, outputdata); output(output); } } /** * Initialses information specific to ATanCont. */ public void init() { super.init(); // changeInputNodes(2); // setResizableInputs(false); // setResizableOutputs(true); // // This is to ensure that we receive arrays containing double-precision numbers // setRequireDoubleInputs(true); // setCanProcessDoubleArrays(true); setDefaultInputNodes(1); setMinimumInputNodes(1); setMaximumInputNodes(Integer.MAX_VALUE); setDefaultOutputNodes(1); setMinimumOutputNodes(1); setMaximumOutputNodes(Integer.MAX_VALUE); myWindow = new ScrollerWindow(this, "Initial angle in radians added to output"); myWindow.setValues(0.0, 2.0 * Math.PI, phase); } /** * Reset's ATanCont */ public void reset() { super.reset(); } /** * Saves ATanCont's parameters to the parameter file. */ // public void saveParameters() { // saveParameter("phase", phase); // } /** * Loads ATanCont's parameters of from the parameter file. */ public void setParameter(String name, String value) { phase = Str.strToDouble(value); } public String[] getInputTypes() { return new String[]{"triana.types.VectorType", "triana.types.SampleSet", "triana.types.Spectrum", "triana.types.Histogram"}; } public String[] getOutputTypes() { return new String[]{"triana.types.VectorType", "triana.types.SampleSet", "triana.types.Spectrum", "triana.types.Histogram"}; } /** * * @returns the location of the help file for this unit. */ public String getHelpFile() { return "ATanCont.html"; } /** * @return ATanCont's parameter window sp that Triana can move and display it. */ public Window getParameterWindow() { return myWindow; } /** * Captures the events thrown out by ATanCont. */ // public void actionPerformed(ActionEvent e) { // super.actionPerformed(e); // we need this // // //if (e.getSource() == myWindow.slider) { // // phase = myWindow.getValue(); // // } // } }