Skip to content

Commit

Permalink
- Bug fix in the simulation when model can't be calculated for a cert…
Browse files Browse the repository at this point in the history
…ain date of the provided evaluation sample

- Improvements in Correlation Ball :
    - Zoom feature
    - Wheel can be rotated to ease label reading
    - Selection sync between the list of variables and the wheel
    - By default, the highest correlations are shown (representing 25% of total data)
  • Loading branch information
maggima committed Nov 18, 2015
1 parent 4bc3879 commit e472245
Show file tree
Hide file tree
Showing 11 changed files with 745 additions and 258 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#JDemetra+ Nowcasting plugin

_Current version of the plugin needs the latest development version of JDemetra+ (develop branch, not the 2.0.0 release)_

##Features
- Operationalize the nowcasting process
- Visual analysis of news and updates
- Real-time simulations

##Installation
In order to install the plugin, 2 nbm files have to be added to the JDemetra+ plugins :

- nbdemetra-core2-X.X.X.nbm
- nbdemetra-dfm-X.X.X.nbm

where X.X.X is the version of the compiled plugin
3 changes: 1 addition & 2 deletions jtss2/src/main/java/ec/tss/dfm/DfmSimulation.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ public boolean process(DfmDocument refdoc, Day[] ed, List<Day> estimationDays) {
Ts[] input = refdoc.getInput();

TsInformationSet info = new TsInformationSet(refdoc.getData());

descriptions.addAll(Arrays.asList(refdoc.getDfmResults().getDescriptions()));
for (MeasurementSpec ms : refdoc.getSpecification().getModelSpec().getMeasurements()) {
watched.add(ms.isWatched());
Expand Down Expand Up @@ -131,7 +130,7 @@ public boolean process(DfmDocument refdoc, Day[] ed, List<Day> estimationDays) {

if (doc.getResults() != null) {
Node n = doc.getResults().getNode(DfmProcessingFactory.FINALC);
if (n != null) {
if (n != null && n.results != null) {
SimulationResultsDocument rslts = new SimulationResultsDocument(n.results);
rslts.setSmoothedSeriesStdev(doc.getDfmResults() == null ? null : doc.getDfmResults().getSmoothedSeriesStdev());
rslts_.put(ed[i], rslts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,17 @@ protected Object doInBackground() throws Exception {
last.move(last.getFrequency().intValue());
Day horizon = last.lastday();
simulation = new DfmSimulation(horizon);

simulation.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(DfmSimulation.CALENDAR_RESULTS)) {
Day value = (Day)evt.getNewValue();
Day value = (Day) evt.getNewValue();
publish("Generating data of publication date : " + value.toString() + "...");
}
}
});

publish("Processing simulation of DFM...");
simulation.process(vdoc.getCurrent(), new ArrayList<>(Arrays.asList(vdoc.getCurrent().getSpecification().getSimulationSpec().getEstimationDays())));
Map<Day, SimulationResultsDocument> results = simulation.getResults();
Expand All @@ -248,7 +248,19 @@ public void propertyChange(PropertyChangeEvent evt) {
publish("Generating results of series #" + s);
TsDataTable tble = new TsDataTable();
for (int i = 0; i < cal.length; ++i) {
tble.insert(-1, results.get(cal[i]).getSimulationResults().getData("var" + (s + 1), TsData.class));
if (results.get(cal[i]) != null) {
if (results.get(cal[i]).getSimulationResults() != null) {
if (results.get(cal[i]).getSimulationResults().contains("var" + (s + 1))) {
tble.insert(-1, results.get(cal[i]).getSimulationResults().getData("var" + (s + 1), TsData.class));
} else {
System.out.println("Simulation results for calendar " + cal[i].toString() + " don't contain variable " + (s + 1));
}
} else {
System.out.println("No simulation results for calendar " + cal[i].toString() + " - Variable " + (s + 1));
}
} else {
System.out.println("No results for calendar " + cal[i].toString() + " - Variable " + (s + 1));
}
}
tble.insert(-1, info.series(s));

Expand Down Expand Up @@ -378,6 +390,13 @@ private DfmSimulationResults createFHTable(StringWriter writer, TsDataTable tabl
mapQoQ.put(diff, new Double[nbHeaders]);
}

// TsDataTableInfo dataInfo;
// try {
// dataInfo = table.getDataInfo(i, j);
// } catch (TsException ex) {
// dataInfo = null;
// }
// if (dataInfo != null && dataInfo == TsDataTableInfo.Valid) {
TsDataTableInfo dataInfo = table.getDataInfo(i, j);
if (dataInfo == TsDataTableInfo.Valid) {
Double current = table.getData(i, j);
Expand Down Expand Up @@ -572,7 +591,7 @@ private DfmSimulationResults createFHTable(StringWriter writer, TsDataTable tabl
r.setTrueValues(trueValues);
r.setTrueValuesYoY(trueValuesYoY);
r.setTrueValuesQoQ(trueValuesQoQ);

return r;
}

Expand Down Expand Up @@ -709,7 +728,7 @@ public void execute(DfmSimulationTopComponent c) throws Exception {
JOptionPane.showMessageDialog(null, "DFM processing must be done before the simulation !", "Error", JOptionPane.ERROR_MESSAGE);
return;
}

VersionedDfmDocument vd = c.getDocument().getElement();
List<MeasurementSpec> m = vd.getSpecification().getModelSpec().getMeasurements();
int count = 0;
Expand All @@ -720,12 +739,12 @@ public void execute(DfmSimulationTopComponent c) throws Exception {
}
i++;
}

if (count == 0) {
JOptionPane.showMessageDialog(null, "You must select at least one series for data generation !\nRight click on a series to enable/disable data generation.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}

chooser.setDialogTitle("Select the output folder");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,29 @@

import be.nbb.demetra.dfm.output.correlationball.CorrelationBall;
import static be.nbb.demetra.dfm.output.correlationball.CorrelationBall.COLOR_SCALE_PROPERTY;
import be.nbb.demetra.dfm.output.correlationball.CorrelationJList;
import com.google.common.base.Optional;
import ec.nbdemetra.ui.awt.PopupListener;
import ec.nbdemetra.ui.NbComponents;
import ec.tss.dfm.DfmResults;
import ec.tstoolkit.dfm.DynamicFactorModel;
import ec.tstoolkit.maths.matrices.Matrix;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
*
Expand All @@ -39,16 +50,18 @@ public class CorrelationBallView extends JPanel {

// Properties
public static final String DFM_RESULTS_PROPERTY = "dfmResults";

private Optional<DfmResults> results;
private CorrelationBall ball;

private List<String> titles;
private final CorrelationJList list;

public CorrelationBallView(Optional<DfmResults> r) {
setLayout(new BorderLayout());

this.results = r;
createBall();

addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Expand All @@ -59,33 +72,93 @@ public void propertyChange(PropertyChangeEvent evt) {
}
}
});


final JSlider slider = new JSlider(0, 360, 0);
slider.setBackground(Color.WHITE);
Dictionary<Integer, JComponent> dic = new Hashtable<>();
for (int i = 0; i <= 360; i = i + 30) {
dic.put(i, new JLabel(String.valueOf(i) + "°"));
}
slider.setLabelTable(dic);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setMajorTickSpacing(30);
slider.setMinorTickSpacing(5);
slider.setFocusable(false);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
ball.spin(source.getValue());
}
});

ball.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
switch (evt.getPropertyName()) {
case COLOR_SCALE_PROPERTY:
updateBall();
break;
case CorrelationBall.SPIN_ON_SELECTION_PROPERTY :
slider.setValue((int)((double)evt.getNewValue()));
break;
}
}
});

ball.addMouseListener(new PopupListener.PopupAdapter(ball.buildGridMenu().getPopupMenu()));

add(ball, BorderLayout.CENTER);

ball.setComponentPopupMenu(ball.buildGridMenu().getPopupMenu());
list = new CorrelationJList();

JScrollPane scrollPane = new JScrollPane(list,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(150, 500));
JSplitPane splitPane = NbComponents.newJSplitPane(JSplitPane.HORIZONTAL_SPLIT, ball, scrollPane);
splitPane.setResizeWeight(0.9);

enableSync();

add(slider, BorderLayout.SOUTH);
add(splitPane, BorderLayout.CENTER);

updateBall();
}


private void enableSync() {
PropertyChangeListener listener = new PropertyChangeListener() {
boolean updating = false;

@Override
public void propertyChange(PropertyChangeEvent evt) {
if (updating) {
return;
}

updating = true;
switch (evt.getPropertyName()) {
case CorrelationBall.INDEX_SELECTED_PROPERTY:
int index = (int) evt.getNewValue();
list.setSelectedItem(index);
break;
case CorrelationJList.SELECTED_ITEM_PROPERTY:
ball.setIndexSelected((int) evt.getNewValue());
break;
}
updating = false;
}
};

ball.addPropertyChangeListener(listener);
list.addPropertyChangeListener(listener);
}

private void createBall() {
ball = new CorrelationBall();
ball.setBackground(Color.WHITE);
ball.setForeground(Color.BLACK);
}

private List<String> titles;


private double[][] filterMatrix() {
List<Integer> indexes = new ArrayList<>();
titles = new ArrayList<>();
Expand All @@ -98,7 +171,7 @@ private double[][] filterMatrix() {
titles.add(rslts.getDescription(i).description);
}
}

double[][] result = new double[indexes.size()][indexes.size()];
for (int i = 0; i < indexes.size(); i++) {
for (int j = 0; j < indexes.size(); j++) {
Expand All @@ -107,24 +180,27 @@ private double[][] filterMatrix() {
}
return result;
}

public Optional<DfmResults> getDfmResults() {
return results;
}

public void setDfmResults(Optional<DfmResults> dfmResults) {
Optional<DfmResults> old = this.results;
this.results = dfmResults != null ? dfmResults : Optional.<DfmResults>absent();
firePropertyChange(DFM_RESULTS_PROPERTY, old, this.results);
}

private void updateBall() {
removeAll();
ball.removeAll();
if (results != null && results.isPresent()) {
double[][] matrix = filterMatrix();
ball.setMatrix(titles, matrix);
add(ball, BorderLayout.CENTER);

list.setListData(titles.toArray(new String[titles.size()]));
}
}




}
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
l.setForeground(table.getSelectionForeground());
}
} else if (value instanceof Double) {
DemetraUI demetraUI = DemetraUI.getInstance();
DemetraUI demetraUI = DemetraUI.getDefault();
Formatter<Number> format = demetraUI.getDataFormat().numberFormatter();
Number number = (Double) value;

Expand Down
Loading

0 comments on commit e472245

Please sign in to comment.