aboutsummaryrefslogtreecommitdiff
path: root/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators
diff options
context:
space:
mode:
authorRJ Nowling <rnowling@gmail.com>2015-09-15 09:46:46 -0500
committerRJ Nowling <rnowling@gmail.com>2015-09-15 09:46:46 -0500
commitad88e7414540d6631854f1a731a3c1c029a3c965 (patch)
tree82d233e3884b24372a6b341c79577690613fe199 /bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators
parentbe796c98323573c7a3dff84a0a5115490c966a0f (diff)
BIGTOP-1991. Add BigTop Weatherman
Diffstat (limited to 'bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators')
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherGenerator.java67
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherRecord.java77
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/Driver.java194
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/PrecipitationSampler.java51
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/TemperatureSampler.java71
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherConstants.java53
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherParametersReader.java80
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherRecordBuilder.java163
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSampler.java50
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSamplerBuilder.java80
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherStationParameters.java110
-rw-r--r--bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WindSpeedSampler.java74
12 files changed, 1070 insertions, 0 deletions
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherGenerator.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherGenerator.java
new file mode 100644
index 00000000..0601c147
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherGenerator.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman;
+
+import java.util.List;
+
+import org.apache.bigtop.datagenerators.locations.Location;
+import org.apache.bigtop.datagenerators.samplers.SeedFactory;
+import org.apache.bigtop.datagenerators.samplers.samplers.Sampler;
+import org.apache.bigtop.datagenerators.weatherman.internal.WeatherParametersReader;
+import org.apache.bigtop.datagenerators.weatherman.internal.WeatherSamplerBuilder;
+import org.apache.bigtop.datagenerators.weatherman.internal.WeatherStationParameters;
+import org.joda.time.LocalDate;
+
+/**
+ * Generates daily weather records for a given location.
+ *
+ * @author rnowling
+ *
+ */
+public class WeatherGenerator implements Sampler<WeatherRecord> {
+ private final Sampler<WeatherRecord> weatherSampler;
+
+ /**
+ * Initializes the generator.
+ *
+ * @param startDate
+ * - first day of simulation
+ * @param location
+ * - location to simulate weather for
+ * @param seedFactory
+ * - for initializing seeds
+ * @throws Exception
+ * - if weather parameter data cannot be read
+ */
+ public WeatherGenerator(LocalDate startDate, Location location,
+ SeedFactory seedFactory) throws Exception {
+ List<WeatherStationParameters> parameters = new WeatherParametersReader()
+ .readParameters();
+ WeatherSamplerBuilder builder = new WeatherSamplerBuilder(parameters,
+ location, startDate, seedFactory);
+ weatherSampler = builder.build();
+ }
+
+ /**
+ * Generates a daily WeatherRecord for consecutive days, one day per call.
+ *
+ * @return Weather data for a single day
+ * @throws Exception
+ */
+ public WeatherRecord sample() throws Exception {
+ return weatherSampler.sample();
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherRecord.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherRecord.java
new file mode 100644
index 00000000..04d2eaa1
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/WeatherRecord.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman;
+
+import org.joda.time.LocalDate;
+
+/**
+ * Weather data for a single day and location
+ *
+ * @author rnowling
+ *
+ */
+public interface WeatherRecord {
+
+ /**
+ * Day
+ *
+ * @return date
+ */
+ public abstract LocalDate getDate();
+
+ /**
+ * Average daily temperature in units of Fahrenheit
+ *
+ * @return temperature
+ */
+ public abstract double getTemperature();
+
+ /**
+ * Daily total precipitation measured in millimeters
+ *
+ * @return total precipitation
+ */
+ public abstract double getPrecipitation();
+
+ /**
+ * Daily average wind speed in meters per second.
+ *
+ * @return average wind speed
+ */
+ public abstract double getWindSpeed();
+
+ /**
+ * Daily average wind chill in Fahrenheit
+ *
+ * @return average wind chill
+ */
+ public abstract double getWindChill();
+
+ /**
+ * Daily total rainfall in millimeters
+ *
+ * @return total rainfall
+ */
+ public abstract double getRainFall();
+
+ /**
+ * Daily total snowfall in centimeters
+ *
+ * @return total snowfall
+ */
+ public abstract double getSnowFall();
+
+} \ No newline at end of file
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/Driver.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/Driver.java
new file mode 100644
index 00000000..0bd8c41c
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/Driver.java
@@ -0,0 +1,194 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.bigtop.datagenerators.locations.Location;
+import org.apache.bigtop.datagenerators.locations.LocationReader;
+import org.apache.bigtop.datagenerators.samplers.SeedFactory;
+import org.apache.bigtop.datagenerators.weatherman.WeatherGenerator;
+import org.apache.bigtop.datagenerators.weatherman.WeatherRecord;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+import com.google.common.collect.Lists;
+
+public class Driver {
+ List<Location> locations;
+ Location location;
+ int simulationLength;
+ LocalDate startDate;
+ SeedFactory seedFactory;
+ File outputDir;
+
+ static final int NPARAMS = 5;
+
+ private void printUsage() {
+ String usage = "BigPetStore Data Generator\n" + "\n"
+ + "Usage: java -jar bigpetstore-weather-generator.java outputDir zipcode simulationLength startDate [seed]\n"
+ + "\n" + "outputDir - (string) directory to write files\n"
+ + "zipcode - (string) location zipcode\n"
+ + "simulationLength - (int) number of days to simulate\n"
+ + "startDate - (string) simulation start date in YYYY-MM-DD format\n"
+ + "seed - (long) seed for RNG. If not given, one is randomly generated.\n";
+
+ System.out.println(usage);
+ }
+
+ private Location findLocation(String zipcode) {
+ for (Location location : locations) {
+ if (location.getZipcode().equals(zipcode))
+ return location;
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns local date from string in YYYY-MM-DD format
+ *
+ * @param text
+ * @return
+ */
+ private LocalDate parseDate(String text) {
+ DateTimeFormatter dtFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
+ DateTime dt = dtFormatter.parseDateTime(text);
+
+ return dt.toLocalDate();
+ }
+
+ public void parseArgs(String[] args) {
+ if (args.length != NPARAMS && args.length != (NPARAMS - 1)) {
+ printUsage();
+ System.exit(1);
+ }
+
+ int i = -1;
+
+ outputDir = new File(args[++i]);
+ if (!outputDir.exists()) {
+ System.err.println("Given path (" + args[i] + ") does not exist.\n");
+ printUsage();
+ System.exit(1);
+ }
+
+ if (!outputDir.isDirectory()) {
+ System.err.println("Given path (" + args[i] + ") is not a directory.\n");
+ printUsage();
+ System.exit(1);
+ }
+
+ location = findLocation(args[++i]);
+ if (location == null) {
+ System.err.println(
+ "No location found for given zipcode \"" + args[i] + "\"");
+ printUsage();
+ System.exit(1);
+ }
+
+ try {
+ simulationLength = Integer.parseInt(args[++i]);
+ } catch (Exception e) {
+ System.err.println("Unable to parse '" + args[i]
+ + "' as an int for simulationLength.\n");
+ printUsage();
+ System.exit(1);
+ }
+
+ try {
+ startDate = parseDate(args[++i]);
+ } catch (Exception e) {
+ System.err.println("Unable to parse '" + args[i]
+ + "'. Expected string in 'YYYY-MM-DD' format.\n");
+ printUsage();
+ System.exit(1);
+ }
+
+ long seed = (new Random()).nextLong();
+ if (args.length == NPARAMS) {
+ try {
+ seed = Long.parseLong(args[++i]);
+ } catch (Exception e) {
+ System.err.println(
+ "Unable to parse '" + args[i] + "' as a long for the seed.\n");
+ printUsage();
+ System.exit(1);
+ }
+ }
+
+ seedFactory = new SeedFactory(seed);
+ }
+
+ private void writeWeather(Location location, List<WeatherRecord> trajectory)
+ throws Exception {
+ File outputFile = new File(outputDir.toString() + File.separator
+ + location.getZipcode() + ".txt");
+ Writer output = new BufferedWriter(new FileWriter(outputFile));
+
+ output.write(
+ "date,city,state,zipcode,temperature,windchill,windspeed,precipitation,rainfall,snowfall\n");
+ for (WeatherRecord weather : trajectory) {
+ String record = weather.getDate() + ",";
+ record += location.getCity() + ",";
+ record += location.getState() + ",";
+ record += location.getZipcode() + ",";
+ record += weather.getTemperature() + ",";
+ record += weather.getWindChill() + ",";
+ record += weather.getWindSpeed() + ",";
+ record += weather.getPrecipitation() + ",";
+ record += weather.getRainFall() + ",";
+ record += weather.getSnowFall() + "\n";
+
+ output.write(record);
+ }
+
+ output.close();
+ }
+
+ public void run(String[] args) throws Exception {
+ locations = new LocationReader().readData();
+
+ parseArgs(args);
+
+ WeatherGenerator generator = new WeatherGenerator(startDate, location,
+ seedFactory);
+
+ LocalDate date = startDate;
+ LocalDate endDate = startDate.plusDays(simulationLength);
+ List<WeatherRecord> trajectory = Lists.newArrayList();
+
+ while (date.isBefore(endDate)) {
+ WeatherRecord weather = generator.sample();
+ trajectory.add(weather);
+ date = weather.getDate();
+ }
+
+ writeWeather(location, trajectory);
+ }
+
+ public static void main(String[] args) throws Exception {
+ Driver driver = new Driver();
+ driver.run(args);
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/PrecipitationSampler.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/PrecipitationSampler.java
new file mode 100644
index 00000000..118e2451
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/PrecipitationSampler.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import org.apache.bigtop.datagenerators.samplers.SeedFactory;
+import org.apache.bigtop.datagenerators.samplers.samplers.ConditionalSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.ExponentialSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.Sampler;
+
+public class PrecipitationSampler implements
+ ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> {
+ private final Sampler<Double> precipitationSampler;
+
+ public PrecipitationSampler(double averagePrecipitation,
+ SeedFactory seedFactory) {
+ precipitationSampler = new ExponentialSampler(1.0 / averagePrecipitation,
+ seedFactory);
+ }
+
+ public WeatherRecordBuilder sample(WeatherRecordBuilder record)
+ throws Exception {
+ double temp = record.getTemperature();
+ double precipitation = precipitationSampler.sample();
+ record.setPrecipitation(precipitation);
+
+ double fractionRain = 1.0
+ / (1.0 + Math.exp(-WeatherConstants.PRECIPITATION_A
+ * (temp - WeatherConstants.PRECIPITATION_B)));
+
+ double rainfall = fractionRain * precipitation;
+ double snowfall = WeatherConstants.PRECIPITATION_TO_SNOWFALL
+ * (1.0 - fractionRain) * precipitation;
+ record.setRainFall(rainfall);
+ record.setSnowFall(snowfall);
+
+ return record;
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/TemperatureSampler.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/TemperatureSampler.java
new file mode 100644
index 00000000..b64b6e0e
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/TemperatureSampler.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import org.apache.bigtop.datagenerators.samplers.SeedFactory;
+import org.apache.bigtop.datagenerators.samplers.samplers.ConditionalSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.GaussianSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.Sampler;
+import org.joda.time.LocalDate;
+
+public class TemperatureSampler implements
+ ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> {
+ final private Sampler<Double> R;
+ final private double average;
+ final private double coeffReal;
+ final private double coeffImag;
+
+ private LocalDate date;
+ private double noise;
+
+ public TemperatureSampler(LocalDate startDate, double tempAverage,
+ double tempRealCoeff, double tempImagCoeff, double tempSigma,
+ SeedFactory seedFactory) {
+ R = new GaussianSampler(0.0, tempSigma, seedFactory);
+
+ this.average = tempAverage;
+ this.coeffReal = tempRealCoeff;
+ this.coeffImag = tempImagCoeff;
+
+ date = startDate;
+ noise = 0.0;
+ }
+
+ public WeatherRecordBuilder sample(WeatherRecordBuilder weatherRecord)
+ throws Exception {
+ double temp = 0.0;
+ while (date.isEqual(weatherRecord.getDate())
+ || date.isBefore(weatherRecord.getDate())) {
+ double dayOfYear = date.getDayOfYear();
+ temp = average
+ + coeffReal * Math.cos(-2.0 * Math.PI * dayOfYear
+ / WeatherConstants.TEMPERATURE_PERIOD)
+ + coeffImag * Math.sin(-2.0 * Math.PI * dayOfYear
+ / WeatherConstants.TEMPERATURE_PERIOD)
+ + noise;
+
+ noise += -1.0 * noise * WeatherConstants.TEMPERATURE_GAMMA
+ * WeatherConstants.WEATHER_TIMESTEP
+ + Math.sqrt(WeatherConstants.WEATHER_TIMESTEP) * R.sample();
+
+ date = date.plusDays(WeatherConstants.WEATHER_TIMESTEP);
+ }
+
+ weatherRecord.setTemperature(temp);
+
+ return weatherRecord;
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherConstants.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherConstants.java
new file mode 100644
index 00000000..83461607
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherConstants.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import java.io.File;
+
+public class WeatherConstants {
+ public static final File WEATHER_PARAMETERS_FILE = new File(
+ "weather_parameters.csv");
+
+ public static final double TEMPERATURE_GAMMA = 0.5; // 2 / day
+ public static final int WEATHER_TIMESTEP = 1; // days
+ public static final double TEMPERATURE_PERIOD = 365.0; // days
+
+ public static final double PRECIPITATION_A = 0.2;
+ public static final double PRECIPITATION_B = 27.0;
+ public static final double PRECIPITATION_TO_SNOWFALL = 10.0;
+
+ public static final double WIND_CHILL_PROBABILITY_A = 0.8;
+ public static final double WIND_CHILL_PROBABILITY_B = 0.5;
+ public static final double WIND_CHILL_PROBABILITY_C = 10.0; // F
+ public static final double WIND_CHILL_PROBABILITY_D = 0.2;
+
+ public static final double WIND_SPEED_PROBABILITY_A = -0.5;
+ public static final double WIND_SPEED_PROBABILITY_B = 0.8;
+ public static final double WIND_SPEED_PROBABILITY_C = 17.5; // mph
+ public static final double WIND_SPEED_PROBABILITY_D = 1.0;
+
+ public static final double SNOWFALL_PROBABILITY_A = -0.8;
+ public static final double SNOWFALL_PROBABILITY_B = 10.0;
+ public static final double SNOWFALL_PROBABILITY_C = 0.75; // in
+ public static final double SNOWFALL_PROBABILITY_D = 1.0;
+
+ public static final double RAINFALL_PROBABILITY_A = -0.6;
+ public static final double RAINFALL_PROBABILITY_B = 7.5;
+ public static final double RAINFALL_PROBABILITY_C = 0.75; // in
+ public static final double RAINFALL_PROBABILITY_D = 1.0;
+
+ public static final double M_PER_S_TO_MPH = 2.23694;
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherParametersReader.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherParametersReader.java
new file mode 100644
index 00000000..e8097d66
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherParametersReader.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Scanner;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.google.common.collect.Lists;
+
+public class WeatherParametersReader {
+ private InputStream getResource(File filename) throws Exception {
+ InputStream stream = getClass()
+ .getResourceAsStream("/input_data/" + filename);
+ return new BufferedInputStream(stream);
+ }
+
+ private WeatherStationParameters parseLine(String line) {
+ line = line.trim();
+ String[] cols = line.split(",");
+
+ String WBAN = cols[0];
+ String city = cols[1];
+ String state = cols[2];
+ double latitude = Double.parseDouble(cols[3]);
+ double longitude = Double.parseDouble(cols[4]);
+ Pair<Double, Double> coordinates = Pair.of(latitude, longitude);
+ double temperatureAverage = Double.parseDouble(cols[5]);
+ double temperatureRealCoeff = Double.parseDouble(cols[6]);
+ double temperatureImagCoeff = Double.parseDouble(cols[7]);
+ double temperatureDerivStd = Double.parseDouble(cols[8]);
+ double precipitationAverage = Double.parseDouble(cols[9]);
+ double windSpeedRealCoeff = Double.parseDouble(cols[10]);
+ double windSpeedImagCoeff = Double.parseDouble(cols[11]);
+ double windSpeedK = Double.parseDouble(cols[12]);
+ double windSpeedTheta = Double.parseDouble(cols[13]);
+
+ return new WeatherStationParameters(WBAN, city, state, coordinates,
+ temperatureAverage, temperatureRealCoeff, temperatureImagCoeff,
+ temperatureDerivStd, precipitationAverage, windSpeedRealCoeff,
+ windSpeedImagCoeff, windSpeedK, windSpeedTheta);
+ }
+
+ public List<WeatherStationParameters> readParameters() throws Exception {
+ InputStream inputStream = getResource(
+ WeatherConstants.WEATHER_PARAMETERS_FILE);
+ Scanner scanner = new Scanner(inputStream);
+
+ // skip header
+ scanner.nextLine();
+
+ List<WeatherStationParameters> parameterList = Lists.newArrayList();
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ WeatherStationParameters parameters = parseLine(line);
+ parameterList.add(parameters);
+ }
+
+ scanner.close();
+
+ return parameterList;
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherRecordBuilder.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherRecordBuilder.java
new file mode 100644
index 00000000..393414e7
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherRecordBuilder.java
@@ -0,0 +1,163 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import java.io.Serializable;
+
+import org.apache.bigtop.datagenerators.weatherman.WeatherRecord;
+import org.joda.time.LocalDate;
+
+public class WeatherRecordBuilder implements Serializable, WeatherRecord {
+ private static final long serialVersionUID = -6397575341624071821L;
+
+ private LocalDate date;
+ private Double temperature;
+ private Double precipitation;
+ private Double windSpeed;
+ private Double windChill;
+ private Double rainFall;
+ private Double snowFall;
+
+ public WeatherRecordBuilder(LocalDate date) {
+ this.date = date;
+ }
+
+ public WeatherRecordBuilder(LocalDate date, double temperature,
+ double precipitation, double windSpeed, double windChill,
+ double rainFall, double snowFall) {
+ this.date = date;
+ this.temperature = temperature;
+ this.precipitation = precipitation;
+ this.windSpeed = windSpeed;
+ this.windChill = windChill;
+ this.rainFall = rainFall;
+ this.snowFall = snowFall;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getDate()
+ */
+ @Override
+ public LocalDate getDate() {
+ return date;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getTemperature()
+ */
+ @Override
+ public double getTemperature() {
+ return temperature;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getPrecipitation()
+ */
+ @Override
+ public double getPrecipitation() {
+ return precipitation;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getWindSpeed()
+ */
+ @Override
+ public double getWindSpeed() {
+ return windSpeed;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getWindChill()
+ */
+ @Override
+ public double getWindChill() {
+ return windChill;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getRainFall()
+ */
+ @Override
+ public double getRainFall() {
+ return rainFall;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.bigtop.bigpetstore.datagenerator.generators.weather.
+ * WeatherRecord#getSnowFall()
+ */
+ @Override
+ public double getSnowFall() {
+ return snowFall;
+ }
+
+ public WeatherRecord build() {
+ if (temperature == null || precipitation == null || windSpeed == null
+ || windChill == null || rainFall == null || snowFall == null) {
+ throw new IllegalStateException("Not all fields have been initialized.");
+ }
+
+ return this;
+ }
+
+ public void setDate(LocalDate date) {
+ this.date = date;
+ }
+
+ public void setTemperature(Double temperature) {
+ this.temperature = temperature;
+ }
+
+ public void setPrecipitation(Double precipitation) {
+ this.precipitation = precipitation;
+ }
+
+ public void setWindSpeed(Double windSpeed) {
+ this.windSpeed = windSpeed;
+ }
+
+ public void setWindChill(Double windChill) {
+ this.windChill = windChill;
+ }
+
+ public void setRainFall(Double rainFall) {
+ this.rainFall = rainFall;
+ }
+
+ public void setSnowFall(Double snowFall) {
+ this.snowFall = snowFall;
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSampler.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSampler.java
new file mode 100644
index 00000000..3885caa5
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSampler.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import org.apache.bigtop.datagenerators.samplers.samplers.ConditionalSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.Sampler;
+import org.apache.bigtop.datagenerators.weatherman.WeatherRecord;
+import org.joda.time.LocalDate;
+
+public class WeatherSampler implements Sampler<WeatherRecord> {
+ private final ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> tempSampler;
+ private final ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> windSpeedSampler;
+ private final ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> precipitationSampler;
+ private LocalDate date;
+
+ public WeatherSampler(LocalDate startDate,
+ ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> tempSampler,
+ ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> windSpeedSampler,
+ ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> precipitationSampler) {
+ this.tempSampler = tempSampler;
+ this.windSpeedSampler = windSpeedSampler;
+ this.precipitationSampler = precipitationSampler;
+ date = startDate;
+ }
+
+ public WeatherRecord sample() throws Exception {
+ WeatherRecordBuilder weatherRecord = new WeatherRecordBuilder(date);
+
+ weatherRecord = tempSampler.sample(weatherRecord);
+ weatherRecord = windSpeedSampler.sample(weatherRecord);
+ weatherRecord = precipitationSampler.sample(weatherRecord);
+
+ date = date.plusDays(WeatherConstants.WEATHER_TIMESTEP);
+
+ return weatherRecord.build();
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSamplerBuilder.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSamplerBuilder.java
new file mode 100644
index 00000000..40128ae9
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherSamplerBuilder.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import java.util.Collection;
+
+import org.apache.bigtop.datagenerators.locations.Location;
+import org.apache.bigtop.datagenerators.samplers.SeedFactory;
+import org.apache.bigtop.datagenerators.samplers.samplers.ConditionalSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.Sampler;
+import org.apache.bigtop.datagenerators.weatherman.WeatherRecord;
+import org.joda.time.LocalDate;
+
+public class WeatherSamplerBuilder {
+
+ private final WeatherStationParameters parameters;
+ private final SeedFactory seedFactory;
+ private final LocalDate startDate;
+
+ public WeatherSamplerBuilder(
+ Collection<WeatherStationParameters> weatherParameters,
+ Location location, LocalDate startDate, SeedFactory seedFactory) {
+ parameters = findClosest(weatherParameters, location);
+ this.seedFactory = seedFactory;
+ this.startDate = startDate;
+ }
+
+ private WeatherStationParameters findClosest(
+ Collection<WeatherStationParameters> weatherParameters,
+ Location location) {
+ WeatherStationParameters closestStation = null;
+ double minDist = Double.MAX_VALUE;
+
+ for (WeatherStationParameters parameters : weatherParameters) {
+ double dist = location.distance(parameters.getCoordinates());
+ if (dist < minDist) {
+ minDist = dist;
+ closestStation = parameters;
+ }
+ }
+
+ return closestStation;
+ }
+
+ private ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> buildTempSampler() {
+ return new TemperatureSampler(startDate, parameters.getTemperatureAverage(),
+ parameters.getTemperatureRealCoeff(),
+ parameters.getTemperatureImagCoeff(),
+ parameters.getTemperatureDerivStd(), seedFactory);
+ }
+
+ private ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> buildWindSpeedSampler() {
+ return new WindSpeedSampler(parameters.getWindSpeedRealCoeff(),
+ parameters.getWindSpeedImagCoeff(), parameters.getWindSpeedK(),
+ parameters.getWindSpeedTheta(), seedFactory);
+ }
+
+ private ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> buildPrecipitationSampler() {
+ return new PrecipitationSampler(parameters.getPrecipitationAverage(),
+ seedFactory);
+ }
+
+ public Sampler<WeatherRecord> build() {
+ return new WeatherSampler(startDate, buildTempSampler(),
+ buildWindSpeedSampler(), buildPrecipitationSampler());
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherStationParameters.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherStationParameters.java
new file mode 100644
index 00000000..7edba341
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WeatherStationParameters.java
@@ -0,0 +1,110 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+public class WeatherStationParameters implements Serializable {
+ private static final long serialVersionUID = -7268791467819627718L;
+
+ private String WBAN;
+ private String city;
+ private String state;
+ private Pair<Double, Double> coordinates;
+ private double temperatureAverage;
+ private double temperatureRealCoeff;
+ private double temperatureImagCoeff;
+ private double temperatureDerivStd;
+ private double precipitationAverage;
+ private double windSpeedRealCoeff;
+ private double windSpeedImagCoeff;
+ private double windSpeedK;
+ private double windSpeedTheta;
+
+ public WeatherStationParameters(String WBAN, String city, String state,
+ Pair<Double, Double> coordinates, double temperatureAverage,
+ double temperatureRealCoeff, double temperatureImagCoeff,
+ double temperatureDerivStd, double precipitationAverage,
+ double windSpeedRealCoeff, double windSpeedImagCoeff,
+ double windSpeedK, double windSpeedTheta) {
+ this.city = city;
+ this.state = state;
+ this.coordinates = coordinates;
+ this.temperatureAverage = temperatureAverage;
+ this.temperatureRealCoeff = temperatureRealCoeff;
+ this.temperatureImagCoeff = temperatureImagCoeff;
+ this.temperatureDerivStd = temperatureDerivStd;
+ this.precipitationAverage = precipitationAverage;
+ this.windSpeedRealCoeff = windSpeedRealCoeff;
+ this.windSpeedImagCoeff = windSpeedImagCoeff;
+ this.windSpeedK = windSpeedK;
+ this.windSpeedTheta = windSpeedTheta;
+ }
+
+ public String getWBAN() {
+ return WBAN;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public Pair<Double, Double> getCoordinates() {
+ return coordinates;
+ }
+
+ public double getTemperatureAverage() {
+ return temperatureAverage;
+ }
+
+ public double getTemperatureRealCoeff() {
+ return temperatureRealCoeff;
+ }
+
+ public double getTemperatureImagCoeff() {
+ return temperatureImagCoeff;
+ }
+
+ public double getTemperatureDerivStd() {
+ return temperatureDerivStd;
+ }
+
+ public double getPrecipitationAverage() {
+ return precipitationAverage;
+ }
+
+ public double getWindSpeedRealCoeff() {
+ return windSpeedRealCoeff;
+ }
+
+ public double getWindSpeedImagCoeff() {
+ return windSpeedImagCoeff;
+ }
+
+ public double getWindSpeedK() {
+ return windSpeedK;
+ }
+
+ public double getWindSpeedTheta() {
+ return windSpeedTheta;
+ }
+}
diff --git a/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WindSpeedSampler.java b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WindSpeedSampler.java
new file mode 100644
index 00000000..c4454325
--- /dev/null
+++ b/bigtop-data-generators/bigtop-weatherman/src/main/java/org/apache/bigtop/datagenerators/weatherman/internal/WindSpeedSampler.java
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bigtop.datagenerators.weatherman.internal;
+
+import org.apache.bigtop.datagenerators.samplers.SeedFactory;
+import org.apache.bigtop.datagenerators.samplers.samplers.ConditionalSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.GammaSampler;
+import org.apache.bigtop.datagenerators.samplers.samplers.Sampler;
+
+public class WindSpeedSampler implements
+ ConditionalSampler<WeatherRecordBuilder, WeatherRecordBuilder> {
+ private final double coeffReal;
+ private final double coeffImag;
+ private final Sampler<Double> gamma;
+
+ public WindSpeedSampler(double windSpeedRealCoeff, double windSpeedImagCoeff,
+ double windSpeedK, double windSpeedTheta, SeedFactory seedFactory) {
+ coeffReal = windSpeedRealCoeff;
+ coeffImag = windSpeedImagCoeff;
+
+ gamma = new GammaSampler(windSpeedK, windSpeedTheta, seedFactory);
+
+ }
+
+ /**
+ *
+ * @param temp
+ * - given in Fahrenheit
+ * @param windSpeed
+ * - given in MPH
+ * @return
+ */
+ private Double windChill(double temp, double windSpeed) {
+ double v_16 = Math.pow(windSpeed, 0.16);
+ double windChill = 35.74 + 0.6215 * temp - 35.74 * v_16
+ + 0.4275 * temp * v_16;
+
+ return windChill;
+ }
+
+ public WeatherRecordBuilder sample(WeatherRecordBuilder weatherRecord)
+ throws Exception {
+
+ double dayOfYear = weatherRecord.getDate().getDayOfYear();
+ // meters/second
+ double windSpeed = Math.max(0.0,
+ coeffReal
+ * Math.cos(-2.0 * Math.PI * dayOfYear
+ / WeatherConstants.TEMPERATURE_PERIOD)
+ + coeffImag * Math.sin(-2.0 * Math.PI * dayOfYear
+ / WeatherConstants.TEMPERATURE_PERIOD) + gamma.sample());
+
+ double windChill = windChill(weatherRecord.getTemperature(),
+ windSpeed * WeatherConstants.M_PER_S_TO_MPH);
+
+ weatherRecord.setWindSpeed(windSpeed);
+ weatherRecord.setWindChill(windChill);
+
+ return weatherRecord;
+ }
+}