QuakemlProductCreator.java
- package gov.usgs.earthquake.eids;
- import gov.usgs.earthquake.event.Converter;
- import gov.usgs.earthquake.product.ByteContent;
- import gov.usgs.earthquake.product.Content;
- import gov.usgs.earthquake.product.Product;
- import gov.usgs.earthquake.product.ProductId;
- import gov.usgs.earthquake.product.io.ObjectProductSource;
- import gov.usgs.earthquake.product.io.XmlProductHandler;
- import gov.usgs.earthquake.quakeml.FileToQuakemlConverter;
- import gov.usgs.util.StreamUtils;
- import gov.usgs.util.XmlUtils;
- import java.io.File;
- import java.math.BigDecimal;
- import java.math.BigInteger;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.logging.Logger;
- import org.quakeml_1_2.Axis;
- import org.quakeml_1_2.ConfidenceEllipsoid;
- import org.quakeml_1_2.CreationInfo;
- import org.quakeml_1_2.EvaluationMode;
- import org.quakeml_1_2.Event;
- import org.quakeml_1_2.EventDescription;
- import org.quakeml_1_2.EventDescriptionType;
- import org.quakeml_1_2.EventParameters;
- import org.quakeml_1_2.EventType;
- import org.quakeml_1_2.FocalMechanism;
- import org.quakeml_1_2.InternalEvent;
- import org.quakeml_1_2.Magnitude;
- import org.quakeml_1_2.MomentTensor;
- import org.quakeml_1_2.NodalPlane;
- import org.quakeml_1_2.NodalPlanes;
- import org.quakeml_1_2.Origin;
- import org.quakeml_1_2.OriginQuality;
- import org.quakeml_1_2.OriginUncertainty;
- import org.quakeml_1_2.OriginUncertaintyDescription;
- import org.quakeml_1_2.Quakeml;
- import org.quakeml_1_2.RealQuantity;
- import org.quakeml_1_2.ScenarioEvent;
- import org.quakeml_1_2.SourceTimeFunction;
- import org.quakeml_1_2.SourceTimeFunctionType;
- import org.quakeml_1_2.Tensor;
- import org.quakeml_1_2.TimeQuantity;
- import org.quakeml_1_2.PrincipalAxes;
- import org.quakeml_1_2.EvaluationStatus;
- /**
- * Create Products from ANSS Quakeml files.
- */
- public class QuakemlProductCreator implements ProductCreator {
- /** For use in logging issues */
- public static final Logger LOGGER = Logger
- .getLogger(QuakemlProductCreator.class.getName());
- /** Content type for xml */
- public static final String XML_CONTENT_TYPE = "application/xml";
- /** Content path for quakeml */
- public static final String QUAKEML_CONTENT_PATH = "quakeml.xml";
- /** Contents XML path */
- public static final String CONTENTS_XML_PATH = "contents.xml";
- /** Var for number of meters/kilometer... */
- public static final BigDecimal METERS_PER_KILOMETER = new BigDecimal("1000");
- /** Version */
- public static final String VERSION = "1.0";
- /**
- * When phases exist it is a "phase" type product. When this flag is set to
- * true, a lightweight, origin-only type product (without bulky phase data)
- * is also sent.
- */
- private boolean sendOriginWhenPhasesExist = false;
- private boolean sendMechanismWhenPhasesExist = false;
- // xml for the eqmessage currently being processed
- private String quakemlXML;
- private CreationInfo eventParametersCreationInfo;
- // attributes of current quakeml being processed
- private String productSource;
- private String productCode;
- private String eventSource;
- private String eventCode;
- private Date updateTime;
- private FileToQuakemlConverter converter = null;
- private Converter formatConverter = new Converter();
- private boolean validate = false;
- // default to fixing padding issues
- private boolean padForBase64Bug = true;
- /** Default Constructor */
- public QuakemlProductCreator() {
- super();
- }
- /**
- * Constructor taking in argument for Base64 bug padding
- * @param padForBase64Bug Boolean if needed to pad
- */
- public QuakemlProductCreator(boolean padForBase64Bug) {
- this.padForBase64Bug = padForBase64Bug;
- }
- /**
- * Gets Quakeml products with no rawQuakeml
- * @param message Parsed quakeml message
- * @return List of products
- * @throws Exception if error occurs
- */
- public List<Product> getQuakemlProducts(final Quakeml message)
- throws Exception {
- return getQuakemlProducts(message, null);
- }
- /**
- * Gets Quakeml products with the message as a rawQuakeml
- * @param message Parsed quakeml message
- * @return List of products
- * @throws Exception if error occurs
- */
- public List<Product> getQuakemlProducts(final String message)
- throws Exception {
- Quakeml quakeml = formatConverter.getQuakeml(message, validate);
- return getQuakemlProducts(quakeml, message);
- }
- /**
- * Get products in a quakeml message.
- *
- * @param message
- * the parsed quakeml message.
- * @param rawQuakeml
- * bytes of quakeml message. If null, the quakeml object will be
- * serialized into xml. This parameter is used to preserve the
- * original input, instead of always serializing from the quakeml
- * object.
- * @return list of products generated from quakeml message.
- * @throws Exception if error occurs
- */
- public List<Product> getQuakemlProducts(final Quakeml message,
- final String rawQuakeml) throws Exception {
- List<Product> products = new ArrayList<Product>();
- // serialize for embedding in product
- quakemlXML = rawQuakeml;
- if (quakemlXML == null) {
- quakemlXML = convertQuakemlToString(message);
- } else {
- quakemlXML = fixRawQuakeml(quakemlXML);
- }
- EventParameters eventParameters = message.getEventParameters();
- eventParametersCreationInfo = eventParameters.getCreationInfo();
- // only process first event
- Event firstEvent = QuakemlUtils.getFirstEvent(eventParameters);
- if (firstEvent != null) {
- if (firstEvent instanceof InternalEvent) {
- products.addAll(getInternalEventProducts(message, (InternalEvent) firstEvent));
- } else if (firstEvent instanceof ScenarioEvent) {
- products.addAll(getScenarioEventProducts(message, (ScenarioEvent) firstEvent));
- } else {
- products.addAll(getEventProducts(message, firstEvent));
- }
- }
- // add property to all products to indicate they all come from the same
- // eventParameters "envelope"
- String eventParametersPublicID = eventParameters.getPublicID();
- Iterator<Product> productIter = products.iterator();
- while (productIter.hasNext()) {
- Product next = productIter.next();
- setProperty(next.getProperties(), "eventParametersPublicID",
- eventParametersPublicID);
- }
- eventParametersCreationInfo = null;
- quakemlXML = null;
- return products;
- }
- /**
- * Get internal products in quakeml event element.
- *
- * Calls {@link #getEventProducts(Quakeml, Event)}, and adds "internal-"
- * prefix to each type in the returned list of products.
- *
- * @param message
- * the quakeml message.
- * @param event
- * the internal event element.
- * @return list of internal products found in event element, may be empty.
- * @throws Exception if error occurs
- */
- public List<Product> getInternalEventProducts(final Quakeml message,
- final InternalEvent event) throws Exception {
- List<Product> products = getEventProducts(message, event);
- Iterator<Product> iter = products.iterator();
- while (iter.hasNext()) {
- ProductId nextId = iter.next().getId();
- nextId.setType("internal-" + nextId.getType());
- }
- return products;
- }
- /**
- * Get scenario products in quakeml event element.
- *
- * Calls {@link #getEventProducts(Quakeml, Event)}, and adds "-scenario"
- * suffix to each type in the returned list of products.
- *
- * @param message
- * the quakeml message.
- * @param event
- * the scenario event element.
- * @return list of scenario products found in event element, may be empty.
- * @throws Exception if error occurs
- */
- public List<Product> getScenarioEventProducts(final Quakeml message,
- final ScenarioEvent event) throws Exception {
- List<Product> products = getEventProducts(message, event);
- Iterator<Product> iter = products.iterator();
- while (iter.hasNext()) {
- ProductId nextId = iter.next().getId();
- nextId.setType(nextId.getType() + "-scenario");
- }
- return products;
- }
- /**
- * Get products in quakeml event element.
- *
- * @param message
- * the quakeml message.
- * @param event
- * the event element in the quakeml message.
- * @return list of products found in event element, may be empty.
- * @throws Exception if error occurs
- */
- public List<Product> getEventProducts(final Quakeml message, Event event)
- throws Exception {
- List<Product> products = new ArrayList<Product>();
- // read catalog attributes for product source and code, and event source
- // and code
- productSource = event.getDatasource();
- productCode = event.getDataid();
- eventSource = event.getEventsource();
- eventCode = event.getEventid();
- if (productSource == null || eventSource == null || eventCode == null) {
- LOGGER.warning("Missing catalog attributes from event element, skipping");
- // not anss information, don't convert to products
- return products;
- } else if (productCode == null) {
- productCode = eventSource + eventCode;
- }
- productSource = productSource.toLowerCase();
- // product update time
- updateTime = null;
- if (eventParametersCreationInfo != null) {
- updateTime = eventParametersCreationInfo.getCreationTime();
- } else {
- LOGGER.warning("Missing eventParameters creationTime, using now for update time");
- updateTime = new Date();
- }
- ByteContent quakemlContent = new ByteContent(quakemlXML.getBytes());
- quakemlContent.setContentType(XML_CONTENT_TYPE);
- quakemlContent.setLastModified(updateTime);
- boolean hasPhaseData = QuakemlUtils.hasPhaseData(event);
- // create this object, may go unused
- Product originProduct = new Product(new ProductId(productSource,
- (hasPhaseData ? "phase-data" : "origin"), productCode,
- updateTime));
- originProduct.setEventId(eventSource, eventCode);
- if (event.getCreationInfo() != null) {
- originProduct.setVersion(event.getCreationInfo().getVersion());
- }
- originProduct.getContents().put(QUAKEML_CONTENT_PATH, quakemlContent);
- originProduct.getContents().put(CONTENTS_XML_PATH, getContentsXML());
- // track which event this product is from
- setProperty(originProduct.getProperties(), "quakeml-publicid",
- event.getPublicID());
- // delete origin product
- if (event.getType() == EventType.NOT_EXISTING) {
- originProduct.setStatus(Product.STATUS_DELETE);
- products.add(originProduct);
- Product phaseDelete = new Product(originProduct);
- phaseDelete.getId().setType("phase-data");
- products.add(phaseDelete);
- // don't need to delete other stuff
- // when origins for event are deleted, event is deleted
- return products;
- }
- Origin origin = QuakemlUtils.getPreferredOrigin(event);
- if (origin != null) {
- // track which origin this product is from
- setProperty(originProduct.getProperties(), "quakeml-origin-publicid",
- origin.getPublicID());
- // update origin product
- Map<String, String> properties = originProduct.getProperties();
- TimeQuantity eventTime = origin.getTime();
- if (eventTime != null) {
- originProduct.setEventTime(eventTime.getValue());
- setProperty(properties, "eventtime-error",
- eventTime.getUncertainty());
- }
- RealQuantity eventLatitude = origin.getLatitude();
- if (eventLatitude != null) {
- originProduct.setLatitude(eventLatitude.getValue());
- setProperty(properties, "latitude-error",
- eventLatitude.getUncertainty());
- }
- RealQuantity eventLongitude = origin.getLongitude();
- if (eventLongitude != null) {
- originProduct.setLongitude(eventLongitude.getValue());
- setProperty(properties, "longitude-error",
- eventLongitude.getUncertainty());
- }
- RealQuantity depth = origin.getDepth();
- if (depth != null) {
- originProduct.setDepth(depth.getValue().divide(
- METERS_PER_KILOMETER));
- if (depth.getUncertainty() != null) {
- setProperty(properties, "vertical-error", depth
- .getUncertainty().divide(METERS_PER_KILOMETER));
- }
- if (origin.getDepthType() != null) {
- setProperty(properties, "depth-type", origin.getDepthType()
- .value());
- }
- }
- // read horizontal error
- OriginUncertainty originUncertainty = origin.getOriginUncertainty();
- if (originUncertainty != null) {
- if (originUncertainty.getHorizontalUncertainty() != null) {
- setProperty(properties, "horizontal-error",
- originUncertainty.getHorizontalUncertainty()
- .divide(METERS_PER_KILOMETER));
- } else if (originUncertainty.getPreferredDescription() == OriginUncertaintyDescription.HORIZONTAL_UNCERTAINTY) {
- throw new IllegalArgumentException(
- "Missing horizontal uncertainty value");
- }
- ConfidenceEllipsoid ellipse = originUncertainty.getConfidenceEllipsoid();
- if (ellipse != null) {
- setProperty(properties, "error-ellipse-azimuth",
- ellipse.getMajorAxisAzimuth());
- setProperty(properties, "error-ellipse-plunge",
- ellipse.getMajorAxisPlunge());
- setProperty(properties, "error-ellipse-rotation",
- ellipse.getMajorAxisRotation());
- setProperty(properties, "error-ellipse-major",
- ellipse.getSemiMajorAxisLength());
- setProperty(properties, "error-ellipse-minor",
- ellipse.getSemiMinorAxisLength());
- setProperty(properties, "error-ellipse-intermediate",
- ellipse.getSemiIntermediateAxisLength());
- }
- }
- EventType eventType = event.getType();
- properties.put("event-type",
- ((eventType == null) ? EventType.EARTHQUAKE : eventType)
- .value());
- CreationInfo originCreationInfo = origin.getCreationInfo();
- if (originCreationInfo != null) {
- setProperty(properties, "origin-source",
- originCreationInfo.getAgencyID());
- }
- OriginQuality originQuality = origin.getQuality();
- if (originQuality != null) {
- setProperty(properties, "azimuthal-gap",
- originQuality.getAzimuthalGap());
- setProperty(properties, "num-phases-used",
- originQuality.getUsedPhaseCount());
- setProperty(properties, "num-stations-used",
- originQuality.getUsedStationCount());
- setProperty(properties, "minimum-distance",
- originQuality.getMinimumDistance());
- setProperty(properties, "standard-error",
- originQuality.getStandardError());
- }
- if (origin.getEvaluationMode() == EvaluationMode.MANUAL) {
- properties.put("review-status", "reviewed");
- } else {
- properties.put("review-status", "automatic");
- }
- if (origin.getEvaluationStatus() != null) {
- properties.put("evaluation-status", origin
- .getEvaluationStatus().value());
- } else {
- properties.put("evaluation-status",
- EvaluationStatus.PRELIMINARY.value());
- }
- // add magnitude properties
- Magnitude magnitude = QuakemlUtils.getPreferredMagnitude(event);
- if (magnitude != null) {
- // track which origin this product is from
- setProperty(originProduct.getProperties(), "quakeml-magnitude-publicid",
- magnitude.getPublicID());
- CreationInfo magnitudeCreationInfo = magnitude
- .getCreationInfo();
- if (magnitudeCreationInfo != null) {
- setProperty(properties, "magnitude-source",
- magnitudeCreationInfo.getAgencyID());
- }
- originProduct.setMagnitude(QuakemlUtils.getValue(magnitude
- .getMag()));
- setProperty(properties, "magnitude-type",
- QuakemlUtils.getMagnitudeType(magnitude.getType()));
- setProperty(properties, "magnitude-azimuthal-gap",
- magnitude.getAzimuthalGap());
- try {
- setProperty(properties, "magnitude-error", magnitude
- .getMag().getUncertainty());
- } catch (Exception e) {
- // no magnitude uncertainty
- }
- setProperty(properties, "magnitude-num-stations-used",
- magnitude.getStationCount());
- } else {
- // a location without a magnitude
- }
- products.add(originProduct);
- } else {
- // no preferred origin found
- // signal origin product hasn't been created
- originProduct = null;
- }
- // look for event description products
- Iterator<EventDescription> iter = event.getDescriptions().iterator();
- while (iter.hasNext()) {
- EventDescription next = iter.next();
- EventDescriptionType type = next.getType();
- if (type == EventDescriptionType.EARTHQUAKE_NAME) {
- if (originProduct != null) {
- // Region name overrides should be sent
- // from the admin pages, or attached to an origin. That way
- // only a preferred origin, or a manually sent region,
- // can alter the displayed region name
- setProperty(originProduct.getProperties(), "title", next
- .getText().trim());
- }
- } else if (type == EventDescriptionType.TECTONIC_SUMMARY) {
- Product product = new Product(new ProductId(productSource,
- "tectonic-summary", productCode, updateTime));
- product.setEventId(eventSource, eventCode);
- ByteContent content = new ByteContent(next.getText().getBytes());
- content.setLastModified(updateTime);
- product.getContents().put("tectonic-summary.inc.html", content);
- products.add(product);
- } else if (type == EventDescriptionType.FELT_REPORT) {
- Product product = new Product(new ProductId(productSource,
- "impact-text", productCode, updateTime));
- product.setEventId(eventSource, eventCode);
- ByteContent content = new ByteContent(next.getText().getBytes());
- content.setLastModified(updateTime);
- product.getContents().put("", content);
- products.add(product);
- }
- }
- if (sendMechanismWhenPhasesExist || originProduct == null
- || !hasPhaseData) {
- Iterator<FocalMechanism> focalMechanisms = event
- .getFocalMechanisms().iterator();
- while (focalMechanisms.hasNext()) {
- FocalMechanism mech = focalMechanisms.next();
- Product mechProduct = null;
- if (hasPhaseData && originProduct != null) {
- // when a phase data product was created, send lightweight
- // focal mechanism
- Quakeml lightweightQuakeml = QuakemlUtils
- .getLightweightFocalMechanism(message,
- mech.getPublicID());
- Event lightweightEvent = QuakemlUtils.getFirstEvent(
- lightweightQuakeml.getEventParameters());
- FocalMechanism lightweightMech = QuakemlUtils
- .getFocalMechanism(lightweightEvent,
- mech.getPublicID());
- mechProduct = getFocalMechanismProduct(lightweightQuakeml,
- lightweightEvent, lightweightMech,
- convertQuakemlToString(lightweightQuakeml));
- } else {
- // otherwise, fall back to original
- mechProduct = getFocalMechanismProduct(message, event,
- mech, quakemlXML);
- }
- if (mechProduct != null) {
- products.add(mechProduct);
- }
- }
- }
- // send lightweight origin product
- if (sendOriginWhenPhasesExist && hasPhaseData && originProduct != null) {
- // create lightweight origin product
- Product lightweightOrigin = new Product(originProduct);
- lightweightOrigin.getId().setType("origin");
- Quakeml lightweightQuakeml = QuakemlUtils
- .getLightweightOrigin(message);
- // serialize xml without phase data
- ByteContent lightweightContent = new ByteContent(convertQuakemlToString(lightweightQuakeml).getBytes());
- lightweightContent.setContentType(XML_CONTENT_TYPE);
- lightweightContent.setLastModified(updateTime);
- lightweightOrigin.getContents().put(QUAKEML_CONTENT_PATH,
- lightweightContent);
- // insert at front of list
- products.add(0, lightweightOrigin);
- }
- return products;
- }
- /**
- * @param quakeml Quakeml
- * @param event the event element in the quakeml message
- * @param mech A focal mechanism
- * @param quakemlContent String of content in Quakeml
- * @return A product derived from a focal mechanism
- */
- protected Product getFocalMechanismProduct(final Quakeml quakeml,
- final Event event, final FocalMechanism mech,
- final String quakemlContent) {
- MomentTensor momentTensor = mech.getMomentTensor();
- // determine product id
- String mechSource = mech.getDatasource();
- String mechCode = mech.getDataid();
- String mechType = mech.getDatatype();
- if (mechType == null) {
- // automatically determine mechanism type based on available data
- mechType = "focal-mechanism";
- if (momentTensor != null && momentTensor.getTensor() != null) {
- mechType = "moment-tensor";
- if (mechCode == null && momentTensor.getMethodID() != null) {
- mechCode = productCode + "_" + momentTensor.getMethodID();
- }
- }
- }
- if (mechSource == null) {
- mechSource = productSource;
- }
- if (mechCode == null) {
- mechCode = productCode;
- }
- Product product = new Product(new ProductId(mechSource, mechType,
- mechCode, updateTime));
- if (mech.getEvaluationStatus() == EvaluationStatus.REJECTED) {
- // this is a delete
- product.setStatus(Product.STATUS_DELETE);
- }
- // product is being contributed to containing event
- product.setEventId(eventSource, eventCode);
- ByteContent tensorContent = new ByteContent(quakemlContent.getBytes());
- tensorContent.setContentType(XML_CONTENT_TYPE);
- tensorContent.setLastModified(updateTime);
- product.getContents().put(QUAKEML_CONTENT_PATH, tensorContent);
- product.getContents().put(CONTENTS_XML_PATH, getContentsXML());
- Map<String, String> properties = product.getProperties();
- // track which mechanism is used in this product, for later
- // extraction
- setProperty(properties, "quakeml-publicid", mech.getPublicID());
- // also track original event if set, in case this is a recontributed
- // product
- setProperty(properties, "original-eventsource", mech.getEventsource());
- setProperty(properties, "original-eventsourcecode", mech.getEventid());
- if (mech.getEvaluationMode() == EvaluationMode.MANUAL) {
- properties.put("review-status", "reviewed");
- } else {
- properties.put("review-status", "automatic");
- }
- if (mech.getEvaluationStatus() != null) {
- properties.put("evaluation-status", mech.getEvaluationStatus()
- .value());
- } else {
- properties.put("evaluation-status", EvaluationStatus.PRELIMINARY
- .value());
- }
- CreationInfo focalMechanismCreationInfo = mech.getCreationInfo();
- if (focalMechanismCreationInfo != null) {
- product.setVersion(focalMechanismCreationInfo.getVersion());
- setProperty(properties, "beachball-source",
- focalMechanismCreationInfo.getAgencyID());
- }
- NodalPlanes planes = mech.getNodalPlanes();
- if (planes != null) {
- NodalPlane plane1 = planes.getNodalPlane1();
- setProperty(properties, "nodal-plane-1-strike", plane1.getStrike());
- setProperty(properties, "nodal-plane-1-dip", plane1.getDip());
- setProperty(properties, "nodal-plane-1-rake", plane1.getRake());
- NodalPlane plane2 = planes.getNodalPlane2();
- setProperty(properties, "nodal-plane-2-strike", plane2.getStrike());
- setProperty(properties, "nodal-plane-2-dip", plane2.getDip());
- setProperty(properties, "nodal-plane-2-rake", plane2.getRake());
- }
- // add properties for principal axes
- PrincipalAxes axes = mech.getPrincipalAxes();
- if (axes != null) {
- Axis tAxis = axes.getTAxis();
- if (tAxis != null) {
- setProperty(properties, "t-axis-azimuth", tAxis.getAzimuth());
- setProperty(properties, "t-axis-plunge", tAxis.getPlunge());
- setProperty(properties, "t-axis-length", tAxis.getLength(), true);
- }
- Axis nAxis = axes.getNAxis();
- if (nAxis != null) {
- setProperty(properties, "n-axis-azimuth", nAxis.getAzimuth());
- setProperty(properties, "n-axis-plunge", nAxis.getPlunge());
- setProperty(properties, "n-axis-length", nAxis.getLength(), true);
- }
- Axis pAxis = axes.getPAxis();
- if (pAxis != null) {
- setProperty(properties, "p-axis-azimuth", pAxis.getAzimuth());
- setProperty(properties, "p-axis-plunge", pAxis.getPlunge());
- setProperty(properties, "p-axis-length", pAxis.getLength(), true);
- }
- }
- setProperty(properties, "num-stations-used",
- mech.getStationPolarityCount());
- // try to read triggering origin attributes for association
- Origin triggeringOrigin = QuakemlUtils.getOrigin(event,
- mech.getTriggeringOriginID());
- if (triggeringOrigin != null) {
- // set properties for association purposes.
- product.setLatitude(triggeringOrigin.getLatitude().getValue());
- product.setLongitude(triggeringOrigin.getLongitude().getValue());
- product.setEventTime(triggeringOrigin.getTime().getValue());
- // add triggering depth if present
- if (triggeringOrigin.getDepth() != null) {
- product.setDepth(triggeringOrigin.getDepth().getValue()
- .divide(METERS_PER_KILOMETER));
- }
- }
- Tensor tensor = null;
- if (momentTensor != null) {
- setProperty(properties, "percent-double-couple",
- momentTensor.getDoubleCouple());
- setProperty(properties, "scalar-moment",
- momentTensor.getScalarMoment(), true);
- setProperty(properties, "beachball-type",
- momentTensor.getMethodID());
- if (momentTensor.getInversionType() != null) {
- setProperty(properties, "inversion-type",
- momentTensor.getInversionType().value());
- }
- tensor = momentTensor.getTensor();
- if (tensor != null) {
- setProperty(properties, "tensor-mpp", tensor.getMpp(), true);
- setProperty(properties, "tensor-mrp", tensor.getMrp(), true);
- setProperty(properties, "tensor-mrr", tensor.getMrr(), true);
- setProperty(properties, "tensor-mrt", tensor.getMrt(), true);
- setProperty(properties, "tensor-mtp", tensor.getMtp(), true);
- setProperty(properties, "tensor-mtt", tensor.getMtt(), true);
- }
- SourceTimeFunction sourceTimeFunction = momentTensor
- .getSourceTimeFunction();
- if (sourceTimeFunction != null) {
- SourceTimeFunctionType sourceTimeFunctionType = sourceTimeFunction
- .getType();
- if (sourceTimeFunctionType != null) {
- setProperty(properties, "sourcetime-type",
- sourceTimeFunctionType.value());
- }
- setProperty(properties, "sourcetime-duration",
- sourceTimeFunction.getDuration());
- setProperty(properties, "sourcetime-risetime",
- sourceTimeFunction.getRiseTime());
- setProperty(properties, "sourcetime-decaytime",
- sourceTimeFunction.getDecayTime());
- }
- Origin derivedOrigin = QuakemlUtils.getOrigin(event,
- momentTensor.getDerivedOriginID());
- if (derivedOrigin != null) {
- setProperty(properties, "derived-latitude",
- derivedOrigin.getLatitude());
- setProperty(properties, "derived-longitude",
- derivedOrigin.getLongitude());
- RealQuantity depth = derivedOrigin.getDepth();
- if (depth != null) {
- setProperty(properties, "derived-depth", depth.getValue()
- .divide(METERS_PER_KILOMETER));
- }
- setProperty(properties, "derived-eventtime",
- derivedOrigin.getTime());
- }
- Magnitude derivedMagnitude = QuakemlUtils.getMagnitude(event,
- momentTensor.getMomentMagnitudeID());
- if (derivedMagnitude != null) {
- String derivedMagnitudeType = derivedMagnitude.getType();
- setProperty(properties, "derived-magnitude-type",
- derivedMagnitudeType);
- setProperty(properties, "derived-magnitude",
- derivedMagnitude.getMag());
- if (derivedMagnitudeType.equalsIgnoreCase("Mwd")) {
- product.getId().setType("broadband-depth");
- }
- }
- }
- if (!Product.STATUS_DELETE.equals(product.getStatus())) {
- // if not deleting, do some validation
- String type = product.getId().getType();
- if ("focal-mechanism".equals(type) && planes == null) {
- LOGGER.warning("Focal mechanism missing nodal planes");
- return null;
- } else if ("moment-tensor".equals(type) && tensor == null) {
- LOGGER.warning("Moment tensor missing tensor parameters");
- return null;
- }
- }
- return product;
- }
- /**
- * setProperty for RealQuantity values. No exponentials
- * @param properties to add
- * @param name of property
- * @param value of property
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final RealQuantity value) {
- setProperty(properties, name, value, false);
- }
- /**
- * setProperty for RealQuantity values
- * @param properties to add
- * @param name of property
- * @param value of property
- * @param allowExponential if allowed
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final RealQuantity value,
- final boolean allowExponential) {
- if (value == null) {
- return;
- }
- setProperty(properties, name, value.getValue(), allowExponential);
- }
- /**
- * setProperty for strings
- * @param properties to add
- * @param name of property
- * @param value of property
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final String value) {
- if (value == null) {
- return;
- }
- properties.put(name, value);
- }
- /**
- * setProperty for TimeQuantities
- * @param properties to add
- * @param name of property
- * @param value of property
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final TimeQuantity value) {
- if (value == null) {
- return;
- }
- properties.put(name, XmlUtils.formatDate(value.getValue()));
- }
- /**
- * setProperty taking in BigDecimals. No exponentials
- * @param properties to add
- * @param name of property
- * @param value of property
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final BigDecimal value) {
- setProperty(properties, name, value, false);
- }
- /**
- * setProperty taking in BigDecimals
- * @param properties to add
- * @param name of property
- * @param value of property
- * @param allowExponential boolean
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final BigDecimal value,
- final boolean allowExponential) {
- if (value == null) {
- return;
- }
- properties.put(name, allowExponential ? value.toString()
- : value.toPlainString());
- }
- /**
- * setProperty taking in BigIntegers. No exponentials
- * @param properties to add
- * @param name of property
- * @param value of property
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final BigInteger value) {
- if (value == null) {
- return;
- }
- properties.put(name, value.toString());
- }
- /**
- * setProperty taking in Integers
- * @param properties to add
- * @param name of property
- * @param value of property
- */
- public void setProperty(final Map<String, String> properties,
- final String name, final Integer value) {
- if (value == null) {
- return;
- }
- properties.put(name, value.toString());
- }
- /** @param converter FileToQuakeml Converter to set */
- public void setConverter(FileToQuakemlConverter converter) {
- this.converter = converter;
- }
- /** @return FileToQuakeml converter */
- public FileToQuakemlConverter getConverter() {
- return converter;
- }
- @Override
- public boolean isValidate() {
- return validate;
- }
- @Override
- public void setValidate(boolean validate) {
- this.validate = validate;
- }
- /**
- * Implement the ProductCreator interface.
- */
- @Override
- public List<Product> getProducts(File file) throws Exception {
- if (this.converter == null) {
- // preserve quakeml input
- String contents = new String(StreamUtils.readStream(file));
- return this.getQuakemlProducts(contents);
- } else {
- Quakeml quakeml = this.converter.parseFile(file);
- return this.getQuakemlProducts(quakeml);
- }
- }
- /**
- * @return XML contents
- */
- protected Content getContentsXML() {
- StringBuffer buf = new StringBuffer();
- buf.append("<?xml version=\"1.0\"?>\n");
- buf.append("<contents xmlns=\"http://earthquake.usgs.gov/earthquakes/event/contents\">\n");
- buf.append("<file title=\"Earthquake XML (Quakeml)\">\n");
- buf.append("<format type=\"xml\" href=\"").append(QUAKEML_CONTENT_PATH)
- .append("\"/>\n");
- buf.append("</file>\n");
- buf.append("</contents>\n");
- ByteContent content = new ByteContent(buf.toString().getBytes());
- content.setContentType("application/xml");
- return content;
- }
- /** @return boolean sendOriginWhenPhasesExist */
- public boolean isSendOriginWhenPhasesExist() {
- return sendOriginWhenPhasesExist;
- }
- /** @param sendOriginWhenPhasesExist boolean to set */
- public void setSendOriginWhenPhasesExist(boolean sendOriginWhenPhasesExist) {
- this.sendOriginWhenPhasesExist = sendOriginWhenPhasesExist;
- }
- /** @param sendMechanismWhenPhasesExist boolean to set */
- public void setSendMechanismWhenPhasesExist(
- boolean sendMechanismWhenPhasesExist) {
- this.sendMechanismWhenPhasesExist = sendMechanismWhenPhasesExist;
- }
- /** @return sendMechanismWhenPhasesExist boolean */
- public boolean isSendMechanismWhenPhasesExist() {
- return sendMechanismWhenPhasesExist;
- }
- /** @param padForBase64Bug to set */
- public void setPadForBase64Bug(boolean padForBase64Bug) {
- this.padForBase64Bug = padForBase64Bug;
- }
- /** @return padForBase64Bug */
- public boolean isPadForBase64Bug() {
- return padForBase64Bug;
- }
- /**
- * Utility function that converts quakeml to a string
- *
- * @param message
- * The quakeml to be converted
- *
- * @return raw string
- * @throws Exception if quakeml doesn't validate
- */
- private String convertQuakemlToString(Quakeml message) throws Exception{
- return fixRawQuakeml(formatConverter.getString(message,validate));
- }
- /**
- * Fixes base 64 bug: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8222187
- *
- * @param rawMessage
- * the message to edit
- * @return the fixed string
- */
- public String fixRawQuakeml(String rawMessage) {
- if (padForBase64Bug && rawMessage.getBytes().length % 4096 == 1) {
- rawMessage += ' ';
- }
- return rawMessage;
- }
- /**
- * Convert quakeml files to products.
- *
- * @param args
- * a list of files to convert from quakeml to products.
- * @throws Exception if error occurs
- */
- public static void main(final String[] args) throws Exception {
- QuakemlProductCreator creator = new QuakemlProductCreator();
- creator.setSendOriginWhenPhasesExist(true);
- creator.setSendMechanismWhenPhasesExist(true);
- if (args.length == 0) {
- System.err
- .println("Quakeml to product converter utility. "
- + "For visually inspecting products that would be created from quakeml files.");
- System.err.println();
- System.err.println("Usage: QuakemlProductCreator FILE [ FILE ]");
- System.err
- .println("\tFILE - a quakeml file to convert to products, repeat as needed");
- System.exit(1);
- }
- for (String arg : args) {
- File quakeml = new File(arg);
- System.err.println("reading quakeml from "
- + quakeml.getCanonicalPath());
- Iterator<Product> iter = creator.getProducts(quakeml).iterator();
- while (iter.hasNext()) {
- Product next = iter.next();
- new ObjectProductSource(next).streamTo(new XmlProductHandler(
- new StreamUtils.UnclosableOutputStream(System.err)));
- }
- System.err.println();
- }
- }
- }