package newExamples;
import gaia.cu1.tools.exception.GaiaException;
import gaia.cu1.tools.numeric.algebra.GVector2d;
import gaia.cu1.tools.numeric.algebra.GVector3d;
import gaia.cu1.tools.time.GaiaTime;
import gaiasimu.GaiaSimuTime;
import gaiasimu.SimuException;
import gaiasimu.gaia.Gaia;
import gaiasimu.gaia.spacecraft.Transit;
import gaiasimu.universe.source.stellar.ComponentAstrometry;
import gaiasimu.universe.source.stellar.ExoPlanet;
import gaiasimu.universe.source.stellar.StarSystemSimuException;
import java.io.IOException;
import java.util.Random;
/**
* This class DataGenerator is supposed to use a given model to generate data on request,
* e.g. projected orbits or single transit data.
*
* @author ebopp
*/
public class DataGenerator implements Logging {
/** The model of the star system */
private Model model;
/** The simulation to which the generator belongs */
private Simulation sim;
/**
* Constructor.
*
* @param model Model of the star system
*/
public DataGenerator ( Model model, Simulation sim ) {
this.model = model;
this.sim = sim;
}
/**
* Gets the epoch astrometry array from GaiaSimu.
* Gaussian noise can be added for each measurement.
*
* @param useAc true, if across scan data should be used
* @param addNoise true, if gaussian noise i.e. statistical errors should be included
*
* @return the epoch astrometry array
*
* @throws SimuException the simu exception
* @throws GaiaException the gaia exception
* @throws IOException Signals that an I/O exception has occurred.
* @throws StarSystemSimuException
*/
public ObservationalDataSet getObservationalData(boolean addNoise)
throws SimuException, GaiaException, IOException, StarSystemSimuException {
// Random number generator
Random random = new Random();
// Use across scan information?
boolean useAc = model.useAcrossScan();
// Fitted error ratios for along scan (AL) and across scan (AC) determined by model fit
final double ALPHA_AL = 0.38077; // Fit result
final double ALPHA_AC = 0.07144; // Fit result
// Parallax error in mas, TODO: use faint cutoff
ErrorModel errorModel = new ErrorModel(model.getStar().getPhotometry(), sim.isFaintCutOff());
double sigPar = errorModel.parallaxError();
// Single transit errors
double sigTraAl = sigPar / ALPHA_AL; // Transit error along scan in mas
double sigTraAc = sigPar / ALPHA_AC; // Transit error across scan in mas
// Create simulated single transit observations
ObservationalDataSet obsData = new ObservationalDataSet();
for(Transit tr: model.getFilteredTransits()) {
// Obtain field angles
GVector2d fieldAngles = model.getFieldAngles(tr);
if(!useAc)
fieldAngles = new GVector2d(fieldAngles.getX(), 0.0);
// Add noise if boolean switch is true
GVector2d errors = new GVector2d ( sigTraAl, sigTraAc );
if(addNoise) {
GVector2d randomOffset = new GVector2d(sigTraAl * random.nextGaussian(), useAc? sigTraAc * random.nextGaussian() : 0);
fieldAngles.add(randomOffset);
}
// Calculate scanning angle
double scanAngle;
Gaia gaia = sim.getGaia();
synchronized(gaia) {
scanAngle = gaia.getAttitude().getScanAngle(tr.getDirectionCoMRS(), tr.getGSTime());
}
// Add new observed transit to array list
obsData.addTransit(new TransitData(fieldAngles, errors, false, tr.getGSTime(), scanAngle, useAc));
}
// Add reference astrometry to data
obsData.setReferenceAstrometry(model.getRefAstro());
// Return observational data
return obsData;
}
/**
* Generates a theoretical orbit.
* Warning: output does not contain any scan or error information!
*
* @return The orbit
*/
public TheoreticalDataSet getOrbit() {
// Determine earliest and latest observation
double startTime = model.getTransits().get(0).getGSTime().getJD();
double endTime = startTime;
for ( Transit tr: model.getTransits() ) {
double t = tr.getGSTime().getJD();
if ( t > endTime )
endTime = t;
if ( t < startTime )
startTime = t;
}
// Adjust time step to orbital periods; at most 10 days stepsize
double step = 10.0;
final double RESOLUTION_DEGREES = 5.0;
for(ExoPlanet planet: model.getPlanets()) {
double period = 1.0; // Default: 1 day
try {
period = ((ComponentAstrometry) planet.getAstrometry()).getOrbitalParams().period;
} catch (SimuException e) {
// Don't handle, just print stack trace
e.printStackTrace();
}
if ( period < step * (360.0 / RESOLUTION_DEGREES) )
step = period * (RESOLUTION_DEGREES / 360.0);
}
// Generate observational data
TheoreticalDataSet orbit = new TheoreticalDataSet();
for ( double timeJD = startTime; timeJD <= endTime; timeJD += step ) {
// Calculate coordinates and add transit to orbit
boolean relativity = false;
GaiaSimuTime gst = new GaiaSimuTime(new GaiaTime());
gst.setJD(timeJD);
GVector3d comrs = model.getStar().getAstrometry().getCoMRSPosition(gst, relativity);
GVector3d comrsRef = model.getAstrometry().getCoMRSPosition(gst, relativity);
GVector2d lpc = Conversion.fromCoMRStoLPC(comrs, comrsRef.getLongitude(), comrsRef.getLatitude());
orbit.addTransit ( new TransitData ( lpc, new GVector2d(), true, gst, 0.0, false ) );
}
// Return the orbit
return orbit;
}
/**
* Getter for underlying model.
*
* @return Model
*/
public Model getModel() {
return model;
}
}