package math.functions;
import java.awt.Window;
import java.awt.event.ActionEvent;
import org.trianacode.taskgraph.Unit;
import triana.types.ComplexSampleSet;
import triana.types.ComplexSpectrum;
import triana.types.Const;
import triana.types.EmptyingType;
import triana.types.GraphType;
import triana.types.SampleSet;
import triana.types.Spectrum;
import triana.types.util.FlatArray;
/**
* A Sqrt unit to compute the square root of the elements of an input data array. The array can be real or complex. For
* complex data the root returned is in the upper half of the complex plane. For real data the positive root is
* returned.
* <p/>
* This Unit obeys the conventions of Triana Type 2 data types.
*
* @author Bernard Schutz
* @version 2.1 13 January 2001
*/
public class Sqrt extends Unit {
/**
* 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 "Forms the square root of the elements of the input data set";
}
/**
* ********************************************* ** USER CODE of Sqrt goes here ***
* *********************************************
*/
public void process() {
Object input, output;
output = null;
input = getInputAtNode(0);
if (input instanceof EmptyingType) {
return;
}
if (input instanceof SampleSet) {
if (FlatArray.minArray(((SampleSet) input).getData()) < 0) {
output = new ComplexSampleSet((SampleSet) input);
} else {
output = input;
}
} else if (input instanceof Spectrum) {
if (FlatArray.minArray(((Spectrum) input).getData()) < 0) {
output = new ComplexSpectrum((Spectrum) input);
} else {
output = input;
}
} else {
output = input;
}
Class outputClass = output.getClass();
//setOutputType(outputClass);
if (input instanceof GraphType) {
FlatArray tempR, tempI;
int dv, j;
double mag, phase;
double[] inputdataR, inputdataI;
for (dv = 0; dv < ((GraphType) input).getDependentVariables(); dv++) {
if (((GraphType) input).isArithmeticArray(dv)) {
tempR = new FlatArray(((GraphType) input).getDataArrayReal(dv));
inputdataR = (double[]) tempR.getFlatArray();
if (((GraphType) input).isDependentComplex(dv)) {
tempI = new FlatArray(((GraphType) input).getDataArrayImag(dv));
inputdataI = (double[]) tempI.getFlatArray();
for (j = 0; j < inputdataI.length; j++) {
mag = Math.sqrt(Math.sqrt(inputdataR[j] * inputdataR[j] + inputdataI[j] * inputdataI[j]));
phase = Math.atan2(inputdataI[j], inputdataR[j]) * 0.5;
if (phase < 0) {
phase += Math.PI;
}
inputdataR[j] = mag * Math.cos(phase);
inputdataI[j] = mag * Math.sin(phase);
}
((GraphType) output).setDataArrayReal(tempR.restoreArray(false), dv);
((GraphType) output).setDataArrayImag(tempI.restoreArray(false), dv);
} else {
if (FlatArray.minArray(inputdataR) >= 0) {
for (j = 0; j < inputdataR.length; j++) {
inputdataR[j] = Math.sqrt(inputdataR[j]);
}
((GraphType) output).setDataArrayReal(tempR.restoreArray(false), dv);
} else {
//setText("WARNING: SEE DEBUG WINDOW!");
System.out.println("Warning: Some input real data to " + getTask().getToolName()
+ " are out of range (data < 0). Output will be complex.");
inputdataI = new double[inputdataR.length];
for (j = 0; j < inputdataI.length; j++) {
mag = Math.sqrt(Math.abs(inputdataR[j]));
if (inputdataR[j] < 0) {
inputdataR[j] = 0.0;
inputdataI[j] = mag;
} else {
inputdataR[j] = mag;
inputdataI[j] = 0.0;
}
}
((GraphType) output).setDataArrayReal(tempR.restoreArray(false), dv);
tempR.setFlatArray(inputdataI);
((GraphType) output).setDataArrayImag(tempR.restoreArray(true), dv);
}
}
}
}
} else if (input instanceof Const) {
double r, i, mag, phase;
r = ((Const) input).getReal();
if (((Const) input).isComplex()) {
i = ((Const) input).getImag();
mag = Math.sqrt(Math.sqrt(r * r + i * i));
phase = Math.atan2(i, r);
if (phase < 0) {
phase += Math.PI;
}
r = mag * Math.cos(phase);
i = mag * Math.sin(phase);
((Const) output).setImag(i);
} else {
if (r >= 0) {
r = Math.sqrt(r);
} else {
//setText("WARNING: SEE DEBUG WINDOW!");
System.out.println("Warning: Input Const to " + getTask().getToolName() + " is real but out of range, (" + String.valueOf(r)
+ " < 0). Output will be a complex Const.");
r = 0.0;
i = Math.sqrt(Math.abs(r));
((Const) output).setImag(i);
}
}
((Const) output).setReal(r);
}
output(output);
}
/**
* Initialses information specific to Sqrt.
*/
public void init() {
super.init();
// 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);
}
/**
* Resets Sqrt
*/
public void reset() {
super.reset();
}
/**
* Saves Sqrt's parameters to the parameter file.
*/
public void saveParameters() {
}
/**
* Loads Sqrt's parameters of from the parameter file.
*/
public void setParameter(String name, String value) {
}
/**
* @return a string containing the names of the types allowed to be input to Sqrt, each separated by a white space.
*/
public String[] getInputTypes() {
return new String[]{"triana.types.GraphType", "triana.types.Const"};
}
public String[] getOutputTypes() {
return new String[]{"triana.types.GraphType", "triana.types.Const"};
}
/**
*
* @returns the location of the help file for this unit.
*/
public String getHelpFile() {
return "Sqrt.html";
}
/**
* @return Sqrt's parameter window sp that Triana can move and display it.
*/
public Window getParameterWindow() {
return null;
}
/**
* Captures the events thrown out by Sqrt.
*/
// public void actionPerformed(ActionEvent e) {
// super.actionPerformed(e); // we need this
//
// }
}