package edu.sc.seis.sod.source.event; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import edu.iris.Fissures.Quantity; import edu.iris.Fissures.IfEvent.EventAccess; import edu.iris.Fissures.IfEvent.EventAccessOperations; import edu.iris.Fissures.IfEvent.EventAccessSeqHolder; import edu.iris.Fissures.IfEvent.EventSeqIter; import edu.iris.Fissures.IfEvent.EventSeqIterHolder; import edu.iris.Fissures.IfEvent.Magnitude; import edu.iris.Fissures.IfEvent.Origin; import edu.iris.Fissures.model.GlobalAreaImpl; import edu.iris.Fissures.model.MicroSecondDate; import edu.iris.Fissures.model.QuantityImpl; import edu.iris.Fissures.model.UnitImpl; import edu.sc.seis.fissuresUtil.cache.CacheEvent; import edu.sc.seis.fissuresUtil.cache.EventUtil; import edu.sc.seis.fissuresUtil.cache.ProxyEventDC; import edu.sc.seis.fissuresUtil.cache.RetryEventAccessOperations; import edu.sc.seis.fissuresUtil.cache.VestingEventDC; import edu.sc.seis.fissuresUtil.time.MicroSecondTimeRange; import edu.sc.seis.sod.CommonAccess; import edu.sc.seis.sod.ConfigurationException; import edu.sc.seis.sod.SodUtil; import edu.sc.seis.sod.Start; import edu.sc.seis.sod.subsetter.DepthRange; import edu.sc.seis.sod.subsetter.origin.Catalog; import edu.sc.seis.sod.subsetter.origin.Contributor; import edu.sc.seis.sod.subsetter.origin.MagnitudeRange; import edu.sc.seis.sod.subsetter.origin.OriginDepthRange; public class EventDCQuerier { public EventDCQuerier(String serverName, String serverDNS, int numRetries, Element config) throws ConfigurationException { this.serverName = serverName; this.serverDNS = serverDNS; this.numRetries = numRetries; NodeList childNodes = config.getChildNodes(); List configCatalogs = new ArrayList(); List configContributors = new ArrayList(); for(int counter = 0; counter < childNodes.getLength(); counter++) { Node node = childNodes.item(counter); if(node instanceof Element) { String tagName = ((Element)node).getTagName(); if(!tagName.equals("name") && !tagName.equals("dns") && !tagName.equals("retries") && !tagName.equals("originTimeRange")) { Object object = SodUtil.load((Element)node, new String[] {"eventArm", "origin"}); if(tagName.equals("originDepthRange")) { DepthRange dr = ((OriginDepthRange)object); minDepth = dr.getMinDepth(); maxDepth = dr.getMaxDepth(); } else if(tagName.equals("magnitudeRange")) { magRange = (MagnitudeRange)object; } else if(object instanceof edu.iris.Fissures.Area) { area = (edu.iris.Fissures.Area)object; } else if(tagName.equals("catalog")) { configCatalogs.add(((Catalog)object).getCatalog()); } else if(tagName.equals("contributor")) { configContributors.add(((Contributor)object).getContributor()); } } } } catalogs = (String[])configCatalogs.toArray(new String[configCatalogs.size()]); contributors = (String[])configContributors.toArray(new String[configContributors.size()]); } public ProxyEventDC getEventDC() { if(eventDC == null) { eventDC = new VestingEventDC(serverName, serverDNS, CommonAccess.getNameService(), Start.createRetryStrategy(getRetries())); } return eventDC; } public CacheEvent[] query(MicroSecondTimeRange tr) { logger.debug("querying for events from " + tr); EventAccessOperations[] events; EventSeqIterHolder holder = new EventSeqIterHolder(); events = getEvents(tr, holder); logger.debug("got " + events.length + " events from query " + tr); if(holder.value != null) { // might be events in the iterator... LinkedList allEvents = new LinkedList(); for(int j = 0; j < events.length; j++) { allEvents.add(events[j]); } EventSeqIter iterator = holder.value; EventAccessSeqHolder eHolder = new EventAccessSeqHolder(); while(iterator.how_many_remain() > 0) { iterator.next_n(sequenceMaximum, eHolder); EventAccess[] iterEvents = eHolder.value; for(int j = 0; j < iterEvents.length; j++) { allEvents.add(iterEvents[j]); } } events = (EventAccessOperations[])allEvents.toArray(new EventAccessOperations[0]); } CacheEvent[] cached = cacheEvents(events); Arrays.sort(cached, new Comparator() { public int compare(Object first, Object second) { MicroSecondDate firstOrigin = new MicroSecondDate(((CacheEvent)first).getOrigin().getOriginTime()); MicroSecondDate secondOrigin = new MicroSecondDate(((CacheEvent)second).getOrigin().getOriginTime()); return firstOrigin.compareTo(secondOrigin); } }); return cached; } private EventAccessOperations[] getEvents(MicroSecondTimeRange tr, EventSeqIterHolder holder) { return getEventDC().a_finder() .query_events(area, minDepth, maxDepth, tr.getFissuresTimeRange(), magRange.getSearchTypes(), (float)magRange.getMinValue(), (float)magRange.getMaxValue(), catalogs, contributors, sequenceMaximum, holder); } private CacheEvent[] cacheEvents(EventAccessOperations[] uncached) { CacheEvent[] cached = new CacheEvent[uncached.length]; for(int counter = 0; counter < cached.length; counter++) { if(uncached[counter] instanceof CacheEvent) { cached[counter] = (CacheEvent)uncached[counter]; } else { cached[counter] = new CacheEvent(new RetryEventAccessOperations(uncached[counter], 3)); } cached[counter].get_attributes(); // Call get_origins to cache it, and reorder the magnitudes so // that one that passed is first while we're at it Origin[] origins = cached[counter].get_origins(); for(int i = 0; i < origins.length; i++) { putPassingMagFirst(origins[i], magRange); } putPassingMagFirst(EventUtil.extractOrigin(cached[counter]), magRange); } return cached; } /** * Reorder the magnitudes in o such that a magnitude >= minMag and <= maxMag * with a type in searchTypes is in the 0th position of the magnitudes array * * @return - True if a magnitude is found and moved into the 0th position */ public static boolean putPassingMagFirst(Origin o, MagnitudeRange magRange) { Magnitude[] acceptable = magRange.getAcceptable(o.getMagnitudes()); if(acceptable.length > 0) { Magnitude zeroth = o.getMagnitudes()[0]; for(int i = 0; i < o.getMagnitudes().length; i++) { if(o.getMagnitudes()[i].equals(acceptable[0])) { o.getMagnitudes()[0] = acceptable[0]; o.getMagnitudes()[i] = zeroth; return true; } } } return false; } public String toString() { return "EventDCQuerier(" + serverDNS + "/" + serverName + ")"; } public int getRetries() {return numRetries;} public String[] getCatalogs() { return catalogs; } public String[] getContributors() { return contributors; } public QuantityImpl getMinDepth() { return minDepth; } public QuantityImpl getMaxDepth() { return maxDepth; } public String getServerName() { return serverName; } public String getServerDNS() { return serverDNS; } public MagnitudeRange getMagRange() { return magRange; } public edu.iris.Fissures.Area getArea() { return area; } private int sequenceMaximum = 100; private ProxyEventDC eventDC; private String[] catalogs, contributors; private QuantityImpl minDepth = new QuantityImpl(-90000.0, UnitImpl.KILOMETER); private QuantityImpl maxDepth = new QuantityImpl(90000.0, UnitImpl.KILOMETER); private String serverName, serverDNS; private MagnitudeRange magRange = new MagnitudeRange(); private edu.iris.Fissures.Area area = new GlobalAreaImpl(); private int numRetries; private static Logger logger = LoggerFactory.getLogger(EventDCQuerier.class); }