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
Loading
Loading
Loading
Loading
+438 −440
Original line number Diff line number Diff line
@@ -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(
+12 −6
Original line number Diff line number Diff line
@@ -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;
}
+1 −1
Original line number Diff line number Diff line
@@ -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;

+53 −223
Original line number Diff line number Diff line
@@ -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 −5
Original line number Diff line number Diff line
@@ -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);
Loading