Skip to content

Commit f8e681e

Browse files
committed
Add RPI plot type
Add a simple plot of depth vs. RPI.
1 parent a06e313 commit f8e681e

10 files changed

+182
-12
lines changed

src/net/talvi/puffinplot/PuffinApp.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ public class PuffinApp {
151151
private SuiteCalcs multiSuiteCalcs;
152152
private ScriptEngine pythonEngine = null;
153153
private final Version version;
154+
private SuiteRpiEstimate rpis = null;
155+
154156

155157
/*
156158
* I don't use IdToFileMap for lastUsedSaveDirectories, because I think it's
@@ -251,6 +253,11 @@ public boolean getSettingBoolean(String key, boolean def) {
251253
return PuffinApp.this.getPrefs().getPrefs().
252254
getBoolean(key, def);
253255
}
256+
257+
@Override
258+
public SuiteRpiEstimate getSuiteRpiEstimate() {
259+
return rpis;
260+
}
254261

255262
};
256263

@@ -1999,7 +2006,6 @@ public void showCalculateRpiDialog() {
19992006
if (destinationPath == null) {
20002007
return;
20012008
}
2002-
SuiteRpiEstimate rpis = null;
20032009
switch (rpiDialog.getEstimateType()) {
20042010
case ARM_DEMAG:
20052011
case IRM_DEMAG:

src/net/talvi/puffinplot/data/MagSusSampleRpiEstimate.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class MagSusSampleRpiEstimate implements SampleRpiEstimate {
3838
/**
3939
* @return the sample giving the NRM intensity
4040
*/
41+
@Override
4142
public Sample getNrmSample() {
4243
return nrmSample;
4344
}
@@ -61,7 +62,8 @@ public String toCommaSeparatedString() {
6162
final StringBuilder builder = new StringBuilder();
6263
builder.append(getNrmSample().getTreatmentSteps().get(0).getDepth());
6364

64-
final TreatmentStep normalizerTreatmentStep = normalizer.getTreatmentStepByIndex(0);
65+
final TreatmentStep normalizerTreatmentStep =
66+
normalizer.getTreatmentStepByIndex(0);
6567
final double normalizerMagSus = normalizerTreatmentStep.getMagSus();
6668
builder.append(String.format(Locale.ENGLISH, ",%g,%g",
6769
getRatio(), normalizerMagSus));
@@ -73,5 +75,10 @@ public String toCommaSeparatedString() {
7375
public String getCommaSeparatedHeader() {
7476
return "ratio,MS";
7577
}
78+
79+
@Override
80+
public double getEstimate() {
81+
return getEstimate();
82+
}
7683

7784
}

src/net/talvi/puffinplot/data/SampleRpiEstimate.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public interface SampleRpiEstimate {
2424
/**
2525
*
2626
* @return a string of comma-separated values representing an RPI
27-
* estimate for a sample
27+
* estimate (and any associated data) for a sample
2828
*
2929
* @see #getCommaSeparatedHeader()
3030
*/
@@ -38,4 +38,15 @@ public interface SampleRpiEstimate {
3838
* @see #toCommaSeparatedString()
3939
*/
4040
String getCommaSeparatedHeader();
41+
42+
/**
43+
*
44+
* @return an estimate of the sample's RPI
45+
*/
46+
double getEstimate();
47+
48+
/**
49+
* @return the depth of the sample
50+
*/
51+
Sample getNrmSample();
4152
}

src/net/talvi/puffinplot/data/StepwiseSampleRpiEstimate.java

+9
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class StepwiseSampleRpiEstimate implements SampleRpiEstimate {
4848
/**
4949
* @return the sample giving the NRM intensity
5050
*/
51+
@Override
5152
public Sample getNrmSample() {
5253
return nrmSample;
5354
}
@@ -116,5 +117,13 @@ public String toCommaSeparatedString() {
116117
public String getCommaSeparatedHeader() {
117118
return "mean ratio,slope,r,r-squared,normalizer";
118119
}
120+
121+
/**
122+
* @return the sample RPI as estimated by the best-fit slope
123+
*/
124+
@Override
125+
public double getEstimate() {
126+
return getSlope();
127+
}
119128

120129
}

src/net/talvi/puffinplot/data/SuiteRpiEstimate.java

+17-6
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ public class SuiteRpiEstimate<EstimateType extends SampleRpiEstimate> {
4646
Logger.getLogger("net.talvi.puffinplot");
4747
private final List<Double> treatmentLevels;
4848
private final List<EstimateType> rpis;
49+
private final Suite nrmSuite;
4950

5051
private SuiteRpiEstimate(List<Double> treatmentLevels,
51-
List<EstimateType> rpis) {
52+
List<EstimateType> rpis, Suite nrmSuite) {
5253
this.treatmentLevels = treatmentLevels;
5354
this.rpis = rpis;
55+
this.nrmSuite = nrmSuite;
5456
}
5557

5658
/**
@@ -96,7 +98,8 @@ public void writeToFile(String path) throws IOException {
9698
rpis.add(new MagSusSampleRpiEstimate(nrmSample, msSample, rpi));
9799
}
98100
}
99-
return new SuiteRpiEstimate<>(Collections.emptyList(), rpis);
101+
return new SuiteRpiEstimate<>(Collections.emptyList(), rpis,
102+
nrmSuite);
100103
}
101104

102105
/**
@@ -191,7 +194,7 @@ public void writeToFile(String path) throws IOException {
191194
regression.getRSquare()));
192195
}
193196
}
194-
return new SuiteRpiEstimate<>(treatmentLevels, rpis);
197+
return new SuiteRpiEstimate<>(treatmentLevels, rpis, nrmSuite);
195198
}
196199

197200
/**
@@ -286,20 +289,28 @@ public void writeToFile(String path) throws IOException {
286289
regression.getRSquare()));
287290
}
288291
}
289-
return new SuiteRpiEstimate<>(treatmentLevels, rpis);
292+
return new SuiteRpiEstimate<>(treatmentLevels, rpis, nrmSuite);
290293
}
291294

292295
/**
293-
* @return the treatment levels
296+
* @return the treatment levels from which this RPI estimate was calculated
294297
*/
295298
public List<Double> getTreatmentLevels() {
296299
return treatmentLevels;
297300
}
298301

299302
/**
300-
* @return the RPIs
303+
* @return the RPI estimates for the individual samples
301304
*/
302305
public List<EstimateType> getRpis() {
303306
return rpis;
304307
}
308+
309+
/**
310+
* @return suite containing NRM values from which this RPI estimate
311+
* was calculated
312+
*/
313+
public Suite getNrmSuite() {
314+
return nrmSuite;
315+
}
305316
}

src/net/talvi/puffinplot/plots/Plot.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ public abstract class Plot
110110
"zplotlegend true 779 7 156 58 " +
111111
"suite_table false 636 76 297 91 " +
112112
"depth false 50 50 300 200 " +
113-
"vgpmap false 50 50 300 200 ";
114-
113+
"vgpmap false 50 50 300 200 " +
114+
"rpiplot false 50 50 300 200 ";
115+
115116
/**
116117
* Creates a plot with the supplied parameters.
117118
*

src/net/talvi/puffinplot/plots/PlotParams.java

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import net.talvi.puffinplot.data.Correction;
2222
import net.talvi.puffinplot.data.MeasurementAxis;
2323
import net.talvi.puffinplot.data.Sample;
24+
import net.talvi.puffinplot.data.SuiteRpiEstimate;
2425

2526
/**
2627
* The current parameters for a plot. This interface provides a way for a plot
@@ -111,5 +112,10 @@ public interface PlotParams {
111112
* @return the measurement unit size for this plot
112113
*/
113114
public float getUnitSize();
115+
116+
/**
117+
* @return the current suite RPI estimate, or {@code null} if there is none
118+
*/
119+
public SuiteRpiEstimate getSuiteRpiEstimate();
114120

115121
}
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* This file is part of PuffinPlot, a program for palaeomagnetic
2+
* data plotting and analysis. Copyright 2012-2019 Pontus Lurcock.
3+
*
4+
* PuffinPlot is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* PuffinPlot is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with PuffinPlot. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
package net.talvi.puffinplot.plots;
18+
19+
import java.awt.Color;
20+
import java.awt.Graphics2D;
21+
import java.awt.geom.Path2D;
22+
import java.awt.geom.Rectangle2D;
23+
import java.util.List;
24+
import java.util.OptionalDouble;
25+
import net.talvi.puffinplot.data.SampleRpiEstimate;
26+
import net.talvi.puffinplot.data.Suite;
27+
import net.talvi.puffinplot.data.SuiteRpiEstimate;
28+
29+
/**
30+
* A plot which shows the current suite RPI estimate.
31+
*/
32+
public class RpiPlot extends Plot {
33+
34+
/**
35+
* Instantiates a new RPI plot.
36+
*
37+
* @param params the plot parameters controlling this plot's content
38+
*/
39+
public RpiPlot(PlotParams params) {
40+
super(params);
41+
}
42+
43+
@Override
44+
public String getName() {
45+
return "rpiplot";
46+
}
47+
48+
@Override
49+
public String getNiceName() {
50+
return "RPI plot";
51+
}
52+
53+
@Override
54+
public void draw(Graphics2D graphics) {
55+
clearPoints();
56+
final SuiteRpiEstimate suiteRpi = params.getSuiteRpiEstimate();
57+
if (suiteRpi == null) {
58+
return;
59+
}
60+
final Suite suite = suiteRpi.getNrmSuite();
61+
if (suite == null) {
62+
return;
63+
}
64+
65+
final PlotAxis.AxisParameters xAxisParams = new PlotAxis
66+
.AxisParameters(suite.getMaxDepth(), Direction.RIGHT)
67+
.withLabel("Depth")
68+
.withNumberEachTick();
69+
final PlotAxis xAxis = new PlotAxis(xAxisParams, this);
70+
71+
final List<SampleRpiEstimate> sampleRpis = suiteRpi.getRpis();
72+
final OptionalDouble optionalMaxRpi =
73+
sampleRpis.stream().mapToDouble(rpi -> rpi.getEstimate()).max();
74+
if (!optionalMaxRpi.isPresent()) {
75+
return;
76+
}
77+
final double maxRpi = optionalMaxRpi.getAsDouble();
78+
79+
final PlotAxis.AxisParameters upAxisParams =
80+
new PlotAxis.AxisParameters(maxRpi, Direction.UP).
81+
withLabel("RPI").withNumberEachTick();
82+
final PlotAxis upAxis = new PlotAxis(upAxisParams, this);
83+
84+
final Rectangle2D dim =
85+
cropRectangle(getDimensions(), 320, 100, 50, 290);
86+
final double xScale = dim.getWidth() / (xAxis.getLength());
87+
final double yScale =
88+
dim.getHeight() / upAxis.getLength();
89+
90+
int i = 0;
91+
final Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD,
92+
sampleRpis.size());
93+
for (SampleRpiEstimate sampleRpi : sampleRpis) {
94+
final double depth = sampleRpi.getNrmSample().getDepth();
95+
final double rpi = sampleRpi.getEstimate();
96+
final double xPos = dim.getMinX() + depth * xScale;
97+
final double yPos = dim.getMaxY() - rpi * yScale;
98+
if (i == 0) {
99+
path.moveTo(xPos, yPos);
100+
} else {
101+
path.lineTo(xPos, yPos);
102+
}
103+
i++;
104+
}
105+
106+
graphics.setColor(Color.BLACK);
107+
upAxis.draw(graphics, yScale, (int) dim.getMinX(),
108+
(int) (dim.getMaxY()));
109+
xAxis.draw(graphics, xScale, (int) dim.getMinX(),
110+
(int) (dim.getMaxY()));
111+
graphics.draw(path);
112+
}
113+
}

src/net/talvi/puffinplot/window/MainGraphDisplay.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class MainGraphDisplay extends GraphDisplay implements Printable {
5151
SiteEqualAreaPlot.class, SuiteEqualAreaPlot.class,
5252
SampleParamsTable.class, SiteParamsTable.class, NrmHistogram.class,
5353
VgpTable.class, SuiteParamsTable.class, DepthPlot.class,
54-
VgpMap.class
54+
VgpMap.class, RpiPlot.class
5555
};
5656

5757
private final PlotParams params;

test/net/talvi/puffinplot/plots/SettablePlotParams.java

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import net.talvi.puffinplot.data.Correction;
2323
import net.talvi.puffinplot.data.MeasurementAxis;
2424
import net.talvi.puffinplot.data.Sample;
25+
import net.talvi.puffinplot.data.SuiteRpiEstimate;
2526

2627
/**
2728
* A simple configurable PlotParams implementation intended for testing.
@@ -132,4 +133,9 @@ public Map<String, Boolean> getSettingsMapBoolean() {
132133
return settingsMapBoolean;
133134
}
134135

136+
@Override
137+
public SuiteRpiEstimate getSuiteRpiEstimate() {
138+
return null;
139+
}
140+
135141
}

0 commit comments

Comments
 (0)