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