package de.tud.inf.operator.fingerprints.gsc; import java.util.Iterator; import java.util.List; import JSci.maths.wavelet.FWTCoef; import JSci.maths.wavelet.Filter; import JSci.maths.wavelet.Signal; import JSci.maths.wavelet.haar.MultiSplineHaar; import com.rapidminer.example.Attribute; import com.rapidminer.example.Attributes; import com.rapidminer.example.Example; import com.rapidminer.example.ExampleSet; import com.rapidminer.example.table.AttributeFactory; import com.rapidminer.operator.IOObject; import com.rapidminer.operator.Operator; import com.rapidminer.operator.OperatorDescription; import com.rapidminer.operator.OperatorException; import com.rapidminer.parameter.ParameterType; import com.rapidminer.parameter.ParameterTypeCategory; import com.rapidminer.parameter.ParameterTypeInt; import com.rapidminer.parameter.conditions.EqualTypeCondition; import com.rapidminer.tools.Ontology; import de.tud.inf.example.set.ComplexExampleSet; import de.tud.inf.example.set.attributevalues.MapValue; import de.tud.inf.example.table.ConstantArrayAttribute; import de.tud.inf.example.table.MapAttribute; public class GlobalSlopeChange extends Operator{ /* * The number of beams */ public static String PARAMETER_NUM_OF_BEAMS = "number of beams"; /* * The way how the Global Slope Change will be determined */ public static String[] CATEGORIES = { "asc", "wavelet" }; /* * The category of the gsc */ public static String PARAMETER_CATEGORY = "category"; /* * The number of samples per beam */ public static String PARAMETER_SAMPLE_SIZE = "sample size"; /* * The level of the detail coefficient */ public static String PARAMETER_DETAIL_LEVEL = "detail level"; /* * The type of wavelet */ public static String PARAMETER_WAVELET_TYPE = "wavlet type"; /* * The available wavelet types */ public static String[] WAVELET_TYPES = { "Haar Wavelet" }; public GlobalSlopeChange(OperatorDescription description) { super(description); } public IOObject[] apply() throws OperatorException { /** * The ExampleSet must have a MapAttribute */ // get the map Attribute ComplexExampleSet input = getInput(ComplexExampleSet.class); Attributes attr = input.getAttributes(); Attribute mapAttr = null; Iterator<Attribute> iter = attr.allAttributes(); for(Attribute a : attr) { if(a instanceof MapAttribute) { mapAttr = a; break; } } if(mapAttr == null) { // throw a user error } // add new Attribute Attribute valueAttribute = AttributeFactory.createAttribute("Values", Ontology.NOMINAL); input.getExampleTable().addAttribute(valueAttribute); input = input.getExampleTable().createExampleSet(); int numberOfBeams = this.getParameterAsInt(PARAMETER_NUM_OF_BEAMS); int detailLevel = -1; int maxDetaiLevel = -1; int numberOfCoefficients = 0; Filter wavelet = null; int sampleSize = getParameterAsInt(PARAMETER_SAMPLE_SIZE); int gscCategory = getParameterAsInt(PARAMETER_CATEGORY); // add new ComplexAttribute for the fingerprint String hint = Integer.toString(numberOfBeams) + "_"; switch(gscCategory) { case 0: hint += "1"; break; case 1: detailLevel = getParameterAsInt(PARAMETER_DETAIL_LEVEL); maxDetaiLevel = (int)Math.round((Math.log(sampleSize)/Math.log(2))); if(detailLevel > maxDetaiLevel) throw new OperatorException("detail level not feasible"); if(getParameterAsInt(PARAMETER_WAVELET_TYPE) == 0) wavelet = new MultiSplineHaar(); numberOfCoefficients = (int)Math.pow(2, detailLevel); hint += Integer.toString(numberOfCoefficients); break; default: hint += "1"; } ConstantArrayAttribute fingerprint = (ConstantArrayAttribute)AttributeFactory.createAttribute("fingerprint", Ontology.ARRAY,hint); input.addComplexAttribute(fingerprint); // process every map in the Example Set for(Example e : input) { MapValue map = e.getMapValue(mapAttr); int[] dimensions = map.getDimension(); // calculate the center of the beams double[] center = new double[2]; for(int i = 0;i<dimensions.length;i++) { center[i] = Math.round((double)dimensions[i]/2); } // determine the start and endpoint of each beam // start point is always the center double[] startX = new double[numberOfBeams]; double[] endX = new double[numberOfBeams]; double[] startY = new double[numberOfBeams]; double[] endY = new double[numberOfBeams]; for(int i = 0;i<numberOfBeams;i++) { startX[i] = center[0]; startY[i] = center[1]; } if(numberOfBeams == 4) { endX = new double[]{1,center[0],dimensions[0],center[0]}; endY = new double[]{center[1],dimensions[1],center[1],1}; } else { endX[0] =endY[0] = 1; int beamIndex = 1; int j; for(;beamIndex<numberOfBeams/4+1;beamIndex++) { endX[beamIndex] = 1; endY[beamIndex] = Math.round(beamIndex*((double)dimensions[1] / (numberOfBeams/4))); } for(j = 0;j< numberOfBeams/4;j++) { endX[beamIndex+j] = Math.round((j+1)*((double)dimensions[0] / (numberOfBeams/4))); endY[beamIndex+j] = dimensions[1]; } beamIndex += j; for(j = 0;j<numberOfBeams/4-1;j++) { endX[beamIndex+j] = dimensions[0]; endY[beamIndex+j] = Math.round(((numberOfBeams/4-1)-j)*((double)dimensions[1]/(numberOfBeams/4))); } beamIndex += j; for(j=0;j<numberOfBeams/4;j++) { endX[beamIndex+j] = Math.round((numberOfBeams/4-j)*((double)dimensions[0]/(numberOfBeams/4))); endY[beamIndex+j] = 1; } } int category = getParameterAsInt(PARAMETER_CATEGORY); double[] xvalues = new double[sampleSize]; double[] yvalues = new double[sampleSize]; double[] zvalues; double[][] slopes = new double[numberOfBeams][sampleSize]; for(int k = 0;k<numberOfBeams;k++) { int numVals; zvalues = new double[sampleSize]; double xStart = startX[k]; double yStart = startY[k]; double endBeamX = endX[k]; double endBeamY = endY[k]; double xDiff = Math.abs(xStart - endBeamX); double yDiff = Math.abs(yStart - endBeamY); double incX; double incY; int xStepSize = endBeamX - xStart >= 0 ? 1 : -1; int yStepSize = endBeamY - yStart >= 0 ? 1 : -1; if(xDiff == 0) { incY = yStepSize*yDiff/(sampleSize-1); for(int m = 0;m<sampleSize-1;m++) { xvalues[m] = xStart; yvalues[m] = yStart + m*incY; zvalues[m] = map.getValueAtId(xvalues[m]-1, yvalues[m]-1); } } else { if(yDiff == 0) { incX = xStepSize*xDiff/(sampleSize-1); for(int m = 0;m<sampleSize-1;m++) { xvalues[m] = xStart + m*incX; yvalues[m] = yStart; zvalues[m] = map.getValueAtId(xvalues[m]-1, yvalues[m]-1); } } else { double alpha = Math.atan(yDiff/xDiff); incX = xStepSize*Math.cos(alpha)*(Math.sqrt((xDiff*xDiff) + (yDiff*yDiff))/(sampleSize-1)); incY = yStepSize*Math.sin(alpha)*(Math.sqrt((xDiff*xDiff) + (yDiff*yDiff))/(sampleSize-1)); for(int m = 0;m<sampleSize-1;m++) { xvalues[m] = xStart+m*incX; yvalues[m] = yStart+m*incY; zvalues[m] = map.getValueAtId(xvalues[m]-1, yvalues[m]-1); } } } xvalues[sampleSize-1] = endBeamX; yvalues[sampleSize-1] = endBeamY; zvalues[sampleSize-1] = map.getValueAtId(xvalues[sampleSize-1]-1, yvalues[sampleSize-1]-1); // try { // // BufferedWriter out = new BufferedWriter(new FileWriter(new File("/media/drive/Studium/SHK/gsc/rapid/beams.csv"),true)); // // for(int x = 0;x<xvalues.length;x++) { // out.write(String.valueOf(xvalues[x]) + ","); // out.write(String.valueOf(yvalues[x])); // out.newLine(); // // } // out.close(); // // } catch (IOException e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } slopes[k] = zvalues; //slopeList[k] = (double)Math.round(slopeList[k]*10000)/10000; } // create fingerprint attribute value // ConstantArrayValue val = new ConstantArrayValue(slopeList.length, 1); // val.setValues(slopeList); // e.setComplexValue(fingerprint, val); double[][] slope = null; switch(gscCategory) { case 0: // asc slope = new double[slopes.length][1]; for(int i = 0;i<slopes.length;i++) { double slopesList[] = new double[sampleSize/2]; int slopeindex = 0; for(int m=1;m<xvalues.length;m +=2) { //slopes[slopeindex] = map.getValueAtId(xvalues[m]-1, yvalues[m]-1) - map.getValueAtId(xvalues[m-1]-1,yvalues[m-1]-1); slopesList[slopeindex] = slopes[i][m]-slopes[i][m-1]; slopeindex++; } for(int m=0;m<slopesList.length;m++) { slope[i][0] += slopesList[m]; } slope[i][0] /= slopesList.length; } //slopeList[k] = new double[1]; break; case 1: // wavelet slope = new double[slopes.length][numberOfCoefficients]; for(int i = 0;i<slopes.length;i++) { Signal s = new Signal(slopes[i]); s.setFilter(wavelet); FWTCoef coeff = s.fwt(maxDetaiLevel - detailLevel); slope[i] = coeff.getCoefs()[maxDetaiLevel - detailLevel]; } } String slopeString = ""; for(double[] sl : slope) { for(double s : sl) slopeString += (double)Math.round(s*10000)/10000 + ":"; slopeString += "#"; } e.setValue(valueAttribute, slopeString); } return new IOObject[]{input.getExampleTable().createExampleSet()}; } public Class<?>[] getInputClasses() { return new Class[]{ExampleSet.class}; } public Class<?>[] getOutputClasses() { return new Class[]{ExampleSet.class}; } public List<ParameterType> getParameterTypes() { List<ParameterType> types = super.getParameterTypes(); ParameterType type; type = new ParameterTypeInt(PARAMETER_NUM_OF_BEAMS, "The number of beams", 4, 16); type.setExpert(false); types.add(type); type = new ParameterTypeCategory(PARAMETER_CATEGORY, "The way how the gsc will be determined", CATEGORIES, 0); type.setExpert(false); types.add(type); type = new ParameterTypeCategory(PARAMETER_WAVELET_TYPE, "The type of wavelet", WAVELET_TYPES, 0); type.registerDependencyCondition(new EqualTypeCondition(this, PARAMETER_CATEGORY, true, 1)); type.setExpert(false); types.add(type); type = new ParameterTypeInt(PARAMETER_DETAIL_LEVEL, "The level of the detail coefficient", 0, Integer.MAX_VALUE, 1); type.setExpert(false); type.registerDependencyCondition(new EqualTypeCondition(this, PARAMETER_CATEGORY, true, 1)); types.add(type); type = new ParameterTypeInt(PARAMETER_SAMPLE_SIZE, "The number of samples pro beam", 1, Integer.MAX_VALUE); type.setExpert(false); types.add(type); return types; } }