All these examples are in the NVOSS\dev\siapClient directory. In this tutorial we will remark only the relevant code.
Before trying the examples be sure you run the java setup script.
c:\>NVOSS\bin\setupjava
SiapCaller.java
Description: Siap client that given a position, a size, and an URL
calls the HTTP SIAP service to retrieve the VOTable. The program goes through the VOTable and lists the central position of the image and the link.
In this example we have a SIAP class with two members.
String _url; // SIAP service url
VOTWrap.VOTable callHTTPService(double ra, double dec, double sz); // SIAP service URL
callHTTPService() is a very simple method that:
// opens the connection to the SIAP service
URL url_call = new URL(_url + "POS=" + ra + "," + dec +"&SIZE=" + sz);
// creates a VOTable with the response from the service.
// VOTWrap is the library that will allow us to parse the VOTable.
return VOTWrap.createVOTable (url_call.openStream());
How does it look like the main code of our SiapCaller?
As simple as:
SIAP siap = new SIAP(url);
VOTWrap.VOTable vot = siap.callHTTPService(ra, dec, sz);
showLinks(vot);
How do we get the RA, DEC, and link from the VOTable?
showLinks() goes through the VOTable and uses the UCDS to find out
what fields in the VOTable holds the RA, DEC, and image URL.
The code looks approximately like:
// for each Resource, Table, and field
if (field.getUCD().equals("POS_EQ_RA_MAIN")) {
ra_index = f;
} else if (field.getUCD().toUpperCase().equals("POS_EQ_DEC_MAIN")){
dec_index = f;
} else if (field.getUCD().toUpperCase().equals("VOX:IMAGE_ACCESSREFERENCE"))
ref_index = f;
// Now that we know the indexes we fetch the data and print their values
int trCount = table.getTableData().getTRCount(); // Number of rows or elements in the table
for (int rw = 0; rw < trCount; rw++) {
VOTWrap.TR row = table.getTableData().getTR(rw);
System.out.println(" RA = " + row.getTD(ra_index).getPCDATA() +
" DEC = " + row.getTD(dec_index).getPCDATA());
System.out.println(" URL = " + row.getTD(ref_index).getPCDATA());
}
How to try this program?
Go to siapClient1 in the dev\siapClient directory. You will find build.xml.
build.xml has the necessary information to compile and execute this program
So, to compile just type
ant
and to execute
ant test
SiapCaller will call
http://skyserver.sdss.org/vo/DR2SIAP/SIAP.asmx/getSiapInfo?BANDPASS=*&format=image/fits&POS="150.15,54.27"&SIZE=0.01
You can try other services and positions by either modifying the input values in build.xml or running the program directly:
java SiapClient1.SiapCaller 150.15 54.27 0.02 "http://archive.noao.edu/nvo/sim/voquery.php?FORMAT=image/fits&"
SiapCaller.java
Description: Siap client that given a
list of positions, and a size
calls the HTTP SIAP service to retrieve the VOTable. The program goes through the VOTable and lists the central position of the image and the link.
This example reads the coordinates from a file, creates a Vector of positions and loops through the vector calling the service for each position.
Main code:
Vector positions = readFile(filename);
SIAP siap = new SIAP(url);
for (int i = 0; i < positions.size(); i++) {
Position p = (Position)positions.elementAt(i);
VOTWrap.VOTable vot = siap.callHTTPService(p.ra, p.dec, sz);
showLinks(vot);
}
Why a
Vector instead of an array?
The class
Vector is convenient here because does not require to know in advance the cardinality of the set of coordinates we are reading. The only "problem" is we need to cast the element with the class type
Position.
How to try this program?
Go to siapClient2 in the dev\siapClient directory. As before, build.xml has the necessary information to compile and execute this program.
To compile and run just type
ant test
The default setup uses a default coordinates file, a size of 0.02, and calls the SDSS DR2 SIAP service
http://skyserver.sdss.org/vo/DR2SIAP/SIAP.asmx/getSiapInfo?BANDPASS=*&format=image/fits&
you can try other service, or/and change the set of coordinates and size
For example:
java SiapClient2.SiapCaller "coordinates.txt" 0.02 "http://irsa.ipac.caltech.edu/cgi-bin/2MASS/IM/nph-im_sia?FORMAT=image/fits&"
SiapCaller.java
Description: Siap client that given a list of positions, and sizes
calls the HTTP SIAP service to retrieve the VOTable. The program goes through the VOTable listing the central position of the image and the link and dowload the fits or jpegs files to the current directory.
Main code:
Vector positions = readFile(filename);
SIAP siap = new SIAP(url);
Set allUniqueSE = new HashSet(); // We put the elements in a Set to avoid
// dowloading the same image twice
for (int i = 0; i < positions.size(); i++) {
Position p = (Position)positions.elementAt(i);
VOTWrap.VOTable vot = siap.callHTTPService(p.ra, p.dec, sz);
Vector siapElements = fetchLinks(vot); // It displays the central position of
// the image and the link to it
// it returns a Vector with all the
// elements in the VOTable
int siapElementsT = siapElements.size();
for (int j = 0; j < siapElementsT; j++)
{
SiapElement element = (SiapElement)siapElements.elementAt(j);
allUniqueSE.add(element);
}
}
Why a
HashSet instead of a Vector?
The class
HashSet allows us to avoid duplicates.
If the coordinates are very close, we will probably get more than once the same link to the image. Since we are downloading the data, we don't want to download more than once the same file.
Note: To use the HashSet with an object as I did with SiapElement, you need to redefine the methods equals() and hashCode() Don't forget!
class SiapElement {
// central position
double ra;
double dec;
String url;
public SiapElement (double ra, double dec, String url){
this.ra = ra;
this.dec = dec;
this.url = url;
}
public boolean equals(Object o) {
if (!(o instanceof SiapElement))
return false;
SiapElement element = (SiapElement)o;
return (element.url.equals(this.url)) ;
}
public int hashCode( ) {
return url.hashCode( );
}
}
To compile and run just type. However, the default setup uses a default has dowload = 1 which will fill your directory with 10 fits images and will bring probably the network down. I will show you the results.
ant test
So either change the code to the second URL or try this other call which will bring you the jepegs.
java SiapClient3.SiapCaller "coordinates.txt" 0.02 1 "http://skyserver.sdss.org/vo/DR2SIAP/SIAP.asmx/getSiapInfo?BANDPASS=*&format=image/jpeg&"
SiapCaller.java
Description: Siap Client that calls a
ConeSearch service to retrieves a set of coordinates in a VOTable, then this calls the HTTP SIAP service to retrieve the VOTable with the links. The program goes thru the VOTable to list the central position of the image and the link, dowload the fits or jpegs files to the current directory, to read the first fits image and finds the brightest pixel in the image.
Main code:
CONE cone = new CONE(cone_url);
VOTWrap.VOTable vot_cone = cone.callHTTPService(ra, dec, sz);
String UDCs_cone[] = new String[] {"POS_EQ_RA_MAIN",
"POS_EQ_DEC_MAIN"};
// Fetch the positions from the coneSearch
Vector coneStringPositions = fetchData(vot_cone, UDCs_cone);
int objsInCone = coneStringPositions.size();
Element[] conePositions = new Element[objsInCone];
for (int i = 0; i < objsInCone; i++) {
String[] p = (String[])coneStringPositions.elementAt(i);
conePositions[i] = new Element(Double.parseDouble(p[0]), // "POS_EQ_RA_MAIN"
Double.parseDouble(p[1])); // "POS_EQ_DEC_MAIN"
}
SIAP siap = new SIAP(siap_url);
Set allUniqueSE = new HashSet();
for (int h = 0; h < objsInCone; h++) {
h = objsInCone;
VOTWrap.VOTable vot_siap = siap.callHTTPService(ra, dec, sz);
String UDCs_siap[] = new String[]{"POS_EQ_RA_MAIN", "POS_EQ_DEC_MAIN", "VOX:IMAGE_ACCESSREFERENCE"};
Vector siapStringPositions = fetchData(vot_siap, UDCs_siap);
int linksInSiap = siapStringPositions.size();
for (int i = 0; i < linksInSiap; i++) {
String[] p = (String[])siapStringPositions.elementAt(i);
Element siapElement = new Element(Double.parseDouble(p[0]), // "POS_EQ_RA_MAIN"
Double.parseDouble(p[1]), // "POS_EQ_DEC_MAIN"
p[2]); // "VOX:IMAGE_ACCESSREFERENCE"
allUniqueSE.add (siapElement);
}
}
if (download == 1) {
String[] fileNames = downloadImages(allUniqueSE, extension);
if (extension.equals(".fits")) // Search for the brightest pixel in the first image
findBrightestPixel(fileNames[0]);
}
As you might have notice
fetchData() is more flexible and lets us decide which UCDs we want to retrive.
Brief look at findBrightestPixel()
public static void findBrightestPixel(String fname) throws Exception{
Fits theFits = new nom.tam.fits.Fits(fname); //or a url!
ImageHDU h = (ImageHDU) theFits.readHDU();
// it may not be an image so then we would get an exception
Header head = h.getHeader();
double naxis1 = head.getDoubleValue("NAXIS1");
double naxis2 = head.getDoubleValue("NAXIS2");
System.out.println (fname + " has naxis1 "+ (int)naxis1 );
System.out.println (fname + " has naxis2 "+ (int)naxis2 );
short[][] img = (short[][])h.getKernel(); // SDSS has BITPIX = 16 (unsigned shorts)
// Other fits images may have a different type
// and will need a differet casting!!
int max = Short.MIN_VALUE;
int max_naxis1, max_naxis2;
max_naxis1 = max_naxis2 = 0;
for (int i = 0; i < (int)naxis2; i++) {
for (int j = 0; j < (int)naxis1; j++) {
if (max < img[i][j]) {
max = img[i][j];
max_naxis1 = j;
max_naxis2 = i;
}
}
}
max = max + Short.MAX_VALUE;
System.out.println("Maximum Value = " + max + " was found at pixel (" + max_naxis1 + "," + max_naxis2 + ")");
}
To execute:
ant test
This example runs with the fixed URLs for the CONE and SIAP services. Feel free to change the code!
FindingChart.java
Description: Web service Siap Client that given a list of positions, and a size calls the SDSS
ImgCutout service to retrieve a DIME attachment with the image and saves it to the computer.
Not completely finished but working. It needs to define width and height as a function of the requested size.
The important piece of code in this examples is:
public static DataHandler getImage(double ra, double dec, double scale, int width, int height, String opt) throws Exception
{
ImgCutoutLocator loc = new ImgCutoutLocator();
ImgCutoutSoap imgProvider = loc.getImgCutoutSoap();
imgProvider.dimeJpeg(ra, dec,scale, width, height, opt);
//Not so nice but we must cast to a stub to get the attachements
Object[] obj = ((org.apache.axis.client.Stub)imgProvider).getAttachments();
//Each Attachment is actually an AttachmentPart - we only have 1
AttachmentPart p = (AttachmentPart) obj[0];
//We get the dataHandler
DataHandler dh = p.getActivationDataHandler();
return dh;
}
After you run it, you will find 4 nice
Finding Charts in your directory.
Note: The URL in the the program was a test URL, if you want to use this service please change it to
http://skyservice.pha.jhu.edu/dr2/ImgCutout/ImgCutout.asmx