Loading isis/src/clipper/apps/jitterfit/jitterfit.xml 0 → 100644 +226 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <application name="jitterfit" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> <brief> Registers lines from a normal image with lines from the check image. </brief> <description> <p> This program co-regsisters lines in the main cube (FROM) with the corrisponding line in the checkline cube (FROM2). The sensor line used to collect the checkline is used to center the registration around the same area in the main cube. </p> <p> The main input cube (FROM) is expected to be a cube from a rolling shutter instrument. The checkline cube (FROM2) is expected to contain lines of data read from the same rolling shutter instrument, but read at different times than the coorsponding line in the main cube. The check cube must also have an associated table containing the sensor line number and time the line was read. The algorithum co-registers these individual checklines to the main cube and calculates an offset in the line and sample directions. It then fits an Nth order polynomial through the offsets and time to characterize the jitter. The coefficients are then written to the cube labels so the rolling shutter camera model can adjust the look direction of each pixel in the model's detector map. </p> </description> <groups> <group name="Registration"> <parameter name="FROM"> <type>cube</type> <fileMode>input</fileMode> <brief> Input cube containing an image that need jitter correction. </brief> <description> This input cube is the cube that needs to be de-jittered. The algorithms jitterfit uses are designed for a rolling shutter instrument with an accompanying check line cube file (see main description). This cube file must be writable. Coefficients to adjust the jitter will be written to the cube labels for use by the rolling shutter cammera model. </description> <filter> *.cub </filter> </parameter> <parameter name="FROM2"> <type>cube</type> <fileMode>input</fileMode> <brief> Input cube containing the check lines. </brief> <description> This input cube is the check line cube. It contains a set of lines that were repetedly read from the sensor array intersperesed with the readout of the main image data. EXPAND </description> <filter> *.cub </filter> </parameter> <parameter name="DEFFILE"> <type>filename</type> <fileMode>input</fileMode> <brief> The Auto Registration template </brief> <description> The parameter template to use for the Autoregistration process. The default template calls the Maximum Correlation pattern matching algorithm with predefined parameter values. There are other templates available in the system autoreg/template directory. Also, the user can use the 'autoregtemplate' application to create a new template file. Example minimal autoregistration definition file: <pre> Object = AutoRegistration Group = Algorithm Name = MaximumCorrelation Tolerance = 0.7 SubPixelAccuracy = True EndGroup Group = PatternChip Samples = 1391 Lines = 1 EndGroup Group = SearchChip Samples = 1399 Lines = 7 EndGroup Group = SurfaceModel WindowSize = 7 EndGroup EndObject </pre> </description> <filter> *.def </filter> </parameter> <parameter name="SCALE"> <type>double</type> <default><item>4.0</item></default> <brief> The scale of the image. </brief> <description> This is the scale of the image. Only use this parameter if you have enlarged the main cube. This will allow the program to access the correct normal cube line number based on the un-enlarged checktable values. Example: For a 4x enlargement set this value to 4.0. ADD WHY </description> </parameter> <parameter name="TO"> <type>filename</type> <fileMode>output</fileMode> <internalDefault>None</internalDefault> <brief> Output file where the registration results will be written. </brief> <description> SOMETHING </description> <filter> *.csv </filter> </parameter> <parameter name="TO2"> <type>filename</type> <fileMode>output</fileMode> <internalDefault>None</internalDefault> <brief> Output file where the registration statistics will be written. </brief> <description> SOMETHING </description> <filter> *.csv </filter> </parameter> </group> <group name="Fitting"> <parameter name="TOLERANCE"> <type>double</type> <brief> The tolerance that determines which points will be excluded based on the goodness of fit of the registration. </brief> <description> SOMETHING </description> <default><item>.7</item></default> <minimum inclusive="yes">0.0</minimum> </parameter> <parameter name="DEGREE"> <type>integer</type> <brief> The order of polynomial to solve for. </brief> <description> SOMETHING </description> <default><item>3</item></default> <minimum inclusive="yes">1</minimum> </parameter> <parameter name="MAXTIME"> <type>double</type> <brief> The time, in seconds, that the last line was taken. The minimum is .0026 seconds it takes for a 2250 line image to be taken plus the time it takes to take 60 checklines. </brief> <description> SOMETHING WHAT IS THIS USED FOR </description> <default><item>0.0027114285714286</item></default> <minimum inclusive="no">0.0</minimum> </parameter> <parameter name="COEFFICIENTTO"> <type>filename</type> <fileMode>output</fileMode> <brief> Output file that holds the coefficients. </brief> <description> SOMETHING FORMAT </description> <filter> *.csv </filter> </parameter> <parameter name="RESIDUALTO"> <type>filename</type> <fileMode>output</fileMode> <internalDefault>None</internalDefault> <brief> Output file that holds the residuals. </brief> <description> SOMETHING </description> <filter> *.csv </filter> </parameter> </group> </groups> </application> isis/src/clipper/apps/jitterfit/main.cpp 0 → 100644 +234 −0 Original line number Diff line number Diff line #include "Isis.h" #include <iostream> #include <QList> #include <QString> #include "AutoReg.h" #include "AutoRegFactory.h" #include "BasisFunction.h" #include "Chip.h" #include "Cube.h" #include "CSVReader.h" #include "FileName.h" #include "LeastSquares.h" #include "NthOrderPolynomial.h" #include "Pvl.h" #include "Table.h" #include "UserInterface.h" using namespace std; using namespace Isis; struct RegistrationData { int checkLine; //0 int checkSample; //1 double checkTime; //2 double matchedLine; //3 double matchedSample; //4 double matchedTime; //5 double deltaLine; //6 double deltaSample; //7 double goodness; //8 Goodness of fit int success; //9 }; void IsisMain() { bool registrationFileSpecified = false; UserInterface &ui = Application::GetUserInterface(); Cube jitterCube; jitterCube.open(ui.GetFileName("FROM"), "rw"); Cube checkCube; checkCube.open(ui.GetFileName("FROM2"), "r"); Pvl defFile; defFile.read(ui.GetFileName("DEFFILE")); AutoReg *ar = AutoRegFactory::Create(defFile); double scale = ui.GetDouble("SCALE"); int pointSpacing = jitterCube.sampleCount(); // Setup the registration results file ofstream outputFile; if (ui.WasEntered("TO")) { registrationFileSpecified = true; QString to(FileName(ui.GetFileName("TO")).expanded()); outputFile.open(to.toLatin1().data()); outputFile << "# checkline line, checkline sample, checkline time taken, " "matched jittered image line, matched jittered image " "sample, matched jittered image time taken, delta line, " "delta sample, goodness of fit, registration success " << endl; } // Question: Why use a file name here? Can't Table read from an open Cube? Table mainReadouts(QString("Normalized Main Readout Line Times"), jitterCube.fileName()); Table checklineReadouts(QString("Normalized Checkline Readout Line Times"), checkCube.fileName()); // Register each check line to the area near the corrisponding main image line using the // registration definition file QList<RegistrationData> registrationData; for (int k = 0; k < checkCube.lineCount(); k++) { int checklineLine = checklineReadouts[k][0]; int mainLine = mainReadouts[checklineLine][0]; int sample = (int)(pointSpacing / 2.0 + 0.5); ar->PatternChip()->TackCube(sample, k + 1); ar->PatternChip()->Load(checkCube); ar->SearchChip()->TackCube(sample, checklineLine * scale); // The checkline will correspond to the line number that the checkCube was taken at ar->SearchChip()->Load(jitterCube); ar->Register(); if (registrationFileSpecified) { outputFile << checklineLine << "," << sample/scale << "," << std::setprecision(14) << double(checklineReadouts[k][1]) << "," << ar->CubeLine()/scale << "," << ar->CubeSample()/scale << "," << double(mainReadouts[mainLine][1]) << "," << checklineLine - ar->CubeLine()/scale << "," << sample/scale - ar->CubeSample()/scale << "," << ar->GoodnessOfFit() << "," << ar->Success() << endl; } RegistrationData checkLineRegistration; checkLineRegistration.checkLine = checklineLine; checkLineRegistration.checkSample = sample/scale; checkLineRegistration.checkTime = double(checklineReadouts[k][1]); checkLineRegistration.matchedLine = ar->CubeLine()/scale; checkLineRegistration.matchedSample = ar->CubeSample()/scale; checkLineRegistration.matchedTime = double(mainReadouts[mainLine][1]); checkLineRegistration.deltaLine = checklineLine - ar->CubeLine()/scale; checkLineRegistration.deltaSample = sample/scale - ar->CubeSample()/scale; checkLineRegistration.goodness = ar->GoodnessOfFit(); checkLineRegistration.success = ar->Success(); registrationData.append(checkLineRegistration); } //!!!!!!!!FOR INTERNAL STORAGE BETWEEN THE REGISTRATION STEP AND THE FITTING STEP !!!!!!! //!!!!!!!! We are going to use a QList of registrationData structs !!!!!!! if (ui.WasEntered("TO2")) { ofstream regStatsFile; QString to(FileName(ui.GetFileName("TO2")).expanded()); regStatsFile.open(to.toLatin1().data()); Pvl regStats = ar->RegistrationStatistics(); regStatsFile << regStats << endl; regStatsFile << endl; regStatsFile.close(); } if (registrationFileSpecified) { outputFile.close(); } // Solve for the coefficients of the Nth order polynomial double tolerance = ui.GetDouble("TOLERANCE"); int degree = ui.GetInteger("DEGREE"); double maxTime = ui.GetDouble("MAXTIME"); BasisFunction *lineFunction = new NthOrderPolynomial(degree); BasisFunction *sampleFunction = new NthOrderPolynomial(degree); LeastSquares lsqLine(*lineFunction, false, false, false, false); LeastSquares lsqSample(*sampleFunction, false, false, false, false); std::vector<double> known(2); for (int i = 0; i < registrationData.size(); i++) { RegistrationData checkLineRow = registrationData[i]; if (checkLineRow.goodness >= tolerance) { /* Normalization Equation * * a = min of scale * b = max of scale * * ((b - a)(x - min(x)) / (max(x) - min(x))) + a * * We're normalizing from -1 to 1 so the equation below is simplified */ known[0] = ((2 * checkLineRow.matchedTime) / maxTime) - 1; known[1] = ((2 * checkLineRow.checkTime) / maxTime) - 1; lsqLine.AddKnown(known, checkLineRow.deltaLine); lsqSample.AddKnown(known, checkLineRow.deltaSample); } } lsqLine.Solve(); lsqSample.Solve(); // Write the coefficients to COEFFICIENTTO file and the main cube label ofstream outputCoefficientFile; QString coefficientTo(FileName(ui.GetFileName("COEFFICIENTTO")).expanded()); outputCoefficientFile.open(coefficientTo.toLatin1().data()); outputCoefficientFile << "# Line, Sample" << endl; PvlKeyword &jitterLineCoefficients = jitterCube.label()->findKeyword("JitterLineCoefficients", PvlObject::Traverse); PvlKeyword &jitterSampleCoefficients = jitterCube.label()->findKeyword("JitterSampleCoefficients", PvlObject::Traverse); for (int i = 0; i < degree; i++) { outputCoefficientFile << std::setprecision(14) << lineFunction->Coefficient(i) << "," << std::setprecision(14) << sampleFunction->Coefficient(i) << endl; if (i == 0) { jitterLineCoefficients.setValue(toString(lineFunction->Coefficient(i))); jitterSampleCoefficients.setValue(toString(sampleFunction->Coefficient(i))); } else { jitterLineCoefficients += toString(lineFunction->Coefficient(i)); jitterSampleCoefficients += toString(sampleFunction->Coefficient(i)); } } outputCoefficientFile.close(); // Write the registered line/samp, solved line/samp, residual line/samp, time if (ui.WasEntered("RESIDUALTO")) { ofstream outputResidualFile; QString residualTo(FileName(ui.GetFileName("RESIDUALTO")).expanded()); outputResidualFile.open(residualTo.toLatin1().data()); outputResidualFile << "# Registered Line, Solved Line, Registered Line Residual, " "Registered Sample, Solved Sample, Sample Residual, Time Taken" << endl; for (unsigned int i = 0; i < lsqLine.Residuals().size(); i++) { RegistrationData checkLineRow = registrationData[i]; double solvedLine = 0; double solvedSample = 0; for (int k = 0; k < degree; k++) { solvedLine = solvedLine + lineFunction->Coefficient(k) * pow(checkLineRow.matchedTime, k+1); solvedSample = solvedSample + sampleFunction->Coefficient(k) * pow(checkLineRow.matchedTime, k+1); } outputResidualFile << std::setprecision(14) << checkLineRow.matchedLine << "," << std::setprecision(14) << checkLineRow.checkLine - solvedLine << "," << std::setprecision(14) << lsqLine.Residual(i) << "," << std::setprecision(14) << checkLineRow.matchedSample << "," << std::setprecision(14) << checkLineRow.checkSample - solvedSample << "," << std::setprecision(14) << lsqSample.Residual(i) << "," << std::setprecision(14) << checkLineRow.matchedTime << endl; } outputResidualFile.close(); } delete lineFunction; delete sampleFunction; } isis/src/clipper/apps/jitterfit/tsts/default/Makefile 0 → 100644 +15 −0 Original line number Diff line number Diff line APPNAME = jitterfit include $(ISISROOT)/make/isismake.tsts commands: # To test proper run cp $(INPUT)/simulated_clipper_eis_nac_rolling_shutter.cub $(OUTPUT) > /dev/null; $(APPNAME) \ from=$(OUTPUT)/simulated_clipper_eis_nac_rolling_shutter.cub \ from2=$(INPUT)/simulated_clipper_eis_nac_rolling_shutter_checkline.cub \ deffile=$(INPUT)/S046mos1400x2250.def \ coefficientto=$(OUTPUT)/coefficients.txt \ scale=1.0 > /dev/null; catlab from=$(OUTPUT)/simulated_clipper_eis_nac_rolling_shutter.cub \ to=$(OUTPUT)/simulated_clipper_eis_nac_rolling_shutter_labels.pvl > /dev/null; Loading
isis/src/clipper/apps/jitterfit/jitterfit.xml 0 → 100644 +226 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <application name="jitterfit" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> <brief> Registers lines from a normal image with lines from the check image. </brief> <description> <p> This program co-regsisters lines in the main cube (FROM) with the corrisponding line in the checkline cube (FROM2). The sensor line used to collect the checkline is used to center the registration around the same area in the main cube. </p> <p> The main input cube (FROM) is expected to be a cube from a rolling shutter instrument. The checkline cube (FROM2) is expected to contain lines of data read from the same rolling shutter instrument, but read at different times than the coorsponding line in the main cube. The check cube must also have an associated table containing the sensor line number and time the line was read. The algorithum co-registers these individual checklines to the main cube and calculates an offset in the line and sample directions. It then fits an Nth order polynomial through the offsets and time to characterize the jitter. The coefficients are then written to the cube labels so the rolling shutter camera model can adjust the look direction of each pixel in the model's detector map. </p> </description> <groups> <group name="Registration"> <parameter name="FROM"> <type>cube</type> <fileMode>input</fileMode> <brief> Input cube containing an image that need jitter correction. </brief> <description> This input cube is the cube that needs to be de-jittered. The algorithms jitterfit uses are designed for a rolling shutter instrument with an accompanying check line cube file (see main description). This cube file must be writable. Coefficients to adjust the jitter will be written to the cube labels for use by the rolling shutter cammera model. </description> <filter> *.cub </filter> </parameter> <parameter name="FROM2"> <type>cube</type> <fileMode>input</fileMode> <brief> Input cube containing the check lines. </brief> <description> This input cube is the check line cube. It contains a set of lines that were repetedly read from the sensor array intersperesed with the readout of the main image data. EXPAND </description> <filter> *.cub </filter> </parameter> <parameter name="DEFFILE"> <type>filename</type> <fileMode>input</fileMode> <brief> The Auto Registration template </brief> <description> The parameter template to use for the Autoregistration process. The default template calls the Maximum Correlation pattern matching algorithm with predefined parameter values. There are other templates available in the system autoreg/template directory. Also, the user can use the 'autoregtemplate' application to create a new template file. Example minimal autoregistration definition file: <pre> Object = AutoRegistration Group = Algorithm Name = MaximumCorrelation Tolerance = 0.7 SubPixelAccuracy = True EndGroup Group = PatternChip Samples = 1391 Lines = 1 EndGroup Group = SearchChip Samples = 1399 Lines = 7 EndGroup Group = SurfaceModel WindowSize = 7 EndGroup EndObject </pre> </description> <filter> *.def </filter> </parameter> <parameter name="SCALE"> <type>double</type> <default><item>4.0</item></default> <brief> The scale of the image. </brief> <description> This is the scale of the image. Only use this parameter if you have enlarged the main cube. This will allow the program to access the correct normal cube line number based on the un-enlarged checktable values. Example: For a 4x enlargement set this value to 4.0. ADD WHY </description> </parameter> <parameter name="TO"> <type>filename</type> <fileMode>output</fileMode> <internalDefault>None</internalDefault> <brief> Output file where the registration results will be written. </brief> <description> SOMETHING </description> <filter> *.csv </filter> </parameter> <parameter name="TO2"> <type>filename</type> <fileMode>output</fileMode> <internalDefault>None</internalDefault> <brief> Output file where the registration statistics will be written. </brief> <description> SOMETHING </description> <filter> *.csv </filter> </parameter> </group> <group name="Fitting"> <parameter name="TOLERANCE"> <type>double</type> <brief> The tolerance that determines which points will be excluded based on the goodness of fit of the registration. </brief> <description> SOMETHING </description> <default><item>.7</item></default> <minimum inclusive="yes">0.0</minimum> </parameter> <parameter name="DEGREE"> <type>integer</type> <brief> The order of polynomial to solve for. </brief> <description> SOMETHING </description> <default><item>3</item></default> <minimum inclusive="yes">1</minimum> </parameter> <parameter name="MAXTIME"> <type>double</type> <brief> The time, in seconds, that the last line was taken. The minimum is .0026 seconds it takes for a 2250 line image to be taken plus the time it takes to take 60 checklines. </brief> <description> SOMETHING WHAT IS THIS USED FOR </description> <default><item>0.0027114285714286</item></default> <minimum inclusive="no">0.0</minimum> </parameter> <parameter name="COEFFICIENTTO"> <type>filename</type> <fileMode>output</fileMode> <brief> Output file that holds the coefficients. </brief> <description> SOMETHING FORMAT </description> <filter> *.csv </filter> </parameter> <parameter name="RESIDUALTO"> <type>filename</type> <fileMode>output</fileMode> <internalDefault>None</internalDefault> <brief> Output file that holds the residuals. </brief> <description> SOMETHING </description> <filter> *.csv </filter> </parameter> </group> </groups> </application>
isis/src/clipper/apps/jitterfit/main.cpp 0 → 100644 +234 −0 Original line number Diff line number Diff line #include "Isis.h" #include <iostream> #include <QList> #include <QString> #include "AutoReg.h" #include "AutoRegFactory.h" #include "BasisFunction.h" #include "Chip.h" #include "Cube.h" #include "CSVReader.h" #include "FileName.h" #include "LeastSquares.h" #include "NthOrderPolynomial.h" #include "Pvl.h" #include "Table.h" #include "UserInterface.h" using namespace std; using namespace Isis; struct RegistrationData { int checkLine; //0 int checkSample; //1 double checkTime; //2 double matchedLine; //3 double matchedSample; //4 double matchedTime; //5 double deltaLine; //6 double deltaSample; //7 double goodness; //8 Goodness of fit int success; //9 }; void IsisMain() { bool registrationFileSpecified = false; UserInterface &ui = Application::GetUserInterface(); Cube jitterCube; jitterCube.open(ui.GetFileName("FROM"), "rw"); Cube checkCube; checkCube.open(ui.GetFileName("FROM2"), "r"); Pvl defFile; defFile.read(ui.GetFileName("DEFFILE")); AutoReg *ar = AutoRegFactory::Create(defFile); double scale = ui.GetDouble("SCALE"); int pointSpacing = jitterCube.sampleCount(); // Setup the registration results file ofstream outputFile; if (ui.WasEntered("TO")) { registrationFileSpecified = true; QString to(FileName(ui.GetFileName("TO")).expanded()); outputFile.open(to.toLatin1().data()); outputFile << "# checkline line, checkline sample, checkline time taken, " "matched jittered image line, matched jittered image " "sample, matched jittered image time taken, delta line, " "delta sample, goodness of fit, registration success " << endl; } // Question: Why use a file name here? Can't Table read from an open Cube? Table mainReadouts(QString("Normalized Main Readout Line Times"), jitterCube.fileName()); Table checklineReadouts(QString("Normalized Checkline Readout Line Times"), checkCube.fileName()); // Register each check line to the area near the corrisponding main image line using the // registration definition file QList<RegistrationData> registrationData; for (int k = 0; k < checkCube.lineCount(); k++) { int checklineLine = checklineReadouts[k][0]; int mainLine = mainReadouts[checklineLine][0]; int sample = (int)(pointSpacing / 2.0 + 0.5); ar->PatternChip()->TackCube(sample, k + 1); ar->PatternChip()->Load(checkCube); ar->SearchChip()->TackCube(sample, checklineLine * scale); // The checkline will correspond to the line number that the checkCube was taken at ar->SearchChip()->Load(jitterCube); ar->Register(); if (registrationFileSpecified) { outputFile << checklineLine << "," << sample/scale << "," << std::setprecision(14) << double(checklineReadouts[k][1]) << "," << ar->CubeLine()/scale << "," << ar->CubeSample()/scale << "," << double(mainReadouts[mainLine][1]) << "," << checklineLine - ar->CubeLine()/scale << "," << sample/scale - ar->CubeSample()/scale << "," << ar->GoodnessOfFit() << "," << ar->Success() << endl; } RegistrationData checkLineRegistration; checkLineRegistration.checkLine = checklineLine; checkLineRegistration.checkSample = sample/scale; checkLineRegistration.checkTime = double(checklineReadouts[k][1]); checkLineRegistration.matchedLine = ar->CubeLine()/scale; checkLineRegistration.matchedSample = ar->CubeSample()/scale; checkLineRegistration.matchedTime = double(mainReadouts[mainLine][1]); checkLineRegistration.deltaLine = checklineLine - ar->CubeLine()/scale; checkLineRegistration.deltaSample = sample/scale - ar->CubeSample()/scale; checkLineRegistration.goodness = ar->GoodnessOfFit(); checkLineRegistration.success = ar->Success(); registrationData.append(checkLineRegistration); } //!!!!!!!!FOR INTERNAL STORAGE BETWEEN THE REGISTRATION STEP AND THE FITTING STEP !!!!!!! //!!!!!!!! We are going to use a QList of registrationData structs !!!!!!! if (ui.WasEntered("TO2")) { ofstream regStatsFile; QString to(FileName(ui.GetFileName("TO2")).expanded()); regStatsFile.open(to.toLatin1().data()); Pvl regStats = ar->RegistrationStatistics(); regStatsFile << regStats << endl; regStatsFile << endl; regStatsFile.close(); } if (registrationFileSpecified) { outputFile.close(); } // Solve for the coefficients of the Nth order polynomial double tolerance = ui.GetDouble("TOLERANCE"); int degree = ui.GetInteger("DEGREE"); double maxTime = ui.GetDouble("MAXTIME"); BasisFunction *lineFunction = new NthOrderPolynomial(degree); BasisFunction *sampleFunction = new NthOrderPolynomial(degree); LeastSquares lsqLine(*lineFunction, false, false, false, false); LeastSquares lsqSample(*sampleFunction, false, false, false, false); std::vector<double> known(2); for (int i = 0; i < registrationData.size(); i++) { RegistrationData checkLineRow = registrationData[i]; if (checkLineRow.goodness >= tolerance) { /* Normalization Equation * * a = min of scale * b = max of scale * * ((b - a)(x - min(x)) / (max(x) - min(x))) + a * * We're normalizing from -1 to 1 so the equation below is simplified */ known[0] = ((2 * checkLineRow.matchedTime) / maxTime) - 1; known[1] = ((2 * checkLineRow.checkTime) / maxTime) - 1; lsqLine.AddKnown(known, checkLineRow.deltaLine); lsqSample.AddKnown(known, checkLineRow.deltaSample); } } lsqLine.Solve(); lsqSample.Solve(); // Write the coefficients to COEFFICIENTTO file and the main cube label ofstream outputCoefficientFile; QString coefficientTo(FileName(ui.GetFileName("COEFFICIENTTO")).expanded()); outputCoefficientFile.open(coefficientTo.toLatin1().data()); outputCoefficientFile << "# Line, Sample" << endl; PvlKeyword &jitterLineCoefficients = jitterCube.label()->findKeyword("JitterLineCoefficients", PvlObject::Traverse); PvlKeyword &jitterSampleCoefficients = jitterCube.label()->findKeyword("JitterSampleCoefficients", PvlObject::Traverse); for (int i = 0; i < degree; i++) { outputCoefficientFile << std::setprecision(14) << lineFunction->Coefficient(i) << "," << std::setprecision(14) << sampleFunction->Coefficient(i) << endl; if (i == 0) { jitterLineCoefficients.setValue(toString(lineFunction->Coefficient(i))); jitterSampleCoefficients.setValue(toString(sampleFunction->Coefficient(i))); } else { jitterLineCoefficients += toString(lineFunction->Coefficient(i)); jitterSampleCoefficients += toString(sampleFunction->Coefficient(i)); } } outputCoefficientFile.close(); // Write the registered line/samp, solved line/samp, residual line/samp, time if (ui.WasEntered("RESIDUALTO")) { ofstream outputResidualFile; QString residualTo(FileName(ui.GetFileName("RESIDUALTO")).expanded()); outputResidualFile.open(residualTo.toLatin1().data()); outputResidualFile << "# Registered Line, Solved Line, Registered Line Residual, " "Registered Sample, Solved Sample, Sample Residual, Time Taken" << endl; for (unsigned int i = 0; i < lsqLine.Residuals().size(); i++) { RegistrationData checkLineRow = registrationData[i]; double solvedLine = 0; double solvedSample = 0; for (int k = 0; k < degree; k++) { solvedLine = solvedLine + lineFunction->Coefficient(k) * pow(checkLineRow.matchedTime, k+1); solvedSample = solvedSample + sampleFunction->Coefficient(k) * pow(checkLineRow.matchedTime, k+1); } outputResidualFile << std::setprecision(14) << checkLineRow.matchedLine << "," << std::setprecision(14) << checkLineRow.checkLine - solvedLine << "," << std::setprecision(14) << lsqLine.Residual(i) << "," << std::setprecision(14) << checkLineRow.matchedSample << "," << std::setprecision(14) << checkLineRow.checkSample - solvedSample << "," << std::setprecision(14) << lsqSample.Residual(i) << "," << std::setprecision(14) << checkLineRow.matchedTime << endl; } outputResidualFile.close(); } delete lineFunction; delete sampleFunction; }
isis/src/clipper/apps/jitterfit/tsts/default/Makefile 0 → 100644 +15 −0 Original line number Diff line number Diff line APPNAME = jitterfit include $(ISISROOT)/make/isismake.tsts commands: # To test proper run cp $(INPUT)/simulated_clipper_eis_nac_rolling_shutter.cub $(OUTPUT) > /dev/null; $(APPNAME) \ from=$(OUTPUT)/simulated_clipper_eis_nac_rolling_shutter.cub \ from2=$(INPUT)/simulated_clipper_eis_nac_rolling_shutter_checkline.cub \ deffile=$(INPUT)/S046mos1400x2250.def \ coefficientto=$(OUTPUT)/coefficients.txt \ scale=1.0 > /dev/null; catlab from=$(OUTPUT)/simulated_clipper_eis_nac_rolling_shutter.cub \ to=$(OUTPUT)/simulated_clipper_eis_nac_rolling_shutter_labels.pvl > /dev/null;