cz.cuni.mff.peckam.ais.statistics.IonogramStatistics.java Source code

Java tutorial

Introduction

Here is the source code for cz.cuni.mff.peckam.ais.statistics.IonogramStatistics.java

Source

/**
 * Copyright (c) 2013, Martin Pecka (peci1@seznam.cz)
 * All rights reserved.
 * Licensed under the following BSD License.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * Neither the name Martin Pecka nor the
 * names of contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package cz.cuni.mff.peckam.ais.statistics;

import java.awt.Point;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Locale;

import org.apache.commons.math3.util.FastMath;

import cz.cuni.mff.peckam.ais.AISLBLProductReader;
import cz.cuni.mff.peckam.ais.Ionogram;
import cz.cuni.mff.peckam.ais.result.FrameType;
import cz.cuni.mff.peckam.ais.result.PointType;

/**
 * Various ionogram statistics.
 * 
 * @author Martin Pecka
 */
public class IonogramStatistics {

    /**  */
    private final BufferedWriter meanWriter;
    /**  */
    private final BufferedWriter sdWriter;
    /**  */
    private final BufferedWriter maxWriter;
    /**  */
    private final BufferedWriter featuresWriter;
    /**  */
    private final BufferedWriter traceWriter;

    /**  */
    private final AISLBLProductReader reader = new AISLBLProductReader();

    /**
     * @param meanWriter mean
     * @param sdWriter std. dev
     * @param maxWriter max values
     * @param featuresWriter features
     * @param traceWriter trace points values
     */
    public IonogramStatistics(BufferedWriter meanWriter, BufferedWriter sdWriter, BufferedWriter maxWriter,
            BufferedWriter featuresWriter, BufferedWriter traceWriter) {
        this.meanWriter = meanWriter;
        this.sdWriter = sdWriter;
        this.maxWriter = maxWriter;
        this.featuresWriter = featuresWriter;
        this.traceWriter = traceWriter;
    }

    /**  */
    private static float min = Float.MAX_VALUE;

    /**
     * Compute the stats.
     * 
     * @param lblFile The .LBL file with orbit data.
     * @throws IOException On IO exception.
     */
    public void execute(File lblFile) throws IOException {
        final Ionogram[] ionograms = reader.readFile(lblFile);
        int i = -1;
        for (Ionogram iono : ionograms) {
            i++;
            System.out.println("Orbit " + iono.getOrbitNumber() + " frame " + i);
            final Float[][] data = iono.getData();
            final int numItems = iono.getWidth() * iono.getHeight();
            float sum = 0, max = 0;
            for (int x = 0; x < data.length; x++) {
                for (int y = 0; y < data[0].length; y++) {
                    sum += data[x][y];
                    if (data[x][y] > max)
                        max = data[x][y];
                    if (data[x][y] < min)
                        min = data[x][y];
                }
            }
            final float mean = sum / numItems;

            float sdSum = 0;
            for (int x = 0; x < data.length; x++) {
                for (int y = 0; y < data[0].length; y++) {
                    sdSum += FastMath.pow(data[x][y] - mean, 2);
                    if (data[x][y] > max)
                        max = data[x][y];
                }
            }
            final float sd = (float) FastMath.sqrt(sdSum / numItems);

            if (iono.getReferenceDetectionResult() == null) {
                System.err.println("No result data for orbit " + iono.getOrbitNumber() + " frame " + i);
                continue;
            }

            final FrameType result = iono.getReferenceDetectionResult();

            if (result.getHperiod() == null && result.getVperiod() == null && result.getIonospheretrace() == null
                    && result.getIonospheretrace() == null)
                continue;

            final Float hp = result.getHperiod() != null && result.getHperiod() > 0 ? result.getHperiod() : null;
            final Float vp = result.getVperiod() != null && result.getVperiod() > 0 ? result.getVperiod() : null;
            final List<PointType> gp = result.getGroundtrace() != null
                    && result.getGroundtrace().getPoints().size() > 0 ? result.getGroundtrace().getPoints() : null;
            final List<PointType> ip = result.getIonospheretrace() != null
                    && result.getIonospheretrace().getPoints().size() > 0 ? result.getIonospheretrace().getPoints()
                            : null;

            final boolean hasFeatures = hp != null || vp != null || gp != null || ip != null;

            meanWriter.write(format(mean) + " " + (hasFeatures ? 1 : 0));
            meanWriter.newLine();

            sdWriter.write(format(sd) + " " + (hasFeatures ? 1 : 0));
            sdWriter.newLine();

            maxWriter.write(format(max) + " " + (hasFeatures ? 1 : 0));
            maxWriter.newLine();

            if (ip != null)
                writeTracePoints(result.getIonospheretrace().getPoints(), iono, "iono");
            if (gp != null)
                writeTracePoints(result.getGroundtrace().getPoints(), iono, "ground");

            final int w = iono.getWidth(), h = iono.getHeight();
            for (int x = 0; x < data.length; x++) {
                for (int y = 0; y < data[0].length; y++) {
                    final float val = data[x][y];
                    if (val > 1E-12) {
                        final PointType pos = iono.getFreqTimePosition(x, y);
                        final float posX = pos.getX();
                        final float posY = pos.getY();

                        if (hp != null && y < h / 2 && FastMath.abs(Math.round(posX / hp) * hp - posX) < 0.03) {
                            featuresWriter.write(iono.getOrbitNumber() + ":" + i + " " + format(val) + "\thPeriod");
                            featuresWriter.newLine();
                        } else if (vp != null && x < w / 2
                                && FastMath.abs(Math.round(posY / vp) * vp - posY) < 0.1) {
                            featuresWriter.write(iono.getOrbitNumber() + ":" + i + " " + format(val) + "\tvPeriod");
                            featuresWriter.newLine();
                        } else if (gp != null && findInTrace(pos, gp)) {
                            featuresWriter
                                    .write(iono.getOrbitNumber() + ":" + i + " " + format(val) + "\tgroundtrace");
                            featuresWriter.newLine();
                        } else if (ip != null && findInTrace(pos, ip)) {
                            featuresWriter.write(
                                    iono.getOrbitNumber() + ":" + i + " " + format(val) + "\tionospheretrace");
                            featuresWriter.newLine();
                        } else {
                            featuresWriter
                                    .write(iono.getOrbitNumber() + ":" + i + " " + format(val) + "\tnoFeature");
                            featuresWriter.newLine();
                        }
                    }
                }
            }
        }
    }

    /**
     * Return true if the given point is near a point in the given trace.
     * 
     * @param pos The point.
     * @param trace The trace.
     * @return Return true if the given point is near a point in the given trace.
     */
    private boolean findInTrace(PointType pos, List<PointType> trace) {
        for (PointType point : trace) {
            if (FastMath.abs(pos.getX() - point.getX()) < 0.001 && FastMath.abs(pos.getY() - point.getY()) < 0.01)
                return true;
        }
        return false;
    }

    /**
     * Write trace point values.
     * 
     * @param points The points
     * @param iono The ionogram.
     * @param tag Tag to add to the resulting file.
     * @throws IOException On IO error.
     */
    private void writeTracePoints(List<PointType> points, Ionogram iono, String tag) throws IOException {
        final Float[][] data = iono.getData();
        for (PointType p : points) {
            final Point coords = iono.getDataPosition(p.getY(), p.getX());
            float val = 0;
            for (int i = 0; i <= 6 && coords.y + i < data[0].length; i++) {
                if (data[coords.x][coords.y + i] > val)
                    val = data[coords.x][coords.y + i];
            }

            if (val > 0) {
                traceWriter.write(
                        iono.getOrbitNumber() + ":" + iono.getPositionInSeries() + " " + format(val) + "\t" + tag);
                traceWriter.newLine();
            }
        }
    }

    /**
     * Convert the float to string.
     * 
     * @param f The float.
     * @return The string.
     */
    private static String format(float f) {
        return String.format(Locale.ENGLISH, "%.25f", f);
    }

    /**
     * @param args 0 => Orbit base dir, 1 => min orbit, 2 => max orbit
     * @throws IOException On IO error.
     */
    public static void main(String[] args) throws IOException {
        final File orbitDir = new File(args[0]);
        final int minOrbit = Integer.parseInt(args[1]);
        final int maxOrbit = Integer.parseInt(args[2]);

        try (final BufferedWriter meanWriter = new BufferedWriter(new FileWriter("mean"));
                final BufferedWriter sdWriter = new BufferedWriter(new FileWriter("sd"));
                final BufferedWriter maxWriter = new BufferedWriter(new FileWriter("max"));
                final BufferedWriter featuresWriter = new BufferedWriter(new FileWriter("features"));
                final BufferedWriter traceWriter = new BufferedWriter(new FileWriter("trace"))) {
            final IonogramStatistics stats = new IonogramStatistics(meanWriter, sdWriter, maxWriter, featuresWriter,
                    traceWriter);

            for (int i = minOrbit; i <= maxOrbit; i++) {
                final File orbitFile = new File(orbitDir,
                        (i + "").replaceAll(".$", "X") + File.separator + "FRM_AIS_RDR_" + i + ".LBL");
                if (orbitFile.exists()) {
                    stats.execute(orbitFile);
                }
            }
        }
        System.out.println("Minimal value: " + min);
    }

}