Isis 3.0 Application Source Code Reference |
Home |
00001 #include "Isis.h" 00002 00003 #include <vector> 00004 00005 #include <QDir> 00006 00007 #include "Brick.h" 00008 #include "Camera.h" 00009 #include "Constants.h" 00010 #include "Cube.h" 00011 #include "CubeAttribute.h" 00012 #include "ProcessByBrick.h" 00013 #include "SpecialPixel.h" 00014 #include "Statistics.h" 00015 #include "iTime.h" 00016 00017 using namespace Isis; 00018 using namespace std; 00019 00020 #define POLAR_MODE_SAMPLES 1024 00021 #define NO_POLAR_MODE_SAMPLES 704 00022 #define BW_BANDS 1 00023 #define VIS_LINES 14 00024 #define COLOR_BANDS 5 00025 #define UV_SAMPLES 128 00026 #define UV_LINES 4 00027 #define UV_BANDS 2 00028 #define KM_PER_AU 149597871 00029 00030 void ResetGlobals (); 00031 void Calibrate ( Buffer &in, Buffer &out ); 00032 void CopyCubeIntoBuffer ( string &fileString, Buffer* &data); 00033 double min ( double a, double b ); 00034 00035 void GetDark(string fileString, double temp, double time, Buffer* &data1, Buffer* &data2, double & temp1, double & temp2, string & file1, string & file2); 00036 void GetMask(string &fileString, double temp, Buffer* &data); 00037 00038 vector<double> g_iofResponsivity; 00039 vector<double> g_radianceResponsivity; 00040 00041 bool g_dark = true, g_flatfield = true, g_radiometric = true, g_iof = true, g_specpix = true; 00042 00043 double g_exposure; // Exposure duration 00044 double g_solarDistance = 1.01; // average distance in [AU] 00045 double g_startTemperature, g_endTemperature; 00046 double g_temp1, g_temp2; 00047 00048 int g_numFrames; 00049 00050 vector<int> g_bands; 00051 00052 Buffer *g_darkCube1, *g_darkCube2, *g_flatCube, *g_specpixCube; 00053 00054 void IsisMain () { 00055 ResetGlobals(); 00056 UserInterface &ui = Application::GetUserInterface(); 00057 00058 ProcessByBrick p; 00059 Cube *icube = p.SetInputCube("FROM"); 00060 00061 // Make sure it is a WAC cube 00062 Isis::PvlGroup &inst = icube->getLabel()->FindGroup("Instrument", Pvl::Traverse); 00063 iString instId = (string) inst["InstrumentId"]; 00064 instId.UpCase(); 00065 if (instId != "WAC-VIS" && instId != "WAC-UV") { 00066 string msg = "This program is intended for use on LROC WAC images only. ["; 00067 msg += icube->getFilename() + "] does not appear to be a WAC image."; 00068 throw iException::Message(iException::User, msg, _FILEINFO_); 00069 } 00070 00071 // And check if it has already run through calibration 00072 if (icube->getLabel()->FindObject("IsisCube").HasGroup("Radiometry")) { 00073 string msg = "This image has already been calibrated"; 00074 throw iException::Message(iException::User, msg, _FILEINFO_); 00075 } 00076 00077 if (icube->getLabel()->FindObject("IsisCube").HasGroup("AlphaCube")) { 00078 string msg = "This application can not be run on any image that has been geometrically transformed (i.e. scaled, rotated, sheared, or reflected) or cropped."; 00079 throw iException::Message(iException::User, msg, _FILEINFO_); 00080 } 00081 00082 g_dark = ui.GetBoolean("DARK"); 00083 g_flatfield = ui.GetBoolean("FLATFIELD"); 00084 g_radiometric = ui.GetBoolean("RADIOMETRIC"); 00085 g_iof = (ui.GetString("RADIOMETRICTYPE") == "IOF"); 00086 g_specpix = ui.GetBoolean("SPECIALPIXELS"); 00087 00088 // Determine the dark/flat files to use 00089 iString offset = (string) inst["BackgroundOffset"]; 00090 iString mode = (string) inst["Mode"]; 00091 iString instModeId = (string) inst["InstrumentModeId"]; 00092 instModeId.UpCase(); 00093 00094 if (instModeId == "COLOR" && (string) inst["InstrumentId"] == "WAC-UV") 00095 instModeId = "UV"; 00096 else if (instModeId == "VIS") 00097 instModeId = "COLOR"; 00098 00099 g_startTemperature = (double) inst["BeginTemperatureFpa"]; 00100 g_endTemperature = (double) inst["EndTemperatureFpa"]; 00101 00102 g_numFrames = (int) inst["NumFramelets"]; 00103 00104 vector<string> darkFiles; 00105 ui.GetAsString("DARKFILE", darkFiles); 00106 iString flatFile = ui.GetAsString("FLATFIELDFILE"); 00107 iString radFile = ui.GetAsString("RADIOMETRICFILE"); 00108 iString specpixFile = ui.GetAsString("SPECIALPIXELSFILE"); 00109 00110 // Figure out which bands are input 00111 for (int i = 1; i <= icube->getBandCount(); i++) { 00112 g_bands.push_back(icube->getPhysicalBand(i)); 00113 } 00114 00115 Isis::PvlGroup &bandBin = icube->getLabel()->FindGroup("BandBin", Pvl::Traverse); 00116 iString filter = (string) bandBin["Center"][0]; 00117 00118 if (g_dark) { 00119 if (darkFiles.size() == 0 || darkFiles[0] =="Default" || darkFiles[0].length() == 0) { 00120 darkFiles.resize(2); 00121 double temp = (double) inst["MiddleTemperatureFpa"]; 00122 double time = iTime(inst["StartTime"][0]).Et(); 00123 string darkFile = "$lro/calibration/wac_darks/WAC_" + instModeId; 00124 if (instModeId == "BW") 00125 darkFile += "_" + filter + "_Mode" + mode; 00126 darkFile += "_Offset" + offset + "_*C_*T_Dark.????.cub"; 00127 GetDark (darkFile, temp, time, g_darkCube1, g_darkCube2, g_temp1, g_temp2, darkFiles[0], darkFiles[1]); 00128 } 00129 else if (darkFiles.size() == 1) { 00130 CopyCubeIntoBuffer(darkFiles[0], g_darkCube1); 00131 g_temp1 = 0.0; 00132 g_darkCube2 = new Buffer(*g_darkCube1); 00133 g_temp2 = g_temp1; 00134 } 00135 else { 00136 CopyCubeIntoBuffer(darkFiles[0], g_darkCube1); 00137 int index = darkFiles[0].find_last_of("_"); 00138 g_temp1 = iString(darkFiles[0].substr( darkFiles[0].find_last_of("_", index-1), index)).ToDouble(); 00139 CopyCubeIntoBuffer(darkFiles[1], g_darkCube2); 00140 index = darkFiles[1].find_last_of("_"); 00141 g_temp2 = iString(darkFiles[1].substr( darkFiles[1].find_last_of("_", index-1), index)).ToDouble(); 00142 } 00143 } 00144 00145 if (g_flatfield) { 00146 if (flatFile.Equal("Default") || flatFile.length() == 0) { 00147 flatFile = "$lro/calibration/wac_flats/WAC_" + instModeId; 00148 if (instModeId == "BW") 00149 flatFile += "_" + filter + "_Mode" + mode; 00150 flatFile += "_Flatfield.????.cub"; 00151 } 00152 CopyCubeIntoBuffer(flatFile, g_flatCube); 00153 } 00154 00155 PvlKeyword responsivity; 00156 00157 if (g_radiometric) { 00158 00159 Isis::PvlKeyword &bands = icube->getLabel()->FindGroup("BandBin", Pvl::Traverse).FindKeyword("FilterNumber"); 00160 00161 if (radFile.Equal("Default") || radFile.length() == 0) 00162 radFile = "$lro/calibration/WAC_RadiometricResponsivity.????.pvl"; 00163 00164 Filename radFilename(radFile); 00165 if ((radFilename.Expanded()).find("?") != string::npos) 00166 radFilename.HighestVersion(); 00167 if (!radFilename.Exists()) { 00168 string msg = radFile + " does not exist."; 00169 throw iException::Message(iException::User, msg, _FILEINFO_); 00170 } 00171 00172 Pvl radPvl(radFilename.Expanded()); 00173 00174 if (g_iof) { 00175 responsivity = radPvl["IOF"]; 00176 00177 for (int i = 0; i < bands.Size(); i++) 00178 g_iofResponsivity.push_back(responsivity[(int)bands[i] - 1]); 00179 00180 try { 00181 iTime startTime((string) inst["StartTime"]); 00182 double etStart = startTime.Et(); 00183 // Get the distance between the Moon and the Sun at the given time in 00184 // Astronomical Units (AU) 00185 string bspKernel1 = p.MissionData("lro", "/kernels/tspk/moon_pa_de421_1900-2050.bpc", false); 00186 string bspKernel2 = p.MissionData("lro", "/kernels/tspk/de421.bsp", false); 00187 furnsh_c(bspKernel1.c_str()); 00188 furnsh_c(bspKernel2.c_str()); 00189 string pckKernel1 = p.MissionData("base", "/kernels/pck/pck?????.tpc", true); 00190 string pckKernel2 = p.MissionData("lro", "/kernels/pck/moon_080317.tf", false); 00191 string pckKernel3 = p.MissionData("lro", "/kernels/pck/moon_assoc_me.tf", false); 00192 furnsh_c(pckKernel1.c_str()); 00193 furnsh_c(pckKernel2.c_str()); 00194 furnsh_c(pckKernel3.c_str()); 00195 double sunpos[6], lt; 00196 spkezr_c("sun", etStart, "MOON_ME", "LT+S", "MOON", sunpos, <); 00197 g_solarDistance = vnorm_c(sunpos) / KM_PER_AU; 00198 unload_c(bspKernel1.c_str()); 00199 unload_c(bspKernel2.c_str()); 00200 unload_c(pckKernel1.c_str()); 00201 unload_c(pckKernel2.c_str()); 00202 unload_c(pckKernel3.c_str()); 00203 } 00204 catch (iException &e) { 00205 string msg = "Can not find necessary SPICE kernels for converting to IOF"; 00206 throw iException::Message(iException::User, msg, _FILEINFO_); 00207 } 00208 } 00209 else { 00210 responsivity = radPvl["Radiance"]; 00211 for (int i = 0; i < bands.Size(); i++) 00212 g_radianceResponsivity.push_back(responsivity[(int)bands[i] - 1]); 00213 } 00214 } 00215 00216 if (g_specpix) { 00217 if (specpixFile.Equal("Default") || specpixFile.length() == 0) { 00218 specpixFile = "$lro/calibration/wac_masks/WAC_" + instModeId; 00219 double temp = (double) inst["MiddleTemperatureFpa"]; 00220 if (instModeId == "BW") 00221 specpixFile += "_" + filter + "_Mode" + mode; 00222 specpixFile += "_*C_SpecialPixels.????.cub"; 00223 GetMask(specpixFile, temp, g_specpixCube); 00224 } 00225 else 00226 CopyCubeIntoBuffer(specpixFile, g_specpixCube); 00227 } 00228 00229 if (instModeId == "BW") { 00230 if (mode == "1" || mode == "0") 00231 p.SetBrickSize(NO_POLAR_MODE_SAMPLES, VIS_LINES, (int)min(BW_BANDS, g_bands.size())); 00232 else 00233 p.SetBrickSize(POLAR_MODE_SAMPLES, VIS_LINES, (int)min(BW_BANDS, g_bands.size())); 00234 } 00235 else if (instModeId == "COLOR") { 00236 p.SetBrickSize(NO_POLAR_MODE_SAMPLES, VIS_LINES, (int)min(COLOR_BANDS, g_bands.size())); 00237 } 00238 else if (instModeId == "UV") { 00239 p.SetBrickSize(UV_SAMPLES, UV_LINES, (int)min(UV_BANDS, g_bands.size())); 00240 } 00241 00242 g_exposure = inst["ExposureDuration"]; 00243 00244 Cube *ocube = p.SetOutputCube("TO"); 00245 p.StartProcess(Calibrate); 00246 00247 // Add an output group with the appropriate information 00248 PvlGroup calgrp("Radiometry"); 00249 if (g_dark) { 00250 PvlKeyword darks("DarkFiles"); 00251 darks.AddValue(darkFiles[0]); 00252 if (darkFiles.size() > 1) 00253 darks.AddValue(darkFiles[1]); 00254 calgrp += darks; 00255 } 00256 if (g_flatfield) 00257 calgrp += PvlKeyword("FlatFile", flatFile); 00258 if (g_radiometric) { 00259 PvlKeyword vals("ResponsivityValues"); 00260 if (g_iof) { 00261 calgrp += PvlKeyword("RadiometricType", "IOF"); 00262 for (unsigned int i=0; i< g_iofResponsivity.size(); i++) 00263 vals.AddValue(g_iofResponsivity[i]); 00264 } 00265 else { 00266 calgrp += PvlKeyword("RadiometricType", "AbsoluteRadiance"); 00267 for (unsigned int i=0; i< g_radianceResponsivity.size(); i++) 00268 vals.AddValue(g_radianceResponsivity[i]); 00269 } 00270 calgrp += vals; 00271 calgrp += PvlKeyword("SolarDistance", g_solarDistance); 00272 } 00273 if (g_specpix) 00274 calgrp += PvlKeyword("SpecialPixelsFile", specpixFile); 00275 ocube->putGroup(calgrp); 00276 00277 p.EndProcess(); 00278 } 00279 00280 void ResetGlobals () { 00281 g_iofResponsivity.clear(); 00282 g_radianceResponsivity.clear(); 00283 00284 g_dark = true; 00285 g_flatfield = true; 00286 g_radiometric = true; 00287 g_iof = true; 00288 g_specpix = true; 00289 00290 g_bands.clear(); 00291 00292 g_exposure = 1.0; // Exposure duration 00293 g_solarDistance = 1.01; // average distance in [AU] 00294 00295 g_temp1 = 0.0; 00296 g_temp2 = 0.0; 00297 00298 g_numFrames = 0; 00299 00300 delete g_darkCube1; 00301 delete g_darkCube2; 00302 delete g_flatCube; 00303 delete g_specpixCube; 00304 } 00305 00306 // Calibrate each framelet 00307 void Calibrate ( Buffer &inCube, Buffer &outCube ) { 00308 int frameHeight = inCube.LineDimension(); 00309 int frameSize = inCube.SampleDimension()*inCube.LineDimension(); 00310 int frame = inCube.Line() / frameHeight; 00311 00312 for (int i = 0; i < outCube.size(); i++) 00313 outCube[i] = inCube[i]; 00314 00315 if (g_dark) { 00316 for ( int b=0; b<inCube.BandDimension(); b++) { 00317 // We find the index of the corresponding dark frame band as the offset 00318 int offset = g_darkCube1->Index(1, frameHeight * (int) min(frame, g_darkCube1->LineDimension()/frameHeight - 1) + 1, b+1); 00319 00320 for (int i = 0; i < frameSize; i++) { 00321 // Calculate the temperature for the current frame 00322 double temp = (g_endTemperature - g_startTemperature)/g_numFrames * frame + g_startTemperature; 00323 00324 // Interpolate between the two darks with the current temperaturube1 00325 if (IsSpecial(g_darkCube1->at(offset + i)) || IsSpecial(g_darkCube2->at(offset + i)) || IsSpecial(outCube[i + b*frameSize])) 00326 outCube[i + b*frameSize] = Isis::Null; 00327 else { 00328 if (g_temp1 != g_temp2) 00329 outCube[i + b*frameSize] -= (g_darkCube1->at(offset + i) - g_darkCube2->at(offset + i))/(g_temp1-g_temp2) * (temp - g_temp2) + g_darkCube2->at(offset + i); 00330 else 00331 outCube[i+b*frameSize] -= g_darkCube1->at(offset + i); 00332 } 00333 } 00334 } 00335 } 00336 00337 if (g_flatfield) { 00338 for ( int b=0; b<inCube.BandDimension(); b++) { 00339 // We find the index of the corresponding flat frame band as the offset 00340 int offset = g_flatCube->Index(1, frameHeight * (int) min(frame, (g_flatCube->LineDimension()-1) / frameHeight)+1, b+1); 00341 00342 for (int i = 0; i < frameSize; i++) { 00343 if (g_flatCube->at(offset + i) <= 0 || IsSpecial(g_flatCube->at(offset + i)) || IsSpecial(outCube[i + b*frameSize])) 00344 outCube[i+b*frameSize] = Isis::Null; 00345 else 00346 outCube[i+b*frameSize] /= g_flatCube->at(offset + i); 00347 } 00348 } 00349 } 00350 00351 if (g_radiometric) { 00352 for (int i = 0; i < outCube.size(); i++) { 00353 if (IsSpecial(outCube[i])) 00354 outCube[i] = Isis::Null; 00355 else { 00356 outCube[i] /= g_exposure; 00357 if (g_iof) 00358 outCube[i] *= pow(g_solarDistance, 2) / g_iofResponsivity[outCube.Band(i) - 1]; 00359 else 00360 outCube[i] /= g_radianceResponsivity[outCube.Band(i) - 1]; 00361 } 00362 } 00363 } 00364 00365 if (g_specpix) { 00366 for ( int b=0; b<inCube.BandDimension(); b++) { 00367 // We find the index of the corresponding flat frame band as the offset 00368 int offset = g_specpixCube->Index(1, frameHeight * (int) min(frame, (g_specpixCube->LineDimension()-1) / frameHeight)+1, b+1); 00369 00370 for (int i = 0; i < frameSize; i++) { 00371 if (IsSpecial(g_specpixCube->at(offset + i))) 00372 outCube[i+b*frameSize] = g_specpixCube->at(offset + i); 00373 } 00374 } 00375 } 00376 } 00377 00378 void CopyCubeIntoBuffer ( string &fileString, Buffer* &data) { 00379 Cube cube; 00380 Filename filename(fileString); 00381 if ((filename.Expanded()).find("?") != string::npos) 00382 filename.HighestVersion(); 00383 if (!filename.Exists()) { 00384 string msg = fileString + " does not exist."; 00385 throw iException::Message(iException::User, msg, _FILEINFO_); 00386 } 00387 cube.open(filename.Expanded()); 00388 Brick brick(cube.getSampleCount(), cube.getLineCount(), cube.getBandCount(), cube.getPixelType()); 00389 brick.SetBasePosition(1, 1, 1); 00390 cube.read(brick); 00391 00392 data = new Buffer(brick); 00393 00394 fileString = filename.Expanded(); 00395 } 00396 00397 double min ( double a, double b ) { 00398 if (a < b) 00399 return a; 00400 return b; 00401 } 00402 00403 void GetDark(string fileString, double temp, double time, Buffer* &data1, Buffer* &data2, double & temp1, double & temp2, string & file1, string & file2) { 00404 // Find the beginning and end of the "?"s in the versioned filename 00405 Filename filename(fileString); 00406 string absolutePath = filename.Expanded(); 00407 string basename = Filename(filename.Basename()).Basename(); // We do it twice to remove the ".????.cub" 00408 00409 unsigned int tempIndex = basename.find("*C"); 00410 vector<double> temperatures; 00411 00412 unsigned int timeIndex = basename.find("*T"); 00413 vector<int> times; 00414 00415 QDir dir( (QString)(iString)(absolutePath.substr(0, absolutePath.find_last_of("/"))) ); 00416 00417 // Loop through all files in the dir and see if they match our name 00418 for (unsigned int indx=0; indx < dir.count(); indx++) { 00419 string file = Filename( Filename(dir[indx].toStdString()).Basename()).Basename(); // We do it twice to remove ".????.cub 00420 00421 size_t fileTempEndIndex = file.find("C", tempIndex); 00422 size_t fileTimeEndIndex = file.find("T", fileTempEndIndex+1); 00423 size_t fileTimeIndex = file.find_last_not_of("0123456789", fileTimeEndIndex-1) + 1; 00424 if (fileTempEndIndex == string::npos || fileTimeEndIndex == string::npos || fileTimeIndex == string::npos) 00425 continue; 00426 00427 bool matches = file.substr(0, tempIndex) == basename.substr(0,tempIndex); 00428 matches = matches && ( file.substr(fileTempEndIndex, fileTimeIndex-fileTempEndIndex) == basename.substr(tempIndex+1, timeIndex-tempIndex-1) ); 00429 matches = matches && ( file.substr(fileTimeEndIndex) == basename.substr(timeIndex+1) ); 00430 00431 if (matches) { 00432 // Extract all available temperatures 00433 Isis::iString tempStr = file.substr(tempIndex, fileTempEndIndex - tempIndex); 00434 00435 if ((tempStr.length() > 0) && 00436 (tempStr.find_first_not_of("0123456789.-") == string::npos)) { 00437 // Make sure it isn't already included, otherwise add it 00438 bool add = true; 00439 for (unsigned int j=0; j<temperatures.size(); j++) 00440 if (temperatures[j] == tempStr.ToDouble()) 00441 add = false; 00442 if (add) 00443 temperatures.push_back( tempStr.ToDouble()); 00444 } 00445 00446 // Extract all available times 00447 Isis::iString timeStr = file.substr(fileTimeIndex, fileTimeEndIndex - fileTimeIndex); 00448 if ((timeStr.length() > 0) && 00449 (timeStr.find_first_not_of("0123456789.-") == string::npos)) { 00450 // Make sure it isn't already included, otherwise add it 00451 bool add = true; 00452 for (unsigned int j=0; j<times.size(); j++) 00453 if (times[j] == timeStr.ToDouble()) 00454 add = false; 00455 if (add) 00456 times.push_back( timeStr.ToInteger()); 00457 } 00458 } 00459 00460 } 00461 00462 // Now that we have all the available temperatures, we need to find the nearest two temperatures and interpolate (or extrapolate) between them 00463 if (temperatures.size() == 0) { 00464 string msg = "No Dark files exist for these image options [" + basename + "]"; 00465 throw iException::Message(iException::User, msg, _FILEINFO_); 00466 } 00467 else if ( temperatures.size() > 2) { 00468 if (abs(temp - temperatures[0]) < abs(temp - temperatures[1])){ 00469 temp1 = temperatures[0]; 00470 temp2 = temperatures[1]; 00471 } 00472 else { 00473 temp1 = temperatures[1]; 00474 temp2 = temperatures[0]; 00475 } 00476 for (unsigned int i=2; i<temperatures.size(); i++){ 00477 if (abs(temp - temperatures[i]) < abs(temp - temp1)) { 00478 temp2 = temp1; 00479 temp1 = temperatures[i]; 00480 } 00481 else if (abs(temp - temperatures[i]) < abs(temp - temp2)) { 00482 temp2 = temperatures[i]; 00483 } 00484 } 00485 } 00486 else { 00487 temp1=temperatures[0]; 00488 temp2=temp1; 00489 } 00490 00491 tempIndex = fileString.find("*C"); 00492 timeIndex = fileString.find("*T"); 00493 // And then find the latest available time 00494 int bestTime = -1; 00495 for (unsigned int i=0; i<times.size(); i++) { 00496 try { 00497 Filename f1(fileString.substr(0, tempIndex) + iString((int)temp1) + fileString.substr(tempIndex+1, timeIndex-tempIndex-1) + iString(times[i]) + fileString.substr(timeIndex+1)); 00498 Filename f2(fileString.substr(0, tempIndex) + iString((int)temp2) + fileString.substr(tempIndex+1, timeIndex-tempIndex-1) + iString(times[i]) + fileString.substr(timeIndex+1)); 00499 00500 00501 f1.HighestVersion(); 00502 f2.HighestVersion(); 00503 00504 if ( f1.Exists() && f2.Exists() && abs(times[i] - time) < abs(bestTime - time)) 00505 bestTime = times[i]; 00506 } 00507 catch ( Isis::iException e) { 00508 // We ignore exceptions as we expect them every time there is not a file with the given temperature and time 00509 e.Clear(); 00510 } 00511 } 00512 00513 if (bestTime == -1) { 00514 string msg = "No Dark files exist for these image options [" + basename + "]\n no matching times"; 00515 throw iException::Message(iException::User, msg, _FILEINFO_); 00516 } 00517 00518 file1 = fileString.substr(0, tempIndex) + iString((int)temp1) + fileString.substr(tempIndex+1, timeIndex-tempIndex-1) + iString(bestTime) + fileString.substr(timeIndex+1); 00519 file2 = fileString.substr(0, tempIndex) + iString((int)temp2) + fileString.substr(tempIndex+1, timeIndex-tempIndex-1) + iString(bestTime) + fileString.substr(timeIndex+1); 00520 00521 CopyCubeIntoBuffer ( file1, data1 ); 00522 CopyCubeIntoBuffer ( file2, data2 ); 00523 } 00524 00525 void GetMask(string &fileString, double temp, Buffer* &data) { 00526 // Find the beginning and end of the "?"s in the versioned filename 00527 Filename filename(fileString); 00528 string absolutePath = filename.Expanded(); 00529 string basename = Filename(filename.Basename()).Basename(); // We do it twice to remove the ".????.cub" 00530 00531 unsigned int index = basename.find_first_of("*"); 00532 unsigned int charsAfterVersion = basename.length() - index - 1; 00533 00534 vector<double> temperatures; 00535 00536 QDir dir( (QString)(iString)(absolutePath.substr(0, absolutePath.find_last_of("/"))) ); 00537 00538 // Loop through all files in the dir and see if they match our name 00539 for (unsigned int indx=0; indx < dir.count(); indx++) { 00540 00541 string file = Filename( Filename(dir[indx].toStdString()).Basename()).Basename(); // We do it twice to remove ".????.cub" 00542 bool leftSide = file.substr(0, index) == basename.substr(0, index); 00543 bool rightSide = ((int)file.length()-(int)charsAfterVersion) >= 0; 00544 if (rightSide) { 00545 rightSide = rightSide && 00546 (file.substr(file.length()-charsAfterVersion) == basename.substr(index+1)); 00547 } 00548 00549 if (leftSide && rightSide) { 00550 00551 Isis::iString version = file.substr(index, file.length()-charsAfterVersion-index); 00552 00553 if ((version.length() > 0) && 00554 (version.find_first_not_of("0123456789.-") == string::npos)) { 00555 // Make sure it isn't already included, otherwise add it 00556 bool add = true; 00557 for (unsigned int j=0; j<temperatures.size(); j++) 00558 if (temperatures[j] == version.ToDouble()) 00559 add = false; 00560 if (add) 00561 temperatures.push_back( version.ToDouble()); 00562 } 00563 } 00564 } 00565 00566 // Now that we have all the available temperatures, we need to find the nearest temperature 00567 if (temperatures.size() == 0) { 00568 string msg = "No Dark files exist for these image options [" + basename + "]"; 00569 throw iException::Message(iException::User, msg, _FILEINFO_); 00570 } 00571 00572 double bestTemp = temperatures[0]; 00573 for (unsigned int i=1; i< temperatures.size(); i++) { 00574 if (abs(temp - temperatures[i]) < abs(temp - bestTemp)) 00575 bestTemp = temperatures[i]; 00576 } 00577 index = fileString.find_first_of("*"); 00578 00579 string file = fileString.substr(0, index) + iString((int)bestTemp) + fileString.substr(index+1); 00580 CopyCubeIntoBuffer ( file, data ); 00581 fileString = file; 00582 } 00583