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

cutout: modifies SodaImpl to use vlkb-cutout instead on two calls to vlkb-overlap + vlkb-imcopy

parent 44eb0c26
Branches
Tags
No related merge requests found
......@@ -32,13 +32,12 @@ int stream_cutout(string pathname, int extnum, string region)
string pixfilter{ to_cfitsio_format(bnds) };
imcopy(pathname, extnum, pixfilter);
return EXIT_SUCCESS;
// pixfilter must be within NAXIS[] otherwise cfitsio-error
return 0; // EXIT_SUCCESS
}
else if((ov_code == 1) || (ov_code == 6))
{
// no overlap
return EXIT_SUCCESS;
return 1; // no overlap EXIT_SUCCESS
}
else
{
......@@ -47,7 +46,6 @@ int stream_cutout(string pathname, int extnum, string region)
}
// ----------------------------------------------------------------------------------
int fits_copy_image_section2(
......
......@@ -259,10 +259,16 @@ int cmd_cutout(int argc, char * argv[])
if (argc != 4)
{
std::cerr
<< "Usage: cutout <filename.fits> <extnum> <region>\n"
<< "\n"
<< "Calculate overlap between HDU in file and region.\n\nregion in JSON form of VO-SODA params. For example 'POS=CIRCLE 21.4458 -1.373 0.1' :\n"
" \'{\"pos\":{\"circle\":{\"lat\":-1.373,\"lon\":21.4458,\"radius\":0.1},\"system\":\"ICRS\"},\"service\":\"SUBIMG\"}\'\n";
<< "Usage: cutout <filename.fits> <extnum> <region>"
<< endl
<< endl
<< "Calculate overlap between HDU in file and region. Returns 0 (ok), 1 (no overlap) or EXIT_FAILURE"
<< endl
<< endl
<< "region in JSON form of VO-SODA params. For example 'POS=CIRCLE 21.4458 -1.373 0.1' :"
<< endl
<< " \'{\"pos\":{\"circle\":{\"lat\":-1.373,\"lon\":21.4458,\"radius\":0.1},\"system\":\"ICRS\"},\"service\":\"SUBIMG\"}\'"
<< endl;
return EXIT_FAILURE;
}
else
......@@ -272,8 +278,8 @@ int cmd_cutout(int argc, char * argv[])
string region{argv[3]};
int rc = stream_cutout(pathname, extnum, region);
if(!rc)
return EXIT_SUCCESS;
if( (rc == 0) || (rc == 1))
return rc; // OK or no overlap
}
return EXIT_FAILURE;
}
......
......@@ -14,7 +14,7 @@ import vo.parameter.*;
public interface Soda
{
public void doStream(String relPathname, int hdunum,
public int doStream(String relPathname, int hdunum,
Pos pos, Band band, Time time, Pol pol, String pixels,
OutputStream outputStream) throws IOException, InterruptedException;
......
......@@ -43,32 +43,28 @@ class SodaImpl implements Soda
}
public void doStream(String relPathname, int hdunum,
public int doStream(String relPathname, int hdunum,
Pos pos, Band band, Time time, Pol pol, String pixels,
OutputStream outputStream) throws IOException, InterruptedException
{
LOGGER.fine("trace");
Instant start = Instant.now();
LOGGER.fine("trace");
boolean has_overlap = false;
boolean pixels_valid = (pixels != null);
String boundsString = "";
if(outputStream == null)
LOGGER.finest("supplied outputStream for cut-file is null");
// FIXME throw excpetion here
final boolean isDavCall = relPathname.startsWith("http://") || relPathname.startsWith("https://");
final boolean isAbsPath = relPathname.startsWith("/"); // Resolver removes schema from file://
//boolean pixels_valid = (pixels != null);
//final boolean isDavCall = relPathname.startsWith("http://")
// || relPathname.startsWith("https://");
//final boolean isAbsPath = relPathname.startsWith("/"); // Resolver removes schema from file://
// file:///some_abs_path -> /soma_abs_path
// file://some_rel_path -> some_rel_path
//String absPathname = (isDavCall || isAbsPath) ? relPathname
// : (fitsPaths.surveys() +"/"+ relPathname);
String absPathname = (isDavCall || isAbsPath) ? relPathname : (fitsPaths.surveys() +"/"+ relPathname);
if( !pixels_valid )
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if(bos == null)
throw new AssertionError("byte output stream for bounds was not created, is null");
boolean has_overlap = false;
String boundsString = "";
JsonEncoder jReq = new JsonEncoder();
jReq.add(pos);
jReq.add(band);
......@@ -77,203 +73,37 @@ class SodaImpl implements Soda
String coordString = jReq.toString();
LOGGER.finest("coordString: " + coordString);
/* calc bounds */
String[] cmdBounds = new String[4];
cmdBounds[0] = "/usr/local/bin/vlkb";
cmdBounds[1] = "overlap";
cmdBounds[2] = absPathname;
cmdBounds[3] = coordString;
LOGGER.finest(String.join(" ", cmdBounds));
String[] cmd = new String[5];
cmd[0] = "/usr/local/bin/vlkb";
cmd[1] = "cutout";
cmd[2] = fitsPaths.surveys() + "/" + relPathname;
cmd[3] = String.valueOf(hdunum);
cmd[4] = coordString;
LOGGER.finest(String.join(" ", cmd));
ExecCmd execBounds = new ExecCmd();
execBounds.doRun(bos, cmdBounds);
LOGGER.finest("execBounds exitValue: " + execBounds.exitValue);
boolean has_result = (execBounds.exitValue == 0);
if(has_result)
{
boundsString = new String(bos.toByteArray());
StringBuilder errorStrBuilder = new StringBuilder();
/* FIXME disable GRID not supported
boundsString = replaceWithGrid(boundsString, pos, band, time, pol);
LOGGER.finest("boundsString(with GRID): " + boundsString);
*/
LOGGER.warning("GRID support was disabled");
has_overlap = !((boundsString != null) && boundsString.trim().isEmpty());
ExecCmd exec = new ExecCmd();
exec.doRun(outputStream, cmd, errorStrBuilder);
int rc = exec.exitValue;
LOGGER.finest("exec cutout exitValue: " + rc);
LOGGER.finer("EXECTIME cutoutDone: " + Duration.between(start, Instant.now()));
if( !has_overlap )
if(rc == 0)
{
throw new IllegalArgumentException(
"region in file does not overlap with region defined by SODA parameters");
}
return rc; // OK
}
bos.close();
Instant boundsDone = Instant.now();
LOGGER.finer("EXECTIME boundsDone: " + Duration.between(start, boundsDone));
}
if(has_overlap || pixels_valid)
else if(rc == 1)
{
/* cutout -> outputStream */
String pixFilterString = pixels_valid ? pixels : boundsString;
String[] cmdCut = new String[5];
cmdCut[0] = "/usr/local/bin/vlkb";
cmdCut[1] = isDavCall ? "imcopydav" : "imcopy";
cmdCut[2] = absPathname;
cmdCut[3] = String.valueOf(hdunum-1);
cmdCut[4] = pixFilterString;
LOGGER.finest(String.join(" ", cmdCut));
if(outputStream == null)
LOGGER.finest("supplied outputStream for cut-file is null");
ExecCmd execCut = new ExecCmd();
execCut.doRun(outputStream, cmdCut);
LOGGER.finest("execCut exitValue: " + execCut.exitValue);
boolean cut_successful = (execCut.exitValue == 0);
if(!cut_successful)
{
throw new IllegalArgumentException("cut by pixels not completed for pixels : " + pixFilterString);
}
Instant cutDone = Instant.now();
LOGGER.finer("EXECTIME cutDone: " + Duration.between(start, cutDone));
return rc; // OK, but no overlap
}
else
{
throw new IllegalArgumentException(
"overlap computation could not be completed with the given arguments");
"overlap computation could not be completed with the given arguments. "
+ errorStrBuilder.toString());
}
}
private String genRegionForVlkbOverlapCmd(Pos pos, Band band)
{
LOGGER.fine("trace");
String region = "";
if(pos != null)
{
String skySystem = pos.system.name();
if(pos.shape.equals("CIRCLE"))
{
double l = pos.circle.lon;
double b = pos.circle.lat;
double r = pos.circle.radius;
region = region + "skysystem=" + skySystem + "&l=" + String.valueOf(l) + "&b=" + String.valueOf(b)
+ "&r=" + String.valueOf(r);
}
else if(pos.shape.equals("RANGE"))
{
double l = (pos.range.lon1 + pos.range.lon2)/2.0;
double b = (pos.range.lat1 + pos.range.lat2)/2.0;
double dl = (pos.range.lon2 - pos.range.lon1);
double db = (pos.range.lat2 - pos.range.lat1);
region = region + "skysystem=" + skySystem + "&l=" + String.valueOf(l) + "&b=" + String.valueOf(b)
+ "&dl=" + String.valueOf(dl) + "&db=" + String.valueOf(db);
}
else
{
LOGGER.finest("FIXME here Exception: POLYGON not supported or pos.shape invalid: " + pos.shape);
}
}
if(band != null)
{
String specSystem = band.system.name();
double vl = band.min;
double vu = band.max;
region =region + "specsystem=" + specSystem + "&vl=" + String.valueOf(vl) + "&vu=" + String.valueOf(vu);
}
return region;
}
/*
private String replaceWithGrid(String wcsBounds, Pos pos, Band band, Time time, Pol pol)
{
// remove end-of-line (was added by vlkb_ast.cpp: cout << ... << endl)
String lineSeparator = System.lineSeparator();
wcsBounds = wcsBounds.replace(lineSeparator, "");
LOGGER.finest("BOUNDS: " + wcsBounds);
// replace in wcsBounds those bounds where pos,band,time or pol has system=GRID
String[] substr = wcsBounds.split("(?=AXES)", 2);
for(String ss : substr) LOGGER.finest("boundsResult: " + ss);
String boundsString = substr[0];
boolean noOverlap = ((boundsString != null) && boundsString.trim().isEmpty());
if(noOverlap)
{
boundsString = ""; // no overlap
}
else
{
String axesTypes = "";
if(substr.length > 1)
{
axesTypes = substr[1].replace("AXES"," ").trim();
LOGGER.finest("AXES TYPES: " + axesTypes);
String[] bnds = normalize(boundsString);
String[] types = normalize(axesTypes);
// assert: bnds.length == types.length
LOGGER.finest("boundsCount: " + bnds.length + " typesCount: " + types.length);
if(bnds.length == types.length)
boundsString = replaceBounds(bnds, types, pos, band);
}
}
return boundsString;
}
private String replaceBounds(String[] bnds, String[] types, Pos pos, Band band)
{
int ix;
for(ix=0; ix<bnds.length; ix++)
{
if( types[ix].equals("LON") && ((pos != null) && (pos.system == Pos.System.GRID)) )
{
bnds[ix] = pos.lonBoundsString();
}
else if(types[ix].equals("LAT") && ((pos != null) && (pos.system == Pos.System.GRID)))
{
bnds[ix] = pos.latBoundsString();
}
else if(types[ix].equals("BAND") && ((band != null) && (band.system == Band.System.GRID)))
{
bnds[ix] = band.boundsString();
}
}
LOGGER.finest("replaced: " + String.join(" ", bnds)) ;
return "[" + String.join(" ", bnds) + "]";
}
// MAKE SURE vlkb overlap returns space delimited bounds: [ a:b c:d ]
// normalize: strip [,] if any, and split into array by space
private String[] normalize(String spaceStr)
{
String other = spaceStr.replace("[","").replace("]","");
LOGGER.finest("normalize: " + other);
return other.split("\\s+");
}
*/
}
......@@ -11,10 +11,14 @@ class StreamGobbler extends Thread
InputStream is;
String type;
OutputStream os;
StringBuilder sb;
StreamGobbler(InputStream is, String type)
StreamGobbler(InputStream is, String type, StringBuilder sb)
{
this(is, type, null);
this.is = is;
this.type = type;
this.os = null;
this.sb = sb;
}
StreamGobbler(InputStream is, String type, OutputStream redirect)
......@@ -48,7 +52,9 @@ class StreamGobbler extends Thread
}
else
{
LOGGER.finest(type + ">" + new String(buffer, 0, nread, "utf-8"));
String str = new String(buffer, 0, nread, "utf-8");
LOGGER.finest(type + ">" + str);//new String(buffer, 0, nread, "utf-8"));
sb.append(str);
}
}
......@@ -69,7 +75,7 @@ class ExecCmd
public int exitValue;
public void doRun(OutputStream outputStream, String[] cmd)
public void doRun(OutputStream outputStream, String[] cmd, StringBuilder error)
throws IOException, InterruptedException
{
LOGGER.fine("trace CMD: " + Arrays.toString(cmd));
......@@ -82,7 +88,7 @@ class ExecCmd
Process proc = rt.exec(cmd);
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR", error);
// any output?
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT", outputStream);
......
......@@ -115,7 +115,7 @@ public class ServletCutout extends HttpServlet
}
protected void doCutoutStream(String id, Pos pos, Band band, Time time, Pol pol, String pixels,
protected int doCutoutStream(String id, Pos pos, Band band, Time time, Pol pol, String pixels,
OutputStream respOutputStream) throws IOException, InterruptedException
{
LOGGER.fine("trace " + pos);
......@@ -128,7 +128,7 @@ public class ServletCutout extends HttpServlet
resolver.resolve(id);
soda.doStream(resolver.relPathname(), resolver.hdunum(), pos, band, time, pol, pixels, respOutputStream);
return soda.doStream(resolver.relPathname(), resolver.hdunum(), pos, band, time, pol, pixels, respOutputStream);
}
......@@ -270,7 +270,8 @@ public class ServletCutout extends HttpServlet
if(respFormat.startsWith("application/fits"))
{
response.setContentType(respFormat);
doCutoutStream(id, pos, band, time, pol, pixels, respOutputStream);
int rc = doCutoutStream(id, pos, band, time, pol, pixels, respOutputStream);
if(rc == 1) response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
else if(respFormat.startsWith("application/x-vlkb+xml"))
{
......
......@@ -347,8 +347,9 @@ class VlkbCli implements Vlkb
cmdBounds[1] = "nullvals";
cmdBounds[2] = absPathname;
StringBuilder errorStrBuilder = new StringBuilder();
ExecCmd exec = new ExecCmd();
exec.doRun(bos, cmdBounds);
exec.doRun(bos, cmdBounds, errorStrBuilder);
LOGGER.finest("exec NullVals exitValue: " + exec.exitValue);
bos.close();
......@@ -378,7 +379,8 @@ class VlkbCli implements Vlkb
}
else
{
throw new AssertionError("'vlkb nullvals' exited without results for: " + absPathname);
throw new AssertionError("'vlkb nullvals' exited with error: "
+ errorStrBuilder.toString() + " for: " + absPathname);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment