Skip to content
Snippets Groups Projects
Commit cda67320 authored by Robert Butora's avatar Robert Butora
Browse files

links to vlkb-volib with support for coord-system params (POSSYS BANDSYS...

links to vlkb-volib with support for coord-system params (POSSYS BANDSYS TIMESYS) and their defaults from settings-file
parent 4b0fd09d
Branches
Tags
No related merge requests found
Showing
with 46 additions and 795 deletions
import vo.parameter.*;
class Coord
{
......
/* REC-SODA BAND parameter defines the interval(s) to be extracted
from the data using a floating point interval (xtype="interval") as defined
in DALI. */
class Band
{
public enum System {WAVE_Barycentric, VELO_LSRK, NONE};
System system;
double wavelength[];
public Band(String str)
{
this.wavelength = Parser.getDaliIntervalPositiveValues(str, "BAND");
}
public Band(double low, double up)
{
wavelength = new double[2];
wavelength[0] = low;
wavelength[1] = up;
}
public void setSystem(Band.System system) { this.system = system; }
public String toString()
{
return "BAND " + wavelength[0] + " " + wavelength[1];
}
}
/* REC-SODA: UCD describing the CIRCLE parameter is pos.outline;obs.*/
/* REC-DALI Sect 3.3.6 Circle: definition */
class Circle
{
double lon;
double lat;
double radius;
public Circle(String value)
{
parseCircle(value);
}
private void parseCircle(String str)
{
String[] arr = str.strip().split(" +");
if(arr == null)
throw new IllegalArgumentException("CIRCLE : no value, or value contains no space");
else
{
final int len = 3;
if(arr.length != len)
throw new IllegalArgumentException(
"CIRCLE : must have " + len + " elements delimited by space, but found " + arr.length);
else
{
double dbl = Double.parseDouble(arr[0]);
if ((dbl < 0) || (dbl > 360))
throw new IllegalArgumentException("CIRCLE : first number must be in range [0,360] but found " + dbl);
else
this.lon = dbl;
dbl = Double.parseDouble(arr[1]);
if ((dbl < -90) || (dbl > 90))
throw new IllegalArgumentException("CIRCLE : second number must be in range [-90,90] but found " + dbl);
else
this.lat = dbl;
dbl = Double.parseDouble(arr[2]);
if ((dbl <= 0) || (dbl > 180))
throw new IllegalArgumentException("CIRCLE : third number must be in range (0,180] but found " + dbl);
else
this.radius = dbl;
}
}
}
public String toString()
{
return "CIRCLE " + Double.valueOf(lon) + " " + Double.valueOf(lat) + " " + Double.valueOf(radius);
}
}
public class MultiValuedParamNotSupported extends IllegalArgumentException {
public MultiValuedParamNotSupported(String errorMessage){//, Throwable err) {
super(errorMessage);//, err);
}
}
import java.util.Map;
class Parser
{
public static String getFirstString(Map<String, String[]> params, String key)
{
String[] values = params.get(key);
if (values == null) return null;
if (values.length < 1)
throw new IllegalArgumentException(key + " has no valid value");
else
return values[0];// FIXME if values[0] is null -> canot distinguish from key not found
}
public static String[] getFirstStringArray(Map<String, String[]> params, String key, String separator, int arrayLength)
{
String array = getFirstString(params, key);
if (array == null) return null;
String[] stringArray = array.split(separator);
if(stringArray.length != arrayLength)
throw new IllegalArgumentException(
key + " parameter has incorrect number of elements ("
+ stringArray.length + " vs " + arrayLength + ") or incorrect separator used");
return stringArray;
}
public static double[] getDaliIntervalPositiveValues(String value, String errorMsgPrefix)
{
String[] arr = value.strip().split(" +");
double[] dblArr = new double[2];
if(arr == null)
throw new IllegalArgumentException(errorMsgPrefix + " : no value, or value contains no space");
else
{
final int len = 2;
if(arr.length != len)
throw new IllegalArgumentException(
errorMsgPrefix + " : must have " + len + " space-delimited elements, but found " + arr.length);
else
{
String val = arr[0];
if(val.equals("Inf") || val.equals("+Inf"))
{
dblArr[0] = Double.POSITIVE_INFINITY;
}
else
{
double dbl = Double.parseDouble(val);
if (dbl < 0)
throw new IllegalArgumentException(errorMsgPrefix + " : values must be positive, but first value was " + dbl);
else
dblArr[0] = dbl;
}
val = arr[1];
if(val.equals("-Inf"))
{
// dblArr[1] = Double.NEGATIVE_INFINITY;
throw new IllegalArgumentException(errorMsgPrefix + " : values must be positive, but second value was " + val);
}
else
{
double dbl = Double.parseDouble(val);
if (dbl < 0)
throw new IllegalArgumentException(errorMsgPrefix + " : values must be positive, but second value was " + dbl);
else
dblArr[1] = dbl;
}
}
}
return dblArr;
}
}
/* REC ObsCore B.6.5.1. List of polarization states (pol_states)
... polarization labels inspired from the FITS specification. See Table 7 in FITS WCS Paper 1
(Greisen et Calabretta 2002) . Labels are combined using symbols from the
{I Q U V RR LL RL LR XX YY XY YX POLI POLA} set
and separated by a / character. A leading / character must start the list and
a trailing / character must end it. It should be ordered following the above list, compatible with
the FITS list table for polarization definition.
*/
// NOTE POLI POLA is not in FITS STOKES other match and are defined in FITS as: I=1...V=4 and RR=-1...YX=-8
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
class Pol
{
final static Set<String> POL_STATES
= new HashSet<>(Arrays.asList("I", "Q", "U", "V", "RR", "LL", "RL", "LR", "XX", "YY", "XY", "YX"));
String[] states;
Pol(String[] values)
{
for(String pol : values)
if(!POL_STATES.contains(pol))
throw new IllegalArgumentException("POL value is " + pol +" but must be one of " + String.join(" ", POL_STATES));
this.states = values;
}
public String toString()
{
return "POL " + String.join(" ", states);
}
}
/* REC DALI 3.3.7 Polygon
In spherical coordinates, all longitude values must fall within [0,360] and
all latitude values within [-90,90]. Vertices must be ordered such that the
polygon winding direction is counter-clockwise (when viewed from the origin
toward the sky) as described in (Rots, 2007).
Rots, A. (2007), 'Space-time coordinate metadata for the virtual observa-
tory', IVOA Recommendation.
http://www.ivoa.net/documents/latest/STC.html :
4.5.1.4 Polygon
....
In order to avoid ambiguities in direction, vertices need to be less
than 180 deg apart in both coordinates. Great circles or small circles spanning 180 deg
require specification of an extra intermediate vertex.
....
The boundaries are considered part of the region. The inside of the region is
defined as that part of coordinate space that is encircled by the polygon in a
counter-clockwise sense.
...
*/
class Polygon
{
double[] lon;
double[] lat;
public Polygon(String value)
{
parsePolygon(value);
}
private void parsePolygon(String str)
{
String[] arr = str.strip().split(" +");
if(arr == null)
throw new IllegalArgumentException("POLYGON : no value, or value contains no space");
else
{
final int minLen = 3*2; // REC SODA : at least 3 (lon,lat) points
if(arr.length < minLen)
throw new IllegalArgumentException(
"POLYGON : must have at least " + minLen + " elements delimited by space, but found " + arr.length);
else
{
boolean isEven = ((arr.length % 2) == 0);
if(!isEven)
throw new IllegalArgumentException("POLYGON must have even number of values, but has " + arr.length);
lon = new double[arr.length/2];
lat = new double[arr.length/2];
for(int ii=0; ii<(arr.length-1); ii+=2)
{
double dbl = Double.parseDouble(arr[ii]);
if ((dbl < 0) || (dbl > 360))
throw new IllegalArgumentException("POLYGON : first number must be in range [0,360] but found " + dbl);
else
this.lon[ii/2] = dbl;
dbl = Double.parseDouble(arr[ii+1]);
if ((dbl < -90) || (dbl > 90))
throw new IllegalArgumentException("POLYGON : second number must be in range [-90,90] but found " + dbl);
else
this.lat[ii/2] = dbl;
}
}
}
}
public String toString()
{
StringBuilder sb = new StringBuilder("POLYGON");
int ii = 0;
for(ii = 0; ii<lon.length; ii++)
sb.append(" (" + String.valueOf(lon[ii]) + ", " + String.valueOf(lat[ii]) + ")");
return sb.toString();
}
}
import java.util.logging.Logger;
class Pos
{
protected static final Logger LOGGER = Logger.getLogger("Pos");
enum System {NONE, ICRS, GALACTIC};
String shape;
String value;
System system;
Circle circle;
Range range;
Polygon polygon;
public Pos(Circle circle) {this.shape = "CIRCLE"; this.circle = circle;};
public Pos(Range range) {this.shape = "RANGE"; this.range = range;};
public Pos(Polygon polygon) {this.shape = "POLYGON"; this.polygon = polygon;};
public Pos(String value)
{
LOGGER.info("trace: " + value);
parsePos(value);
}
private void parsePos(String str)
{
String strArr[] = str.strip().split(" +", 2);
if(strArr.length > 1)
{
this.shape = strArr[0].strip();
this.value = strArr[1].strip();
}
else
{
throw new IllegalArgumentException("POS value must have more then one space-separated elements but had "
+ strArr.length + " elements)");
}
if(this.shape.equals("CIRCLE"))
{
this.circle = new Circle(this.value);
}
else if(this.shape.equals("RANGE"))
{
this.range = new Range(this.value);
}
else if(this.shape.equals("POLYGON"))
{
this.polygon = new Polygon(this.value);
}
else
{
throw new IllegalArgumentException("Valid POS shape is CIRCLE or RANGE or POLYGON but was: " + this.shape);
}
}
public void setSystem(Pos.System system) { this.system = system; }
public String toString()
{
String shapeStr;
if(this.shape.equals("CIRCLE"))
{
shapeStr = this.circle.toString();
}
else if(this.shape.equals("RANGE"))
{
shapeStr = this.range.toString();
}
else if(this.shape.equals("POLYGON"))
{
shapeStr = this.polygon.toString();
}
else
{
throw new IllegalArgumentException("Valid POS shape is CIRCLE or RANGE or POLYGON but was: " + this.shape);
}
return "POS: " + shapeStr;
}
}
import java.util.Arrays;
class Range
{
double lon1, lon2;
double lat1, lat2;
public Range(String value)
{
parseRange(value);
}
public Range(double lonCenter, double latCenter, double lonWidth, double latWidth)
{
lon1 = lonCenter - lonWidth/2.0;
lon2 = lonCenter + lonWidth/2.0;
lat1 = latCenter - latWidth/2.0;
lat2 = latCenter + latWidth/2.0;
}
public Range(Circle circle)
{
lon1 = circle.lon - circle.radius;
lon2 = circle.lon + circle.radius;
lat1 = circle.lat - circle.radius;
lat2 = circle.lat + circle.radius;
}
public Range(Polygon polygon)
{
lon1 = Arrays.stream(polygon.lon).min().getAsDouble();
lon2 = Arrays.stream(polygon.lon).max().getAsDouble();
lat1 = Arrays.stream(polygon.lat).min().getAsDouble();
lat2 = Arrays.stream(polygon.lat).max().getAsDouble();
}
private void parseRange(String str)
{
String[] arr = str.strip().split(" +");
if(arr == null)
throw new IllegalArgumentException("RANGE : no value, or value contains no space");
else
{
final int len = 4;
if(arr.length != len)
throw new IllegalArgumentException(
"RANGE : must have " + len + " elements delimited by space, but found " + arr.length);
else
{
double dbl = Double.parseDouble(arr[0]);
if ((dbl < 0) || (dbl > 360))
throw new IllegalArgumentException("RANGE : first number must be in range [0,360] but found " + dbl);
else
this.lon1 = dbl;
dbl = Double.parseDouble(arr[1]);
if ((dbl < 0) || (dbl > 360))
throw new IllegalArgumentException("RANGE : first number must be in range [0,360] but found " + dbl);
else
this.lon2 = dbl;
dbl = Double.parseDouble(arr[2]);
if ((dbl < -90) || (dbl > 90))
throw new IllegalArgumentException("RANGE : second number must be in range [-90,90] but found " + dbl);
else
this.lat1 = dbl;
dbl = Double.parseDouble(arr[3]);
if ((dbl < -90) || (dbl > 90))
throw new IllegalArgumentException("RANGE : second number must be in range [-90,90] but found " + dbl);
else
this.lat2 = dbl;
}
}
}
public String toString()
{
String str = "RANGE " + Double.valueOf(lon1) + " " + Double.valueOf(lon2)
+ " " + Double.valueOf(lat1) + " " + Double.valueOf(lat2);
return str;
}
}
/* FIXME contains also VLKB-legacy params which will be removed once clients can do SODA */
public enum SodaParam
{
ID, POS, CIRCLE, POLYGON, BAND, TIME, POL,
skysystem, specsystem,
pubdid,l,b,r,dl,db,vtype,vl,vu,nullvals
}
import java.util.logging.Logger;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
class SodaParser
{
protected static final Logger LOGGER = Logger.getLogger(ServletCutout.class.getName());
//public class SodaParamMap extends HashMap<SodaParam, String[]> {};
Map<SodaParam, String[]> params;
Pos pos;
Band band;
Time time;
Pol pol;
public SodaParser(Map<SodaParam, String[]> params)
{
LOGGER.info("trace - there are " + params.size() + " params");
this.params = params;
}
/* return null if value not present or the value if present exactly once
* else throw MultiplicityNotSupoorted SODA_error
*/
private String soda_getSingleValue(SodaParam name)
{
LOGGER.info("trace");
String[] valArr = params.get(name);
if(valArr == null)
return null;
else
if(valArr.length == 0)
return null;
else if(valArr.length == 1)
{
LOGGER.info("ParamFound " + name.toString() + " : " + valArr[0]);
return valArr[0];
}
else
throw new MultiValuedParamNotSupported(name + " was found " + valArr.length + " times");
}
/*
public String sodaReq_getResponseFormat(SodaParamMap params, String defaultResponseFormat)
{
String respFormat = soda_getSingleValue(params, "RESPONSEFORMAT");
return ((respFormat == null) ? defaultResponseFormat : respFormat);
}
*/
public boolean sodaReq_hasSodaId()
{
String id = soda_getSingleValue(SodaParam.ID);
return (id != null);
}
public String sodaReq_getId()
{
String pubdid = soda_getSingleValue(SodaParam.ID);
if(pubdid == null)
throw new IllegalArgumentException("ID is missing, but is mandatory");
else
return pubdid;
}
public Pos sodaReq_getPosCirclePolygon()
{
String valuePos = soda_getSingleValue(SodaParam.POS);
String valueCircle = soda_getSingleValue(SodaParam.CIRCLE);
String valuePolygon = soda_getSingleValue(SodaParam.POLYGON);
Pos pos = null;
if( (valuePos != null) && (valueCircle == null) && (valuePolygon == null) )
{
pos = new Pos(valuePos);
LOGGER.info(pos.toString());
}
else if( (valuePos == null) && (valueCircle != null) && (valuePolygon == null) )
{
Circle circle = new Circle(valueCircle);
LOGGER.info(circle.toString());
pos = new Pos(circle);
}
else if( (valuePos == null) && (valueCircle == null) && (valuePolygon != null) )
{
Polygon polygon = new Polygon(valuePolygon);
LOGGER.info(polygon.toString());
pos = new Pos(polygon);
}
else
{
throw new IllegalArgumentException("Exactly one of POS | CIRCLE | POLYGON must be given.");
}
return pos;
}
public Band sodaReq_getBand()
{
String value = soda_getSingleValue(SodaParam.BAND);
if(value == null)
return null;
else
return new Band(value);
}
public Time sodaReq_getTime()
{
String value = soda_getSingleValue(SodaParam.TIME);
if(value == null)
return null;
else
return new Time(value);
}
public Pol sodaReq_getPol()
{
String[] valArr = params.get(SodaParam.POL);
if(valArr == null)
return null;
else if(valArr.length < 1)
return null;
else
{
LOGGER.info("ParamFound " + SodaParam.POL.toString() + " : " + Arrays.toString(valArr));
return new Pol(valArr);
}
}
/* VLKB */
public String vlkbReq_getPubdid()
{
String pubdid = soda_getSingleValue(SodaParam.pubdid);
if(pubdid == null)
throw new IllegalArgumentException(SodaParam.pubdid.toString() + " is missing, but is mandatory");
else
return pubdid;
}
public Pos vlkbReq_getCircleRect()
{
Pos pos = null;
String l_value = soda_getSingleValue(SodaParam.l);
String b_value = soda_getSingleValue(SodaParam.b);
if( (l_value != null) && (b_value != null ) )
{
String r_value = soda_getSingleValue(SodaParam.r);
if(r_value != null)
{
Circle circle = new Circle(l_value + " " + b_value + " " + r_value);
pos = new Pos(circle);
}
else
{
String dl_value = soda_getSingleValue(SodaParam.dl);
String db_value = soda_getSingleValue(SodaParam.db);
if((dl_value != null) && (db_value != null))
{
double l = Double.parseDouble(l_value);
double b = Double.parseDouble(b_value);
double dl = Double.parseDouble(dl_value);
double db = Double.parseDouble(db_value);
Range range = new Range(l, b, dl, db);
pos = new Pos(range);
}
else
{
throw new IllegalArgumentException("one of 'r' or '(dl,db)' pair must be provided to designate sky area");
}
}
}
else
{
throw new IllegalArgumentException("VLKB sky position center (l,b) is missing however is mandatory");
}
return pos;
}
public Band vlkbReq_getVelocity()
{
Band band = null;
String cvlow = soda_getSingleValue(SodaParam.vl);
String cvup = soda_getSingleValue(SodaParam.vu);
//String cvtype = soda_getSingleValue(params, "vtype"); // "1"=VELO_LSRK or "2"=WAVE_Barycentirc
boolean vel_valid = (cvlow != null) && (cvup != null);
if(vel_valid)
{
double vel_low = Double.parseDouble(cvlow);
double vel_up = Double.parseDouble(cvup);
band = new Band(vel_low, vel_up);
}
return band;
}
public boolean vlkbReq_getNullValues()
{
return (null != soda_getSingleValue(SodaParam.nullvals));
}
}
/* SODA 3.3.5 TIME
...numeric values interpreted as Modified Julian Date(s) in UTC.
As in DALI, open intervals use -Inf or +Inf as one limit.
*/
class Time
{
enum System {MJD_UTC, NONE};
System system;
double mjdUtc[];
public Time(String value)
{
mjdUtc = Parser.getDaliIntervalPositiveValues(value, "TIME");
}
public void setSystem(Time.System system) { this.system = system; }
public String toString()
{
return "TIME " + mjdUtc[0] + " " + mjdUtc[1];
}
}
......@@ -9,6 +9,8 @@ import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.time.Instant;//Timestamp in cut-filename
import vo.parameter.*;
public interface Cutout
{
......
......@@ -26,6 +26,8 @@ import java.nio.file.Paths;
import java.time.*;// Timestamp in cut-filename
import java.io.ByteArrayOutputStream; // for SODA direct streaming doSubimgStream
import vo.parameter.*;
class CutoutImpl implements Cutout
{
static final Logger LOGGER = Logger.getLogger(DatasetsImpl.class.getName());
......
......@@ -8,6 +8,7 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import vo.parameter.*;
public class JsonEncoder
{
......
......@@ -6,6 +6,7 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import vo.parameter.*;
public class JsonEncoderMerge
{
......
......@@ -21,6 +21,8 @@ import javax.servlet.http.Part;
import javax.servlet.http.HttpServletRequestWrapper;
import java.security.Principal;
import vo.parameter.*;
@javax.servlet.annotation.MultipartConfig
public class MonitorFilter implements Filter
{
......
......@@ -41,6 +41,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import vo.parameter.*;
public class ServletCutout extends javax.servlet.http.HttpServlet
{
......@@ -104,7 +105,7 @@ public class ServletCutout extends javax.servlet.http.HttpServlet
Resolver rsl = new ResolverFromId();
rsl.resolve(id);
if(pos != null) pos.setSystem(Pos.System.valueOf(DEFAULT_SKY_SYSTEM));
// if(pos != null) pos.setSystem(Pos.System.valueOf(DEFAULT_SKY_SYSTEM));
if(band != null) band.setSystem(Band.System.valueOf(DEFAULT_SPEC_SYSTEM));
if(time != null) time.setSystem(Time.System.valueOf(DEFAULT_TIME_SYSTEM));
......@@ -261,18 +262,18 @@ public class ServletCutout extends javax.servlet.http.HttpServlet
writer.close();
}
private Map<SodaParam, String[]> collectSodaParams(HttpServletRequest req)
/*
private Map<VoParam, String[]> collectSodaParams(HttpServletRequest req)
{
Map<SodaParam, String[]> params = new HashMap<SodaParam, String[]>();
for(SodaParam paramToken : SodaParam.values())
Map<VoParam, String[]> params = new HashMap<VoParam, String[]>();
for(VoParam paramToken : VoParam.values())
{
String[] paramValue = req.getParameterValues(paramToken.toString());
params.put(paramToken, paramValue);
}
return params;
}
*/
protected void convertHttpToSoda(HttpServletRequest request, HttpServletResponse response)
......@@ -283,7 +284,7 @@ public class ServletCutout extends javax.servlet.http.HttpServlet
try
{
Map<SodaParam, String[]> params = collectSodaParams(request);
/*/Map<SodaParam, String[]> params = collectSodaParams(request);
SodaParser parser = new SodaParser(params);
String id = null;
......@@ -306,6 +307,20 @@ public class ServletCutout extends javax.servlet.http.HttpServlet
pos = parser.vlkbReq_getCircleRect();
band = parser.vlkbReq_getVelocity();
}
*/
Map<String, String[]> params = request.getParameterMap();
String id = SingleStringParam.parseSingleStringParam(params, "ID");
Pos pos = Pos.parsePos(params, DEFAULT_SKY_SYSTEM);
Band band = Band.parseBand(params, DEFAULT_SPEC_SYSTEM);
Time time = Time.parseTime(params, DEFAULT_TIME_SYSTEM);
Pol pol = Pol.parsePol(params);
String respFormat = sodaReq_getResponseFormat(request, DEFAULT_RESPONSEFORMAT);
......
......@@ -34,7 +34,7 @@ import java.util.TimeZone;
import java.security.Principal;
import vo.parameter.*;
public class ServletMerge extends javax.servlet.http.HttpServlet
{
......@@ -88,7 +88,7 @@ public class ServletMerge extends javax.servlet.http.HttpServlet
try
{
Map<SodaParam, String[]> params = collectSodaParams(request);
/* Map<SodaParam, String[]> params = collectSodaParams(request);
SodaParser parser = new SodaParser(params);
String id = null;
......@@ -111,6 +111,17 @@ public class ServletMerge extends javax.servlet.http.HttpServlet
pos = parser.vlkbReq_getCircleRect();
band = parser.vlkbReq_getVelocity();
}
*/
Map<String, String[]> params = request.getParameterMap();
String id = null;
Pos pos = null;
Band band = null;
Time time = null;
Pol pol = null;
String respFormat = DEFAULT_RESPONSEFORMAT;//sodaReq_getResponseFormat(request, DEFAULT_RESPONSEFORMAT);
......@@ -179,7 +190,7 @@ public class ServletMerge extends javax.servlet.http.HttpServlet
LOGGER.info("processRequest normal exit");
}
/*
private Map<SodaParam, String[]> collectSodaParams(HttpServletRequest req)
{
Map<SodaParam, String[]> params = new HashMap<SodaParam, String[]>();
......@@ -190,7 +201,7 @@ public class ServletMerge extends javax.servlet.http.HttpServlet
}
return params;
}
*/
/* semi-colon separated list of pudids convert to arra */
private String[] parseLegacyPubdidArr(String pubdids)
......
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment