org.pf.midea.SimulationController.java Source code

Java tutorial

Introduction

Here is the source code for org.pf.midea.SimulationController.java

Source

/*
 * Copyright (C) 2009-2013 Oleksandr Natalenko aka post-factum
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the Universal Program License as published by
 * Oleksandr Natalenko aka post-factum; see file COPYING for details.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the Universal Program
 * License along with this program; if not, write to
 * oleksandr@natalenko.name
 */

package org.pf.midea;

import com.jgoodies.forms.layout.CellConstraints;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.axis.LogAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleEdge;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class SimulationController implements Runnable {
    private PlanCell[] planCells;
    private double hSquareLow, hSquareHigh, hSquareStep;
    private int iterationsCount;
    private boolean dBs;
    private JProgressBar progressBar;
    private JPanel chartPanel;
    private JTextArea textAreaNumeric;
    private boolean showLineNumbers;

    public SimulationController(ArrayList<PlanCell> _planCells, JSpinner _spinnerHSquareLow,
            JSpinner _spinnerHSquareHigh, JSpinner _spinnerHSquareStep, JSpinner _spinnerIterations, boolean _dBs,
            JProgressBar _progressBar, JPanel _chartPanel, JTextArea _textAreaNumeric, boolean _showLineNumbers) {
        planCells = _planCells.toArray(new PlanCell[_planCells.size()]);
        hSquareLow = (Double) _spinnerHSquareLow.getValue();
        hSquareHigh = (Double) _spinnerHSquareHigh.getValue();
        hSquareStep = (Double) _spinnerHSquareStep.getValue();
        iterationsCount = (Integer) _spinnerIterations.getValue();
        dBs = _dBs;
        progressBar = _progressBar;
        chartPanel = _chartPanel;
        textAreaNumeric = _textAreaNumeric;
        showLineNumbers = _showLineNumbers;
    }

    @Override
    public void run() {
        textAreaNumeric.setText("");
        XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
        double progress = 0;
        double progressStep = 100.0 / (planCells.length * (hSquareHigh - hSquareLow + hSquareStep) / hSquareStep);
        progressBar.setValue(0);
        for (int i = 0; i < planCells.length; i++) {
            XYSeries xySeries;
            if (showLineNumbers)
                xySeries = new XYSeries(String.valueOf(i + 1) + ") " + planCells[i].getShortDescription());
            else
                xySeries = new XYSeries(planCells[i].getShortDescription());
            textAreaNumeric.append(planCells[i].getDescription() + "\n");
            textAreaNumeric.setCaretPosition(textAreaNumeric.getDocument().getLength());

            PlanStates.SourceType currentSourceType = planCells[i].getSourceCell().getSourceType();
            PlanStates.CodeType currentCodeType = planCells[i].getCodeCell().getCodeType();
            PlanStates.ModulationType currentModulationType = planCells[i].getModulationCell().getModulationType();
            PlanStates.ChannelType currentChannelType = planCells[i].getChannelCell().getChannelType();
            PlanStates.ErrorsType currentErrorsType = planCells[i].getErrorsCell().getErrorsType();

            BinaryNumber[] sourcePoints = null;
            switch (currentSourceType) {
            case ST_TEST:
                sourcePoints = ConstellationPointsGenerator.getTestPoints(currentModulationType, iterationsCount);
                break;
            case ST_RANDOM:
                sourcePoints = ConstellationPointsGenerator.getRandomPoints(currentModulationType, iterationsCount);
                break;
            }

            Coder coder = null;
            Decoder decoder = null;
            switch (currentCodeType) {
            case CT_NONE:
                coder = new CoderNone();
                decoder = new DecoderNone();
                break;
            case CT_HAMMING74:
                coder = new CoderHamming74();
                decoder = new DecoderHamming74();
                break;
            case CT_CYCLIC:
                coder = new CoderCyclic85();
                decoder = new DecoderCyclic85();
                break;
            case CT_BCH155:
                coder = new CoderBCH155();
                decoder = new DecoderBCH155();
                break;
            }

            Modulator modulator = null;
            Demodulator demodulator = null;
            switch (currentModulationType) {
            case MT_ASK:
                modulator = new ModulatorASK();
                demodulator = new DemodulatorASK();
                break;
            case MT_FSK:
                modulator = new ModulatorFSK();
                demodulator = new DemodulatorFSK();
                break;
            case MT_BPSK:
                modulator = new ModulatorBPSK();
                demodulator = new DemodulatorBPSK();
                break;
            case MT_QPSK:
                modulator = new ModulatorQPSK();
                demodulator = new DemodulatorQPSK();
                break;
            case MT_8PSK:
                modulator = new Modulator8PSK();
                demodulator = new Demodulator8PSK();
                break;
            case MT_16PSK:
                modulator = new Modulator16PSK();
                demodulator = new Demodulator16PSK();
                break;
            case MT_32PSK:
                modulator = new Modulator32PSK();
                demodulator = new Demodulator32PSK();
                break;
            case MT_16QAM:
                modulator = new Modulator16QAM();
                demodulator = new Demodulator16QAM();
                break;
            case MT_32QAM:
                modulator = new Modulator32QAM();
                demodulator = new Demodulator32QAM();
                break;
            case MT_64QAM:
                modulator = new Modulator64QAM();
                demodulator = new Demodulator64QAM();
                break;
            case MT_256QAM:
                modulator = new Modulator256QAM();
                demodulator = new Demodulator256QAM();
                break;
            }

            Channel channel = null;
            switch (currentChannelType) {
            case CHT_AWGN:
                channel = new ChannelAWGN();
                break;
            case CHT_RAYLEIGH:
                channel = new ChannelRayleigh();
                break;
            }

            BinaryNumber[] encoded = coder.encode(sourcePoints);
            Signal[] modulated = modulator.modulate(encoded);

            double error = 0;

            for (double h = hSquareLow; h <= hSquareHigh; h += hSquareStep) {
                double realH;
                if (dBs)
                    realH = StatisticsTools.decibelsToTimes(h);
                else
                    realH = h;

                Signal[] noised = channel.noise(realH, modulated);
                BinaryNumber[] demodulated = demodulator.demodulate(noised);
                noised = null;
                System.gc();
                BinaryNumber[] decoded = decoder.decode(demodulated);
                demodulated = null;
                System.gc();
                switch (currentErrorsType) {
                case ET_SER:
                    error = StatisticsTools.getSER(sourcePoints, decoded);
                    break;
                case ET_BER:
                    error = StatisticsTools.getBER(sourcePoints, decoded);
                    break;
                }
                decoded = null;
                System.gc();

                if (error > 0) {
                    xySeries.add(h, error);
                    textAreaNumeric.append(String.valueOf(h) + "\t" + String.valueOf(error) + "\n");
                    textAreaNumeric.setCaretPosition(textAreaNumeric.getDocument().getLength());
                }

                progress += progressStep;
                progressBar.setValue((int) Math.round(progress));
            }
            xySeriesCollection.addSeries(xySeries);
            textAreaNumeric.append("\n");
            textAreaNumeric.setCaretPosition(textAreaNumeric.getDocument().getLength());
        }

        JFreeChart chart = ChartFactory.createXYLineChart("", dBs ? "" : "", "?",
                xySeriesCollection, PlotOrientation.VERTICAL, true, true, false);
        chart.getLegend().setPosition(RectangleEdge.RIGHT);
        XYPlot xyPlot = chart.getXYPlot();

        for (int i = 0; i < planCells.length; i++) {
            xyPlot.getRenderer().setSeriesStroke(i, new BasicStroke(planCells[i].getLineWidth()));
            if (planCells[i].getLineColor() != null)
                xyPlot.getRenderer().setSeriesPaint(i, planCells[i].getLineColor());

            if (showLineNumbers) {
                XYSeries currentSeries = xySeriesCollection.getSeries(i);
                double annotationY = currentSeries.getY(0).doubleValue();
                double annotationX = currentSeries.getX(0).doubleValue();
                for (int j = 1; j < currentSeries.getItemCount(); j++)
                    if (currentSeries.getY(j).doubleValue() == 0) {
                        annotationY = currentSeries.getY(j - 1).doubleValue();
                        annotationX = currentSeries.getX(j - 1).doubleValue();
                        break;
                    } else {
                        annotationY = currentSeries.getY(j).doubleValue();
                        annotationX = currentSeries.getX(j).doubleValue();
                    }
                XYTextAnnotation annotation = new XYTextAnnotation(String.valueOf(i + 1), annotationX, annotationY);
                annotation.setBackgroundPaint(Color.WHITE);
                annotation.setFont(new Font("Dialog", 0, 14));
                xyPlot.addAnnotation(annotation);
            }
        }

        xyPlot.setBackgroundPaint(Color.WHITE);
        xyPlot.setDomainGridlinePaint(Color.GRAY);
        xyPlot.setRangeGridlinePaint(Color.GRAY);
        NumberAxis domainAxis = new NumberAxis("h, " + (dBs ? "" : ""));
        LogAxis rangeAxis = new LogAxis("?");
        rangeAxis.setNumberFormatOverride(new HumanNumberFormat(1));
        domainAxis.setTickLabelFont(new Font("Dialog", 0, 14));
        rangeAxis.setTickLabelFont(new Font("Dialog", 0, 14));
        xyPlot.setDomainAxis(domainAxis);
        xyPlot.setRangeAxis(rangeAxis);

        ChartPanel nestedPanel = new ChartPanel(chart);
        chartPanel.removeAll();
        chartPanel.add(nestedPanel, new CellConstraints());
        chartPanel.updateUI();
    }
}