USGS

Isis 3.0 Application Source Code Reference

Home

crop.cpp

Go to the documentation of this file.
00001 #include "Isis.h"
00002 #include "Cube.h"
00003 #include "ProcessByLine.h"
00004 #include "SpecialPixel.h"
00005 #include "LineManager.h"
00006 #include "Filename.h"
00007 #include "iException.h"
00008 #include "Projection.h"
00009 #include "AlphaCube.h"
00010 #include "Table.h"
00011 
00012 using namespace std; 
00013 using namespace Isis;
00014 
00015 // Globals and prototypes
00016 int ss,sl,sb;
00017 int ns,nl,nb;
00018 int sinc,linc;
00019 Cube cube;
00020 LineManager *in = NULL;
00021 
00022 void crop (Buffer &out);
00023 
00024 void IsisMain() {
00025   ProcessByLine p;
00026 
00027   // Open the input cube
00028   UserInterface &ui = Application::GetUserInterface();
00029   string from = ui.GetAsString("FROM");
00030   CubeAttributeInput inAtt(from);
00031   cube.SetVirtualBands(inAtt.Bands());
00032   from = ui.GetFilename("FROM");
00033   cube.Open(from);
00034 
00035   // Determine the sub-area to extract
00036   ss = ui.GetInteger("SAMPLE");
00037   sl = ui.GetInteger("LINE");
00038   sb = 1;
00039 
00040   int es = cube.Samples();
00041   if (ui.WasEntered("NSAMPLES")) es = ui.GetInteger("NSAMPLES") + ss - 1;
00042   int el = cube.Lines();
00043   if (ui.WasEntered("NLINES")) el = ui.GetInteger("NLINES") + sl - 1;
00044   int eb = cube.Bands();
00045 
00046   sinc = ui.GetInteger("SINC");
00047   linc = ui.GetInteger("LINC");
00048 
00049   // Make sure starting positions fall within the cube
00050   if (ss > cube.Samples()) {
00051     cube.Close();
00052     string msg = "[SAMPLE] exceeds number of samples in the [FROM] cube";
00053     throw iException::Message(iException::User,msg,_FILEINFO_);
00054   }
00055 
00056   if (sl > cube.Lines()) {
00057     cube.Close();
00058     string msg = "[LINE] exceeds number of lines in the [FROM] cube";
00059     throw iException::Message(iException::User,msg,_FILEINFO_);
00060   }
00061 
00062   // Make sure the number of elements do not fall outside the cube
00063   if (es > cube.Samples()) {
00064     cube.Close();
00065     string msg = "[SAMPLE+NSAMPLES-1] exceeds number of ";
00066     msg += "samples in the [FROM] cube";
00067     throw iException::Message(iException::User,msg,_FILEINFO_);
00068   }
00069 
00070   if (el > cube.Lines()) {
00071     cube.Close();
00072     string msg = "[LINE+NLINES-1] exceeds number of ";
00073     msg += "lines in the [FROM] cube";
00074     throw iException::Message(iException::User,msg,_FILEINFO_);
00075   }
00076 
00077   // Determine the size of the output cube and then update the image size
00078   ns = (es - ss + 1) / sinc;
00079   nl = (el - sl + 1) / linc;
00080   nb = eb;
00081   if (ns == 0) ns = 1;
00082   if (nl == 0) nl = 1;
00083   es = ss + (ns - 1) * sinc;
00084   el = sl + (nl - 1) * linc;
00085 
00086   // Allocate the output file and make sure things get propogated nicely
00087   p.SetInputCube("FROM");
00088   p.PropagateTables(false);
00089   Cube *ocube = p.SetOutputCube ("TO",ns,nl,nb);
00090   p.ClearInputCubes();
00091 
00092   // propagate tables manually
00093   Pvl &inLabels = *cube.Label();
00094 
00095   // Loop through the labels looking for object = Table
00096   for(int labelObj = 0; labelObj < inLabels.Objects(); labelObj++) {
00097     PvlObject &obj = inLabels.Object(labelObj);
00098 
00099     if(obj.Name() != "Table") continue;
00100 
00101     // If we're not propagating spice data, dont propagate the following tables...
00102     if(!ui.GetBoolean("PROPSPICE")) {
00103       if((iString)obj["Name"][0] == "InstrumentPointing") continue;
00104       if((iString)obj["Name"][0] == "InstrumentPosition") continue;
00105       if((iString)obj["Name"][0] == "BodyRotation") continue;
00106       if((iString)obj["Name"][0] == "SunPosition") continue;
00107     }
00108 
00109     // Read the table into a table object
00110     Table table(obj["Name"], from);
00111 
00112     // We are not going to bother with line/sample associations; they apply
00113     //   only to the alpha cube at this time. I'm leaving this code here for the
00114     //   equations in case we try our hand at modifying these tables at a later date.
00115 
00116     /* Deal with associations, sample first
00117     if(table.IsSampleAssociated()) {
00118       int numDeleted = 0;
00119       for(int samp = 0; samp < cube.Samples(); samp++) {
00120         // This tests checks to see if we would include this sample. 
00121         //   samp - (ss-1)) / sinc must be a whole number less than ns.
00122         if((samp - (ss-1)) % sinc != 0 || (samp - (ss-1)) / sinc >= ns || (samp - (ss-1)) < 0) {
00123           table.Delete(samp-numDeleted);
00124           numDeleted ++;
00125         }
00126       }
00127     }
00128 
00129     // Deal with line association
00130     if(table.IsLineAssociated()) {
00131       int numDeleted = 0;
00132       for(int line = 0; line < cube.Lines(); line++) {
00133         // This tests checks to see if we would include this line. 
00134         //   line - (sl-1)) / linc must be a whole number less than nl.
00135         if((line - (sl-1)) % linc != 0 || (line - (sl-1)) / linc >= nl || (line - (sl-1)) < 0) {
00136           table.Delete(line-numDeleted);
00137           numDeleted ++;
00138         }
00139       }
00140     }*/
00141 
00142     // Write the table
00143     ocube->Write(table);
00144   }
00145 
00146   Pvl &outLabels = *ocube->Label();
00147   if(!ui.GetBoolean("PROPSPICE") && outLabels.FindObject("IsisCube").HasGroup("Kernels")) {
00148     PvlGroup &kerns = outLabels.FindObject("IsisCube").FindGroup("Kernels");
00149 
00150     string tryKey = "NaifIkCode";
00151     if(kerns.HasKeyword("NaifFrameCode")) {
00152       tryKey = "NaifFrameCode";
00153     }
00154 
00155     if(kerns.HasKeyword(tryKey)) {
00156       PvlKeyword ikCode = kerns[tryKey];
00157       kerns = PvlGroup("Kernels");
00158       kerns += ikCode;
00159     }
00160   }
00161 
00162   // Create a buffer for reading the input cube
00163   in = new LineManager(cube);
00164 
00165   // Crop the input cube
00166   p.StartProcess(crop);
00167 
00168   delete in;
00169   in = NULL;
00170 
00171   // Adjust the upper corner x,y values if the cube is projected
00172   if(cube.HasProjection()) {
00173     // Try to create a projection & set the x,y position
00174     Projection *proj = cube.Projection();
00175     proj->SetWorld(ss-0.5,sl-0.5);
00176 
00177     // Set the new x,y coords in the cube label
00178     PvlGroup &mapgrp = cube.Label()->FindGroup("Mapping",Pvl::Traverse);
00179     mapgrp.AddKeyword(PvlKeyword("UpperLeftCornerX",proj->XCoord()), 
00180                        Pvl::Replace);
00181     mapgrp.AddKeyword(PvlKeyword("UpperLeftCornerY",proj->YCoord()),
00182                                       Pvl::Replace);
00183     ocube->PutGroup(mapgrp);
00184   }
00185   // Only write the alpha group if the cube is not projected
00186   else {
00187     // Add and/or update the alpha group
00188     AlphaCube aCube(cube.Samples(),cube.Lines(),
00189                         ocube->Samples(),ocube->Lines(),
00190                         ss-0.5,sl-0.5,es+0.5,el+0.5);
00191     aCube.UpdateGroup(*ocube->Label());
00192   }
00193 
00194   // Cleanup
00195   p.EndProcess();
00196   cube.Close();
00197 }
00198 
00199 // Line processing routine
00200 void crop (Buffer &out) {
00201   // Read the input line
00202   int iline = sl + (out.Line() - 1) * linc;
00203   in->SetLine(iline,sb);
00204   cube.Read(*in);
00205 
00206   // Loop and move appropriate samples
00207   for (int i=0; i<out.size(); i++) {
00208     out[i] = (*in)[(ss - 1) + i * sinc];
00209   }
00210 
00211   if (out.Line() == nl) sb++;
00212 }