bool TryKernels(Cube *icube, Process &p, Kernel lk, Kernel pck, Kernel targetSpk, Kernel ck, Kernel fk, Kernel ik, Kernel sclk, Kernel spk, Kernel iak, Kernel dem, Kernel exk) { Pvl lab = *icube->Label(); // Add the new kernel files to the existing kernels group PvlKeyword lkKeyword("LeapSecond"); PvlKeyword pckKeyword("TargetAttitudeShape"); PvlKeyword targetSpkKeyword("TargetPosition"); PvlKeyword ckKeyword("InstrumentPointing"); PvlKeyword ikKeyword("Instrument"); PvlKeyword sclkKeyword("SpacecraftClock"); PvlKeyword spkKeyword("InstrumentPosition"); PvlKeyword iakKeyword("InstrumentAddendum"); PvlKeyword demKeyword("ShapeModel"); PvlKeyword exkKeyword("Extra"); for (int i=0; i<lk.size(); i++) { lkKeyword.AddValue(lk[i]); } for (int i=0; i<pck.size(); i++) { pckKeyword.AddValue(pck[i]); } for (int i=0; i<targetSpk.size(); i++) { targetSpkKeyword.AddValue(targetSpk[i]); } for (int i=0; i<ck.size(); i++) { ckKeyword.AddValue(ck[i]); } for (int i=0; i<ik.size(); i++) { ikKeyword.AddValue(ik[i]); } for (int i=0; i<sclk.size(); i++) { sclkKeyword.AddValue(sclk[i]); } for (int i=0; i<spk.size(); i++) { spkKeyword.AddValue(spk[i]); } for (int i=0; i<iak.size(); i++) { iakKeyword.AddValue(iak[i]); } for (int i=0; i<dem.size(); i++) { demKeyword.AddValue(dem[i]); } for (int i=0; i<exk.size(); i++) { exkKeyword.AddValue(exk[i]); } PvlGroup originalKernels = icube->GetGroup("Kernels"); PvlGroup currentKernels = originalKernels; currentKernels.AddKeyword(lkKeyword, Pvl::Replace); currentKernels.AddKeyword(pckKeyword, Pvl::Replace); currentKernels.AddKeyword(targetSpkKeyword, Pvl::Replace); currentKernels.AddKeyword(ckKeyword, Pvl::Replace); currentKernels.AddKeyword(ikKeyword, Pvl::Replace); currentKernels.AddKeyword(sclkKeyword, Pvl::Replace); currentKernels.AddKeyword(spkKeyword, Pvl::Replace); currentKernels.AddKeyword(iakKeyword, Pvl::Replace); currentKernels.AddKeyword(demKeyword, Pvl::Replace); // report qualities PvlKeyword spkQuality("InstrumentPositionQuality"); spkQuality.AddValue(spiceInit::kernelTypeEnum(spk.kernelType)); currentKernels.AddKeyword(spkQuality, Pvl::Replace); PvlKeyword ckQuality("InstrumentPointingQuality"); ckQuality.AddValue(spiceInit::kernelTypeEnum(ck.kernelType)); currentKernels.AddKeyword(ckQuality, Pvl::Replace); if (!exkKeyword.IsNull()) { currentKernels.AddKeyword(exkKeyword, Pvl::Replace); } else if( currentKernels.HasKeyword("EXTRA") ) { currentKernels.DeleteKeyword( "EXTRA" ); } // Get rid of old keywords from previously inited cubes if (currentKernels.HasKeyword("SpacecraftPointing")) { currentKernels.DeleteKeyword("SpacecraftPointing"); } if (currentKernels.HasKeyword("SpacecraftPosition")) { currentKernels.DeleteKeyword("SpacecraftPosition"); } if (currentKernels.HasKeyword("ElevationModel")) { currentKernels.DeleteKeyword("ElevationModel"); } if (currentKernels.HasKeyword("Frame")) { currentKernels.DeleteKeyword("Frame"); } if (currentKernels.HasKeyword("StartPadding")) { currentKernels.DeleteKeyword("StartPadding"); } if (currentKernels.HasKeyword("EndPadding")) { currentKernels.DeleteKeyword("EndPadding"); } UserInterface &ui = Application::GetUserInterface(); // Add any time padding the user specified to the spice group if(ui.GetDouble("STARTPAD") > DBL_EPSILON) { currentKernels.AddKeyword(PvlKeyword("StartPadding", ui.GetDouble("STARTPAD"), "seconds")); } if(ui.GetDouble("ENDPAD") > DBL_EPSILON) { currentKernels.AddKeyword(PvlKeyword("EndPadding", ui.GetDouble("ENDPAD"), "seconds")); } currentKernels.AddKeyword(PvlKeyword("CameraVersion",CameraFactory::CameraVersion(lab)), Pvl::Replace); // Add the modified Kernels group to the input cube labels icube->PutGroup(currentKernels); // Create the camera so we can get blobs if necessary try { Camera *cam; try { cam = icube->Camera(); Application::Log(currentKernels); } catch (iException &e) { Pvl errPvl = e.PvlErrors(); if(errPvl.Groups() > 0) { currentKernels += PvlKeyword("Error", errPvl.Group(errPvl.Groups()-1)["Message"][0]); } Application::Log(currentKernels); icube->PutGroup(originalKernels); throw e; } if (ui.GetBoolean("ATTACH")) { Table ckTable = cam->InstrumentRotation()->Cache("InstrumentPointing"); ckTable.Label() += PvlKeyword("Description", "Created by spiceinit"); ckTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<ckKeyword.Size(); i++) { ckTable.Label()["Kernels"].AddValue(ckKeyword[i]); } icube->Write(ckTable); Table spkTable = cam->InstrumentPosition()->Cache("InstrumentPosition"); spkTable.Label() += PvlKeyword("Description", "Created by spiceinit"); spkTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<spkKeyword.Size(); i++) { spkTable.Label()["Kernels"].AddValue(spkKeyword[i]); } icube->Write(spkTable); Table bodyTable = cam->BodyRotation()->Cache("BodyRotation"); bodyTable.Label() += PvlKeyword("Description", "Created by spiceinit"); bodyTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<targetSpkKeyword.Size(); i++) { bodyTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]); } for (int i=0; i<pckKeyword.Size(); i++) { bodyTable.Label()["Kernels"].AddValue(pckKeyword[i]); } bodyTable.Label() += PvlKeyword("SolarLongitude", cam->SolarLongitude()); icube->Write(bodyTable); Table sunTable = cam->SunPosition()->Cache("SunPosition"); sunTable.Label() += PvlKeyword("Description", "Created by spiceinit"); sunTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<targetSpkKeyword.Size(); i++) { sunTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]); } icube->Write(sunTable); // Save original kernels in keyword before changing to Table PvlKeyword origCk = currentKernels["InstrumentPointing"]; PvlKeyword origSpk = currentKernels["InstrumentPosition"]; PvlKeyword origTargPos = currentKernels["TargetPosition"]; currentKernels["InstrumentPointing"] = "Table"; for (int i=0; i<origCk.Size(); i++) { currentKernels["InstrumentPointing"].AddValue(origCk[i]); } currentKernels["InstrumentPosition"] = "Table"; for (int i=0; i<origSpk.Size(); i++) { currentKernels["InstrumentPosition"].AddValue(origSpk[i]); } currentKernels["TargetPosition"] = "Table"; for (int i=0; i<origTargPos.Size(); i++) { currentKernels["TargetPosition"].AddValue(origTargPos[i]); } icube->PutGroup(currentKernels); } //modify Kernels group only else { Pvl *label = icube->Label(); int i=0; while (i < label->Objects()) { PvlObject currObj = label->Object(i); if (currObj.IsNamed("Table")) { if (currObj["Name"][0] == iString("InstrumentPointing")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("InstrumentPosition")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("BodyRotation")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("SunPosition")) { label->DeleteObject(i); } else { i++; } } else { i++; } } } p.WriteHistory(*icube); } catch (iException &e) { e.Clear(); icube->PutGroup(originalKernels); return false; } return true; }
void IsisMain() { // We will be processing by brick ProcessByBrick p; Isis::Cube *amatrixCube=NULL; Isis::Cube *bmatrixCube=NULL; // Setup the user input for the input/output files and the option UserInterface &ui = Application::GetUserInterface(); // Setup the input HiRise cube Isis::Cube *icube = p.SetInputCube("FROM"); if (icube->Bands() != 1) { std::string msg = "Only single-band HiRise cubes can be calibrated"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } //Get pertinent label information to determine which band of matrix cube to use HiLab hilab(icube); int ccd = hilab.getCcd(); int channel = hilab.getChannel(); if (channel != 0 && channel != 1) { std::string msg = "Only unstitched cubes can be calibrated"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } int band = 1 + ccd*2 + channel; string option = ui.GetString("OPTION"); // Set attributes (input band number) for the matrix cube(s); CubeAttributeInput att("+" + iString(band)); // Determine the file specification to the matrix file(s) if defaulted // and open if (ui.WasEntered ("MATRIX") ) { if (option == "GAIN") { string matrixFile = ui.GetFilename("MATRIX"); amatrixCube = p.SetInputCube(matrixFile, att); } else if (option == "OFFSET") { string matrixFile = ui.GetFilename("MATRIX"); bmatrixCube = p.SetInputCube(matrixFile, att); } else { //(option == "BOTH") std::string msg = "The BOTH option cannot be used if a MATRIX is entered"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } } else { int tdi = hilab.getTdi(); int bin = hilab.getBin(); if (option == "OFFSET" || option == "BOTH") { std::string bmatrixFile = "$mro/calibration"; bmatrixFile += "/B_matrix_tdi"; bmatrixFile += iString(tdi) + "_bin" + iString(bin); bmatrixCube = p.SetInputCube(bmatrixFile, att); } if (option == "GAIN" || option == "BOTH") { std::string amatrixFile = "$mro/calibration"; amatrixFile += "/A_matrix_tdi"; amatrixFile += iString(tdi) + "_bin" + iString(bin); amatrixCube = p.SetInputCube(amatrixFile, att); } } // Open the output file and set processing parameters Cube *ocube = p.SetOutputCube ("TO"); p.SetWrap (true); p.SetBrickSize ( icube->Samples(), 1, 1); // Add the radiometry group if it is not there yet. Otherwise // read the current value of the keyword CalibrationParameters. // Then delete the keyword and rewrite it after appending the // new value to it. Do it this way to avoid multiple Calibration // Parameter keywords. PvlGroup calgrp; PvlKeyword calKey; if (ocube->HasGroup("Radiometry")) { calgrp = ocube->GetGroup ("Radiometry"); if (calgrp.HasKeyword("CalibrationParameters")) { calKey = calgrp.FindKeyword("CalibrationParameters"); calgrp.DeleteKeyword( "CalibrationParameters" ); } else { calKey.SetName ("CalibrationParameters"); } } else { calgrp.SetName("Radiometry"); calKey.SetName ("CalibrationParameters"); } string keyValue = option; if (option == "GAIN") { keyValue += ":" + amatrixCube->Filename(); } else if (option == "OFFSET") { keyValue += ":" + bmatrixCube->Filename(); } else { // "BOTH" keyValue += ":"+bmatrixCube->Filename()+":"+amatrixCube->Filename(); } calKey += keyValue; calgrp += calKey; ocube->PutGroup(calgrp); // Start the processing based on the option if (option == "GAIN") { p.StartProcess(mult); } else if (option == "OFFSET") { p.StartProcess(sub); } else { //(option == "BOTH") p.StartProcess(multSub); } // Cleanup p.EndProcess(); }
void IsisMain() { // We will be warping a cube ProcessRubberSheet p; // Get the map projection file provided by the user UserInterface &ui = Application::GetUserInterface(); Pvl userPvl(ui.GetFilename("MAP")); PvlGroup &userMappingGrp = userPvl.FindGroup("Mapping",Pvl::Traverse); // Open the input cube and get the projection Cube *icube = p.SetInputCube ("FROM"); // Get the mapping group PvlGroup fromMappingGrp = icube->GetGroup("Mapping"); Projection *inproj = icube->Projection(); PvlGroup outMappingGrp = fromMappingGrp; // If the default range is FROM, then wipe out any range data in user mapping file if(ui.GetString("DEFAULTRANGE").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { if(userMappingGrp.HasKeyword("MinimumLatitude")) { userMappingGrp.DeleteKeyword("MinimumLatitude"); } if(userMappingGrp.HasKeyword("MaximumLatitude")) { userMappingGrp.DeleteKeyword("MaximumLatitude"); } if(userMappingGrp.HasKeyword("MinimumLongitude")) { userMappingGrp.DeleteKeyword("MinimumLongitude"); } if(userMappingGrp.HasKeyword("MaximumLongitude")) { userMappingGrp.DeleteKeyword("MaximumLongitude"); } } // Deal with user overrides entered in the GUI. Do this by changing the user's mapping group, which // will then overlay anything in the output mapping group. if(ui.WasEntered("MINLAT") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MinimumLatitude", ui.GetDouble("MINLAT")), Pvl::Replace ); } if(ui.WasEntered("MAXLAT") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MaximumLatitude", ui.GetDouble("MAXLAT")), Pvl::Replace ); } if(ui.WasEntered("MINLON") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MinimumLongitude", ui.GetDouble("MINLON")), Pvl::Replace ); } if(ui.WasEntered("MAXLON") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MaximumLongitude", ui.GetDouble("MAXLON")), Pvl::Replace ); } /** * If the user is changing from positive east to positive west, or vice-versa, the output minimum is really * the input maximum. However, the user mapping group must be left unaffected (an input minimum must be the * output minimum). To accomplish this, we swap the minimums/maximums in the output group ahead of time. This * causes the minimums and maximums to correlate to the output minimums and maximums. That way when we copy * the user mapping group into the output group a mimimum overrides a minimum and a maximum overrides a maximum. */ bool sameDirection = true; if(userMappingGrp.HasKeyword("LongitudeDirection")) { if(((string)userMappingGrp["LongitudeDirection"]).compare(fromMappingGrp["LongitudeDirection"]) != 0) { sameDirection = false; } } // Since the out mapping group came from the from mapping group, which came from a valid cube, // we can assume both min/max lon exists if min longitude exists. if(!sameDirection && outMappingGrp.HasKeyword("MinimumLongitude")) { double minLon = outMappingGrp["MinimumLongitude"]; double maxLon = outMappingGrp["MaximumLongitude"]; outMappingGrp["MaximumLongitude"] = minLon; outMappingGrp["MinimumLongitude"] = maxLon; } if(ui.GetString("PIXRES").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { // Resolution will be in fromMappingGrp and outMappingGrp at this time // delete from user mapping grp if(userMappingGrp.HasKeyword("Scale")) { userMappingGrp.DeleteKeyword("Scale"); } if(userMappingGrp.HasKeyword("PixelResolution")) { userMappingGrp.DeleteKeyword("PixelResolution"); } } else if(ui.GetString("PIXRES").compare("MAP") == 0 || ui.GetBoolean("MATCHMAP")) { // Resolution will be in userMappingGrp - delete all others if(outMappingGrp.HasKeyword("Scale")) { outMappingGrp.DeleteKeyword("Scale"); } if(outMappingGrp.HasKeyword("PixelResolution")) { outMappingGrp.DeleteKeyword("PixelResolution"); } if(fromMappingGrp.HasKeyword("Scale")); { fromMappingGrp.DeleteKeyword("Scale"); } if(fromMappingGrp.HasKeyword("PixelResolution")) { fromMappingGrp.DeleteKeyword("PixelResolution"); } } else if(ui.GetString("PIXRES").compare("MPP") == 0) { // Resolution specified - delete all and add to outMappingGrp if(outMappingGrp.HasKeyword("Scale")) { outMappingGrp.DeleteKeyword("Scale"); } if(outMappingGrp.HasKeyword("PixelResolution")) { outMappingGrp.DeleteKeyword("PixelResolution"); } if(fromMappingGrp.HasKeyword("Scale")) { fromMappingGrp.DeleteKeyword("Scale"); } if(fromMappingGrp.HasKeyword("PixelResolution")) { fromMappingGrp.DeleteKeyword("PixelResolution"); } if(userMappingGrp.HasKeyword("Scale")) { userMappingGrp.DeleteKeyword("Scale"); } if(userMappingGrp.HasKeyword("PixelResolution")) { userMappingGrp.DeleteKeyword("PixelResolution"); } outMappingGrp.AddKeyword(PvlKeyword("PixelResolution", ui.GetDouble("RESOLUTION"), "meters/pixel"), Pvl::Replace); } else if(ui.GetString("PIXRES").compare("PPD") == 0) { // Resolution specified - delete all and add to outMappingGrp if(outMappingGrp.HasKeyword("Scale")) { outMappingGrp.DeleteKeyword("Scale"); } if(outMappingGrp.HasKeyword("PixelResolution")) { outMappingGrp.DeleteKeyword("PixelResolution"); } if(fromMappingGrp.HasKeyword("Scale")) { fromMappingGrp.DeleteKeyword("Scale"); } if(fromMappingGrp.HasKeyword("PixelResolution")) { fromMappingGrp.DeleteKeyword("PixelResolution"); } if(userMappingGrp.HasKeyword("Scale")) { userMappingGrp.DeleteKeyword("Scale"); } if(userMappingGrp.HasKeyword("PixelResolution")) { userMappingGrp.DeleteKeyword("PixelResolution"); } outMappingGrp.AddKeyword(PvlKeyword("Scale", ui.GetDouble("RESOLUTION"), "pixels/degree"), Pvl::Replace); } // Rotation will NOT Propagate if(outMappingGrp.HasKeyword("Rotation")) { outMappingGrp.DeleteKeyword("Rotation"); } /** * The user specified map template file overrides what ever is in the * cube's mapping group. */ for(int keyword = 0; keyword < userMappingGrp.Keywords(); keyword ++) { outMappingGrp.AddKeyword(userMappingGrp[keyword], Pvl::Replace); } /** * Now, we have to deal with unit conversions. We convert only if the following are true: * 1) We used values from the input cube * 2) The values are longitudes or latitudes * 3) The map file or user-specified information uses a different measurement system than * the input cube for said values. * * The data is corrected for: * 1) Positive east/positive west * 2) Longitude domain * 3) planetographic/planetocentric. */ // First, the longitude direction if(!sameDirection) { PvlGroup longitudes = inproj->MappingLongitudes(); for(int index = 0; index < longitudes.Keywords(); index ++) { if(!userMappingGrp.HasKeyword(longitudes[index].Name())) { // use the from domain because that's where our values are coming from if(((string)userMappingGrp["LongitudeDirection"]).compare("PositiveEast") == 0) { outMappingGrp[longitudes[index].Name()] = Projection::ToPositiveEast(outMappingGrp[longitudes[index].Name()], outMappingGrp["LongitudeDomain"]); } else { outMappingGrp[longitudes[index].Name()] = Projection::ToPositiveWest(outMappingGrp[longitudes[index].Name()], outMappingGrp["LongitudeDomain"]); } } } } // The minimum/maximum longitudes should be in order now. However, if the user entered a // maximum that was lower than the minimum, or a minimum that was higher than the maximum this // may still fail. Let it throw an error when we instantiate the projection. // Second, longitude domain if(userMappingGrp.HasKeyword("LongitudeDomain")) { // user set a new domain? if((int)userMappingGrp["LongitudeDomain"] != (int)fromMappingGrp["LongitudeDomain"]) { // new domain different? PvlGroup longitudes = inproj->MappingLongitudes(); for(int index = 0; index < longitudes.Keywords(); index ++) { if(!userMappingGrp.HasKeyword(longitudes[index].Name())) { if((int)userMappingGrp["LongitudeDomain"] == 180) { outMappingGrp[longitudes[index].Name()] = Projection::To180Domain(outMappingGrp[longitudes[index].Name()]); } else { outMappingGrp[longitudes[index].Name()] = Projection::To360Domain(outMappingGrp[longitudes[index].Name()]); } } } } } // Third, planetographic/planetocentric if(userMappingGrp.HasKeyword("LatitudeType")) { // user set a new domain? if(((string)userMappingGrp["LatitudeType"]).compare(fromMappingGrp["LatitudeType"]) != 0) { // new lat type different? PvlGroup latitudes = inproj->MappingLatitudes(); for(int index = 0; index < latitudes.Keywords(); index ++) { if(!userMappingGrp.HasKeyword(latitudes[index].Name())) { if(((string)userMappingGrp["LatitudeType"]).compare("Planetographic") == 0) { outMappingGrp[latitudes[index].Name()] = Projection::ToPlanetographic( (double)fromMappingGrp[latitudes[index].Name()], (double)fromMappingGrp["EquatorialRadius"], (double)fromMappingGrp["PolarRadius"]); } else { outMappingGrp[latitudes[index].Name()] = Projection::ToPlanetocentric( (double)fromMappingGrp[latitudes[index].Name()], (double)fromMappingGrp["EquatorialRadius"], (double)fromMappingGrp["PolarRadius"]); } } } } } // If MinLon/MaxLon out of order, we weren't able to calculate the correct values if((double)outMappingGrp["MinimumLongitude"] >= (double)outMappingGrp["MaximumLongitude"]) { if(!ui.WasEntered("MINLON") || !ui.WasEntered("MAXLON")) { string msg = "Unable to determine the correct [MinimumLongitude,MaximumLongitude]."; msg += " Please specify these values in the [MINLON,MAXLON] parameters"; throw iException::Message(iException::Pvl,msg,_FILEINFO_); } } int samples,lines; Pvl mapData; // Copy to preserve cube labels so we can match cube size if (userPvl.HasObject("IsisCube")) { mapData = userPvl; mapData.FindObject("IsisCube").DeleteGroup("Mapping"); mapData.FindObject("IsisCube").AddGroup(outMappingGrp); } else { mapData.AddGroup(outMappingGrp); } // *NOTE: The UpperLeftX,UpperLeftY keywords will not be used in the CreateForCube // method, and they will instead be recalculated. This is correct. Projection *outproj = ProjectionFactory::CreateForCube(mapData,samples,lines, ui.GetBoolean("MATCHMAP")); // Set up the transform object which will simply map // output line/samps -> output lat/lons -> input line/samps Transform *transform = new map2map (icube->Samples(), icube->Lines(), icube->Projection(), samples, lines, outproj, ui.GetBoolean("TRIM")); // Allocate the output cube and add the mapping labels Cube *ocube = p.SetOutputCube ("TO", transform->OutputSamples(), transform->OutputLines(), icube->Bands()); PvlGroup cleanOutGrp = outproj->Mapping(); // ProjectionFactory::CreateForCube updated mapData to have the correct // upperleftcornerx, upperleftcornery, scale and resolution. Use these // updated numbers. cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["UpperLeftCornerX"], Pvl::Replace); cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["UpperLeftCornerY"], Pvl::Replace); cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["Scale"], Pvl::Replace); cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["PixelResolution"], Pvl::Replace); ocube->PutGroup(cleanOutGrp); // Set up the interpolator Interpolator *interp; if (ui.GetString("INTERP") == "NEARESTNEIGHBOR") { interp = new Interpolator(Interpolator::NearestNeighborType); } else if (ui.GetString("INTERP") == "BILINEAR") { interp = new Interpolator(Interpolator::BiLinearType); } else if (ui.GetString("INTERP") == "CUBICCONVOLUTION") { interp = new Interpolator(Interpolator::CubicConvolutionType); } else { string msg = "Unknow value for INTERP [" + ui.GetString("INTERP") + "]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } // Warp the cube p.StartProcess(*transform, *interp); p.EndProcess(); Application::Log(cleanOutGrp); // Cleanup delete transform; delete interp; }