Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • ViaLactea/vlkb-soda
1 result
Select Git revision
Show changes
Commits on Source (8)
Showing
with 1401 additions and 1399 deletions
......@@ -12,10 +12,10 @@ RPM_ROOT = rpmbuild
.PHONY: all clean
all: vlkb vlkb-obscore vlkbd
all: vlkb vlkb-obscore
.PHONY: vlkb vlkb-obscore vlkbd
vlkb vlkb-obscore vlkbd:
.PHONY: vlkb vlkb-obscore
vlkb vlkb-obscore:
make -C common
make -C $@
make EXEC_NAME=$@ $(PACK_EXT)
......@@ -23,7 +23,6 @@ vlkb vlkb-obscore vlkbd:
clean:
make -C vlkb clean
make -C vlkb-obscore clean
make -C vlkbd clean
make -C common clean
......
......@@ -21,13 +21,6 @@ struct Bounds
int naxis;
};
struct uint_bounds
{
unsigned int pix1;
unsigned int pix2;
unsigned char type;
};
struct double_xy
{
double x;
......
......@@ -12,6 +12,14 @@ enum class specsystem {NONE, VELO_LSRK, WAVE_Barycentric};
enum class timesystem {NONE, MJD_UTC};
struct uint_bounds
{
unsigned int pix1;
unsigned int pix2;
unsigned char type;
};
/* SODA */
struct circle
......@@ -68,25 +76,27 @@ struct coordinates
{
coordinates();
skysystem skysys; // mandatory: "GALACTIC"|"ICRS"
double lon_deg, lat_deg; // mandatory
area shape; // mandatory: CIRCLE dlon=dlat=2xRadius, RECT dlon may differ from dlat
double dlon_deg, dlat_deg; // mandatory
std::vector<double> p_lon_deg; // mandatory polygon arrry
std::vector<double> p_lat_deg; // mandatory polygon array
skysystem skysys; // mandatory: NONE GALACTIC ICRS
double lon_deg, lat_deg; // optional, check skysys == NONE
area shape; // optional: CIRCLE dlon=dlat=2xRadius, RECT dlon may differ dlat
double dlon_deg, dlat_deg; // optional
std::vector<double> p_lon_deg; // optional polygon arrry
std::vector<double> p_lat_deg; // optional polygon array
specsystem specsys; // mandatory NONE VELO-LSRK WAVE-Bary
specsystem specsys; // mandatory NONE VELO_LSRK WAVE_Barycentric
double vl_kmps, vu_kmps; // optional, check specsystem == NONE
timesystem timesys;
double time_value[2]; // time interval (MJD in UTC)
std::vector<std::string> pol; // polarization states FIXME pol should be Set<enums>
std::vector<uint_bounds> pixel_i; // PIXEL_i for non-standard axes allow direct cut without WCS
};
coordinates parse_coordinates(const std::string region_string);
coordinates to_coordinates(const position pos, const band bnd, const time_axis time,
const std::vector<std::string> pol);
const std::vector<std::string> pol, const std::vector<uint_bounds> pixel_i);
/* cutout */
......
......@@ -15,6 +15,8 @@ void to_json(json& j, const cutout_res_s& p);
void to_json(json& j, const fits_card& p);
void from_json(const json& j, fits_card& p);
void from_json(const json& j, uint_bounds& p);
void to_json(json& j, const coordinates& p);
void from_json(const json& j, coordinates& p);
......
......@@ -791,12 +791,17 @@ overlap_ranges ast::frameset::overlap_in_wcs(coordinates coord)
return overlap_ranges{ov_code, pix_ranges };
}
#else
void log_bounds(string prefix, int length, double low[], double up[])
void ast::frameset::log_bounds(string prefix, int length, double low[], double up[])
{
int ix;
LOG_STREAM << prefix << endl;
for(ix=0; ix<length; ix++) LOG_STREAM << prefix << low[ix] << " " << up[ix]
<< " deg: " << R2D*low[ix] << " " << R2D*up[ix] << endl;
double factor;
bool is_wcs = (prefix.find("WCS") != std::string::npos);
for(ix=0; ix<length; ix++)
{
factor = (is_wcs && (ix == (m_sky_lon_axis-1) || ix == (m_sky_lat_axis-1))) ? R2D : 1.0;
LOG_STREAM << prefix << factor*low[ix] << " " << factor*up[ix] << endl;
}
// << " deg: " << R2D*low[ix] << " " << R2D*up[ix] << endl;
}
......@@ -941,7 +946,7 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
astGetRegionBounds(pixbox, xlbnd, xubnd);
if ( !astOK )
throw runtime_error(failed_with_status(__FILE__,__LINE__,"astGetRegionBounds( pixbox )"));
log_bounds("XX BOUNDS header_pix: ", naxes, xlbnd, xubnd);
log_bounds("BOUNDS header PIX: ", naxes, xlbnd, xubnd);
/* DEBUG only */
......@@ -961,11 +966,13 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
if ( !astOK )
throw runtime_error(failed_with_status(__FILE__,__LINE__,"astGetRegionBounds"));
log_bounds("XX BOUNDS header: ", naxes, low, up);
log_bounds("BOUNDS header WCS: ", naxes, low, up);
/* overwrite bounds for sky-axis and spec axis if given by coord input */
/* overwrite bounds for sky- spec- time- pol-axis if given by coord */
if(m_has_skyframe && (coord.skysys != skysystem::NONE))
{
int ix_lon = m_sky_lon_axis - 1; //astGetI(m_hdr_fs,"LonAxis") - 1;
int ix_lat = m_sky_lat_axis - 1; //astGetI(m_hdr_fs,"LatAxis") - 1;
//if ( !astOK )
......@@ -980,6 +987,7 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
low[ix_lat] = D2R * (coord.lat_deg - coord.dlat_deg/2.0);
up[ix_lon] = D2R * (coord.lon_deg + coord.dlon_deg/2.0);
up[ix_lat] = D2R * (coord.lat_deg + coord.dlat_deg/2.0);
}
vector<double_xy> pix_ranges;
......@@ -1005,8 +1013,8 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
/* set values only to get correct debug print for client */
low[m_spec_axis-1] = coord.vl_kmps;
up [m_spec_axis-1] = coord.vu_kmps;
log_bounds("XX BOUNDS client: ", naxes, low, up);
LOG_STREAM << "XX BOUNDS no overlap in spectrum axis, returning ov_code=1" << endl;
log_bounds("BOUNDS client WCS: ", naxes, low, up);
LOG_STREAM << "BOUNDS no overlap in spectrum axis, returning ov_code=1" << endl;
return overlap_ranges{1, pix_ranges };
}
else // at least partial overlap -> cut coord to min/max of header values
......@@ -1031,7 +1039,7 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
up [m_stokes_axis-1] = max_pol_state(coord.pol);
}
log_bounds("XX BOUNDS client: ", naxes, low, up);
log_bounds("BOUNDS client WCS: ", naxes, low, up);
/* FIXME ignored coord.shape; add circle later : metters for ovelap-code (but not for cut, which is always rect) */
AstRegion * crgn = (AstRegion *)astBox( wcsbox, 1, low, up , (AstRegion*)AST__NULL," ");
......@@ -1050,7 +1058,7 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
if ( !astOK )
throw runtime_error(failed_with_status(__FILE__,__LINE__,"astGetRegionBounds"));
log_bounds("XX BOUNDS client_pix: ", naxes, cllow, clup);
log_bounds("BOUNDS client PIX: ", naxes, cllow, clup);
/* DBG only */
......@@ -1080,7 +1088,7 @@ overlap_ranges ast::frameset::overlap(coordinates coord)
if ( !astOK )
throw runtime_error(failed_with_status(__FILE__,__LINE__,"astGetRegionBounds( pixOverlap )"));
log_bounds("XX BOUNDS overlap_pix: ", m_NAXIS, lbnd, ubnd);
log_bounds("BOUNDS overlap PIX: ", m_NAXIS, lbnd, ubnd);
int ix;
for(ix=0; ix<m_NAXIS; ix++)
......
......@@ -45,6 +45,7 @@ class frameset
std::ostream& serialize(std::ostream& strm) const;
private:
void log_bounds(std::string prefix, int length, double low[], double up[]);
void log_warnings(const AstFitsChan * fchan);
AstRegion * create_header_region(void);
......
......@@ -177,6 +177,7 @@ string axistype2string(unsigned char cc)
case 'b': return "BAND"; break;
case 't': return "TIME"; break;
case 'p': return "POL"; break;
case 'x': return "PIXEL_i"; break;
case ' ': return "UNKNOWN"; break;
default:
throw invalid_argument(cc + " is not a valid axis type");
......@@ -207,7 +208,7 @@ coordinates parse_coordinates(const string region_string)
LOG_trace(string(__func__) + " : " + region_string);
json_region reg(region_string);
coordinates coord = to_coordinates(reg.get_pos(), reg.get_band(), reg.get_time(), reg.get_pol());
coordinates coord = to_coordinates(reg.get_pos(), reg.get_band(), reg.get_time(), reg.get_pol(), reg.get_pixel_i());
LOG_STREAM << "coord parsed: " << coord << endl;
......@@ -215,7 +216,8 @@ coordinates parse_coordinates(const string region_string)
}
coordinates to_coordinates(const position pos, const band bnd, const time_axis time, const std::vector<std::string> pol)
coordinates to_coordinates(const position pos, const band bnd, const time_axis time,
const std::vector<std::string> pol, const std::vector<uint_bounds> pixel_i)
{
coordinates coord;
coord.skysys = pos.sys;
......@@ -274,6 +276,8 @@ coordinates to_coordinates(const position pos, const band bnd, const time_axis t
coord.pol = pol;
coord.pixel_i = pixel_i;
return coord;
}
......@@ -336,7 +340,8 @@ cutout_res_s do_cutout_file(
const string abs_subimg_pathname = conf_fits_cutpath + "/" + generate_cut_fitsname(fits_pathname, hdunum);
const string abs_fits_pathname{ conf_fits_path + "/" + fits_pathname };
coordinates coord = to_coordinates(pos, bnd, time, pol);
vector<uint_bounds> pixel_i_none;
coordinates coord = to_coordinates(pos, bnd, time, pol, pixel_i_none);
uintmax_t filesize = cutout_file(abs_fits_pathname, hdunum, coord, abs_subimg_pathname, extra_cards);
......
......@@ -119,6 +119,13 @@ void from_json(const json& j, fits_card& p)
}
void from_json(const json& j, uint_bounds& p)
{
if(j.contains("pix1")) j.at("pix1").get_to(p.pix1); else p.pix1 = 0;
if(j.contains("pix2")) j.at("pix2").get_to(p.pix2); else p.pix2 = 0;
if(j.contains("type")) j.at("type").get_to(p.type); else p.type = ' ';
}
// cutout
......
......@@ -110,15 +110,15 @@ std::ostream& operator<<( std::ostream &out, struct coordinates const& p)
bool is_poly = (p.shape == area::POLYGON);
out << to_string(p.skysys) << " : (" << p.lon_deg << ", " << p.lat_deg << ") "
out << "POS["<< to_string(p.skysys) << "; (" << p.lon_deg << ", " << p.lat_deg << ") "
<< to_string(p.shape) << ": ("
<< (is_poly ? poly_lon_str : to_string(p.dlon_deg)) << ", "
<< (is_poly ? poly_lat_str : to_string(p.dlat_deg)) << ") "
<< to_string(p.specsys) << " [km/s] : (" << p.vl_kmps << ", " << p.vu_kmps << ") "
<< (is_poly ? poly_lat_str : to_string(p.dlat_deg)) << ")] "
<< "BAND[" <<to_string(p.specsys) << "; (" << p.vl_kmps << ", " << p.vu_kmps << ")] "
// << "POS(" << p.pos << ") "
// << "BAND(" << to_string(p.bandsys) << "; " << p.band_value[0] << ", " << p.band_value[1] << ") "
<< "TIME(" << to_string(p.timesys) << "; " << p.time_value[0] << ", " << p.time_value[1] << ") "
<< "POL(" << pol_str << ")";
<< "TIME[" << to_string(p.timesys) << "; " << p.time_value[0] << ", " << p.time_value[1] << "] "
<< "POL[" << pol_str << "]";
return out;
}
......
......@@ -52,16 +52,29 @@ class json_region
std::vector<std::string> get_pol()
{
std::vector<std::string> str;
std::vector<std::string> str_vec;
if(m_jservice.contains("pol"))
{
json j = m_jservice.at("pol");
str = j.get<std::vector<std::string>>();
str_vec = j.get<std::vector<std::string>>();
}
return str;
return str_vec;
}
std::vector<uint_bounds> get_pixel_i()
{
std::vector<uint_bounds> pixi_vec;
if(m_jservice.contains("pixel_i"))
{
json j = m_jservice.at("pixel_i");
pixi_vec = j.get<std::vector<uint_bounds>>();
}
return pixi_vec;
}
private:
json m_jservice;
};
......
......@@ -113,36 +113,36 @@ void read_lines(string pathname, vector<string>& lines)
}
}
int header_backup(const string& pathname, const string& extra_cards_pathname, bool backup)
int header_backup(const string& pathname, int extnum, const string& extra_cards_pathname, bool backup, std::ostream& ostrm)
{
LOG_trace(__func__);
LOG_STREAM << pathname << " " << extnum << endl;
vector<string> extra_cards;
read_lines(extra_cards_pathname, extra_cards);
int maxHdu = 1;//FIXME INT_MAX; // read all HDU's
int maxHdu = extnum+1;
int minHdu = extnum+1;
std::vector<fitsfiles::Hdu> allHdus =
fitsfiles::fname2hdrstr(pathname, extra_cards, maxHdu);
fitsfiles::fname2hdrstr(pathname, extra_cards, maxHdu, minHdu);
for(unsigned int i=0; i<allHdus.size(); i++)
{
cerr << "HDU#" << i << endl;
fitsfiles::Hdu hd = allHdus.at(i);
if(backup)
write_previous(hd.m_header, pathname +"hdr" + ((i>0) ? "#" + to_string(i+1) : "") );
else
{
unsigned long i = 0;
unsigned long ii = 0;
unsigned long hdr_len = hd.m_header.length();
while((i*80+80) <= hdr_len)
LOG_STREAM << "header card count: " << hdr_len/80 << endl;
while((ii*80+80) <= hdr_len)
{
cout << hd.m_header.substr(80*i++, 80) << "<" << endl;
ostrm << hd.m_header.substr(80*ii++, 80) << endl;
}
}
// FIXME remove all explicit cout cerr to main.cpp and here use ostream&
}
return 0;
......@@ -170,6 +170,11 @@ vector<string> split (const string &s, char delim)
return result;
}
void update_with_pixel_i(vector<uint_bounds>& bnds, vector<uint_bounds> pix_vec)
{
for(unsigned int i=0; ( i<pix_vec.size() ) && ( i<bnds.size() ); i++)
if(pix_vec[i].type == 'x') bnds[i] = pix_vec[i];
}
int vlkb_overlap(const string& pathname, const string& region, vector<uint_bounds>& bnds)
{
......@@ -188,6 +193,7 @@ int vlkb_overlap(const string& pathname, const string& region, vector<uint_bound
fitsfiles::Hdu hd = allHdus.at(i);
bnds = calc_overlap(hd.m_header, coord, ov_code);
}
update_with_pixel_i(bnds, coord.pixel_i);
return ov_code;
}
......
......@@ -5,10 +5,11 @@
#include <string>
#include <vector>
#include <iostream>
int vlkb_skyvertices(const std::string& pathname, const std::string& skysys_str);
int vlkb_listbounds(const std::string& skysys_str, const std::string& specsys_str, const std::string& pathname);
int header_backup(const std::string& pathname, const std::string& extra_cards_pathname, bool backup = false);
int header_backup(const std::string& pathname, int extnum, const std::string& extra_cards_pathname, bool backup = false, std::ostream& ostrm=std::cout);
int vlkb_overlap(const std::string& pathname, const std::string& region, std::vector<uint_bounds>& bnds);
#endif
......@@ -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\"}}\'"
<< 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;
}
......@@ -398,7 +404,7 @@ int cmd_header(int argc, char * argv[])
if (argc < 2)
{
std::cerr
<< "Usage: header [--backup] [--extra-cards-pathname=<pathname>] <pathname.fits>...\n"
<< "Usage: header [--backup] [--extra-cards-pathname=<pathname>] [--extnum=] <pathname.fits>...\n"
<< "\n"
<< "Prints current header (one card per line) or writes the header into a file with the same pathname but 'fitshdr' extension.\n"
<< "Arguments:\n"
......@@ -409,6 +415,7 @@ int cmd_header(int argc, char * argv[])
{
bool backup = false;
string extra_cards_pathname;
int extnum=0;
for(int i=1; i<argc; i++)
{
......@@ -419,15 +426,16 @@ int cmd_header(int argc, char * argv[])
else if(0 == (string(argv[i]).substr(0,2+21)).compare("--extra-cards-pathname="))
{
extra_cards_pathname = (string{argv[i]}).substr(2+21);
cout << "DBG " << extra_cards_pathname << endl;
}
else if(0 == (string(argv[i]).substr(0,2+7)).compare("--extnum="))
{
extnum = stoi( (string{argv[i]}).substr(2+7) );
}
else
{
string pathname(argv[i]);
cout << to_string(i) << " : " << pathname << endl;
rc = header_backup(pathname, extra_cards_pathname, backup);
std::cout << "header_backup rc: " << rc << std::endl;
rc = header_backup(pathname, extnum, extra_cards_pathname, backup, cout);
}
}
rc = EXIT_SUCCESS;
......@@ -534,7 +542,7 @@ int cmd_overlap(int argc, char * argv[])
<< "Usage: overlap <filename.fits[ext]> <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";
" \'{\"pos\":{\"circle\":{\"lat\":-1.373,\"lon\":21.4458,\"radius\":0.1},\"system\":\"ICRS\"}}\'\n";
rc = EXIT_FAILURE;
}
else
......
......@@ -65,7 +65,7 @@
<dependency>
<groupId>vo</groupId>
<artifactId>vlkb-volib</artifactId>
<version>0.9.7</version>
<version>0.9.8</version>
</dependency>
<!-- dependency>
......
......@@ -7,7 +7,7 @@ class Coord
String skySystem; // FIXME enum ICRS | GALACTIC
String shape = "CIRCLE"; // FIXME enum CIRCLE | RECT | POLYGON FIXME replace RECT -> RANGE
String specSystem; // FIXME enum VELO_LSRK | WAVE_Barycentric | NONE
String specSystem; // FIXME enum VELO_LSRK | WAVE_Barycentric
Pos pos;
Band band;
......
class Pixeli
{
int pix1,pix2;
int type;
Pixeli(int px1, int px2, char cc) {this.pix1=px1; this.pix2=px2; this.type=cc;}
}
......@@ -27,7 +27,6 @@ public class JsonEncoder
// NOTE: implementation of NULL: do not put into json
// (alternatively could put JSON.NULL as "pos" value or use pos.system.NONE)
public void add(Pos pos)
{
......@@ -91,6 +90,24 @@ public class JsonEncoder
}
}
public void add(Pixeli[] pixiArr)
{
if(pixiArr != null)
{
JSONArray jarr = new JSONArray();
for(Pixeli elem : pixiArr)
{
JSONObject j = new JSONObject();
j.put("pix1", elem.pix1);
j.put("pix2", elem.pix2);
j.put("type", elem.type);
jarr.add(j);
}
this.obj.put("pixel_i", jarr);
}
}
public void add(FitsCard[] extraCards)
{
......
......@@ -14,8 +14,14 @@ import vo.parameter.*;
public interface Soda
{
public void doStream(String relPathname, int hdunum,
Pos pos, Band band, Time time, Pol pol, String pixels,
public int doStream(String relPathname, int hdunum,
Pos pos, Band band, Time time, Pol pol, Pixeli[] pixeli,
OutputStream outputStream) throws IOException, InterruptedException;
public int doStream(String relPathname, int hdunum, String pixels,
OutputStream outputStream) throws IOException, InterruptedException;
public int doStreamHeader(String relPathname, int hdunum,
OutputStream outputStream) throws IOException, InterruptedException;
}
......
......@@ -43,237 +43,157 @@ class SodaImpl implements Soda
}
public void doStream(String relPathname, int hdunum,
Pos pos, Band band, Time time, Pol pol, String pixels,
public int doStream(String relPathname, int hdunum,
Pos pos, Band band, Time time, Pol pol, Pixeli[] pixeli,
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 = "";
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);
if(outputStream == null)
LOGGER.finest("supplied outputStream for cut-file is null");
// FIXME throw excpetion here
if( !pixels_valid )
/*/ DBG start
Pixeli[] pixeli =
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if(bos == null)
throw new AssertionError("byte output stream for bounds was not created, is null");
new Pixeli(0,0,' '),
new Pixeli(0,0,' '),
new Pixeli(10,20,'x')
};
// DBG end*/
boolean has_overlap = false;
String boundsString = "";
JsonEncoder jReq = new JsonEncoder();
jReq.add(pos);
jReq.add(band);
jReq.add(time);
jReq.add(pol);
jReq.add(pixeli);
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;
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));
LOGGER.finest(String.join(" ", cmdBounds));
StringBuilder errorStrBuilder = new StringBuilder();
ExecCmd execBounds = new ExecCmd();
execBounds.doRun(bos, cmdBounds);
LOGGER.finest("execBounds exitValue: " + execBounds.exitValue);
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()));
boolean has_result = (execBounds.exitValue == 0);
if(has_result)
if(rc == 0)
{
boundsString = new String(bos.toByteArray());
/* 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());
if( !has_overlap )
return rc; // OK
}
else if(rc == 1)
{
return rc; // OK, but no overlap
}
else
{
throw new IllegalArgumentException(
"region in file does not overlap with region defined by SODA parameters");
"overlap computation could not be completed with the given arguments. "
+ errorStrBuilder.toString());
}
}
bos.close();
Instant boundsDone = Instant.now();
LOGGER.finer("EXECTIME boundsDone: " + Duration.between(start, boundsDone));
}
if(has_overlap || pixels_valid)
{
/* 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));
public int doStream(String relPathname, int hdunum,
String pixels, OutputStream outputStream) throws IOException, InterruptedException
{
Instant start = Instant.now();
LOGGER.fine("trace");
if(outputStream == null)
LOGGER.finest("supplied outputStream for cut-file is null");
ExecCmd execCut = new ExecCmd();
execCut.doRun(outputStream, cmdCut);
final boolean isDavCall= relPathname.startsWith("http://") || relPathname.startsWith("https://");
final boolean isAbsPath= relPathname.startsWith("/");
String absPathname = (isDavCall || isAbsPath) ? relPathname
: (fitsPaths.surveys() +"/"+ relPathname);
String[] cmd = new String[5];
cmd[0] = "/usr/local/bin/vlkb";
cmd[1] = (isDavCall) ? "imcopydav" : "imcopy";
cmd[2] = absPathname;
cmd[3] = String.valueOf(hdunum);
cmd[4] = pixels;
LOGGER.finest(String.join(" ", cmd));
LOGGER.finest("execCut exitValue: " + execCut.exitValue);
StringBuilder errorStrBuilder = new StringBuilder();
boolean cut_successful = (execCut.exitValue == 0);
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(!cut_successful)
if(rc == 0)
{
throw new IllegalArgumentException("cut by pixels not completed for pixels : " + pixFilterString);
return rc; // OK
}
Instant cutDone = Instant.now();
LOGGER.finer("EXECTIME cutDone: " + Duration.between(start, cutDone));
else if(rc == 1)
{
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)
public int doStreamHeader(String relPathname, int hdunum,
OutputStream outputStream) throws IOException, InterruptedException
{
Instant start = Instant.now();
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);
}
if(outputStream == null)
LOGGER.finest("supplied response outputStream is null");
return region;
}
final boolean isAbsPath= relPathname.startsWith("/");
String absPathname = isAbsPath ? relPathname : (fitsPaths.surveys() +"/"+ relPathname);
/*
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);
String[] cmd = new String[4];
cmd[0] = "/usr/local/bin/vlkb";
cmd[1] = "header";
cmd[2] = "--extnum=" + String.valueOf(hdunum-1);
cmd[3] = absPathname;
LOGGER.finest(String.join(" ", cmd));
// replace in wcsBounds those bounds where pos,band,time or pol has system=GRID
StringBuilder errorStrBuilder = new StringBuilder();
String[] substr = wcsBounds.split("(?=AXES)", 2);
for(String ss : substr) LOGGER.finest("boundsResult: " + ss);
ExecCmd exec = new ExecCmd();
exec.doRun(outputStream, cmd, errorStrBuilder);
int rc = exec.exitValue;
LOGGER.finest("exec header exitValue: " + rc);
LOGGER.finer("EXECTIME headerDone: " + Duration.between(start, Instant.now()));
String boundsString = substr[0];
boolean noOverlap = ((boundsString != null) && boundsString.trim().isEmpty());
if(noOverlap)
if(rc == 0)
{
boundsString = ""; // no overlap
return rc; // OK
}
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);
}
throw new IllegalArgumentException("header could not be retrieved (rc="
+ rc + ") " + errorStrBuilder.toString());
}
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+");
}
*/
}