#include #include #include #include #include #include "Header_Files/oceanOpticsFiberImager.h" #include "Header_Files/atpFiberImager.h" #include "Header_Files/calibration.h" enum CommandLineParseResult { CommandLineOk, CommandLineError, CommandLineVersionRequested, CommandLineHelpRequested }; enum DeviceType { OPTOSKY, OceanOptics, UnknownDevice }; struct TcQuery { DeviceType deviceType; QString serialPort; int sleepTimeinSecond;//有默认值 int averageTimes; int position; int integratingSphereDetectorValue; QString calFileOutputDirectory;//有默认值 QString calFileOutputName; QString standardLightFilePath; bool justRecord; }; CommandLineParseResult parseCommandLine2(QCommandLineParser &parser, TcQuery *query, QString *errorMessage); bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist); void logout(QString str); void createDirectory(QString fullPath); bool isFileExist(QString fullFileName); int getNonlinearityCoeffs2(long deviceID, double * nonlinearityCoeffs); int getNonlinearityCoeffs1(double * nonlinearityCoeffs); int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QCoreApplication::setApplicationName("Ocean optics radiance calibration software"); QCoreApplication::setApplicationVersion("1.0"); // 解析命令行参数 QCommandLineParser parser; parser.setApplicationDescription("This software is used for doing radiance calibration for ocean optics fiber imager."); TcQuery query; QString errorMessage; switch (parseCommandLine2(parser, &query, &errorMessage)) { case CommandLineOk: break; case CommandLineError: errorMessage = "
" + errorMessage + "s!"; logout(errorMessage); // fputs(qPrintable(errorMessage), stderr); fputs("\n\n", stderr); fputs(qPrintable(parser.helpText()), stderr); return 1; case CommandLineVersionRequested: printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion())); return 0; case CommandLineHelpRequested: parser.showHelp(); Q_UNREACHABLE(); } //创建光谱仪对象 FiberSpectrometerOperationBase * m_FiberSpectrometer; bool isOcean = false; double * nonlinearityCoeffs; int numberOfNonlinearityCoeffs; switch (query.deviceType) { case OPTOSKY: m_FiberSpectrometer = new ATPFiberImager(false,query.serialPort.toStdString(),"OPTOSKY"); break; case OceanOptics: { //使用sbapi读取海洋光学仪器的非线性定标参数 nonlinearityCoeffs = new double[100]; numberOfNonlinearityCoeffs = getNonlinearityCoeffs1(nonlinearityCoeffs); m_FiberSpectrometer = new OceanOpticsFiberImager(nonlinearityCoeffs, numberOfNonlinearityCoeffs); isOcean = true; break; } case UnknownDevice: parser.showHelp(); Q_UNREACHABLE(); } //连接光谱仪 QString message; QString SN; QString pixelCount; QString wavelengthInfo; logout("
Connectting the fiber spectrometer!"); m_FiberSpectrometer->connectFiberSpectrometer(SN, pixelCount, wavelengthInfo); //自动曝光 logout("
AutoExpose!"); m_FiberSpectrometer->autoExpose();// int iExposureTime; m_FiberSpectrometer->getExposureTime(iExposureTime); message="
ExposureTime: " + QString::number(iExposureTime) + ""; logout(message); //程序sleep:等待关闭快门 message="
Please close the lamp in " + QString::number(query.sleepTimeinSecond) + "s!"; logout(message); QThread::sleep(query.sleepTimeinSecond); //采集暗帧 logout("
Record dark frame!"); m_FiberSpectrometer->recordDark(query.calFileOutputDirectory); //程序sleep:等待打开快门 message="
Please open the lamp in " + QString::number(query.sleepTimeinSecond) + "s!"; logout(message); QThread::sleep(query.sleepTimeinSecond); //采集积分球光谱 logout("
Record integrating sphere frame!"); m_FiberSpectrometer->recordTarget(query.averageTimes, query.calFileOutputDirectory); //准备定标文件数据 logout("
readAndResample_StandardLightFile!"); DeviceAttribute deviceAttribute; DeviceInfo deviceInfo; m_FiberSpectrometer->getDeviceAttribute(deviceAttribute); m_FiberSpectrometer->getDeviceInfo(deviceInfo); CalibrationAlgorithm * m_CalibrationAlgorithm = new CalibrationAlgorithm(); m_CalibrationAlgorithm->readAndResample_StandardLightFile(query.standardLightFilePath,query.integratingSphereDetectorValue, deviceAttribute, deviceInfo); //生成辐射定标文件 if (query.calFileOutputName.isEmpty())//query->calFileOutputName=="" { QDateTime curDateTime = QDateTime::currentDateTime(); QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); QString calFileName = QDir::cleanPath(query.calFileOutputDirectory + QDir::separator() + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + ".dat"); query.calFileOutputName=calFileName; } logout("
Produce calibration file!"); m_CalibrationAlgorithm->produceCalfile(query.calFileOutputName, deviceAttribute, m_FiberSpectrometer->m_IntegratingSphereData, m_FiberSpectrometer->m_DarkData); //复制辐射定标文件 QDateTime curDateTime = QDateTime::currentDateTime(); QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); QString destName = QDir::cleanPath(query.calFileOutputDirectory + QDir::separator() + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_" +QString::number(query.position) + ".cal"); copyFileToPath(query.calFileOutputName,destName,true); //将海洋光学仪器的非线性定标参数写到文件中 if (isOcean) { QDateTime curDateTime = QDateTime::currentDateTime(); QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); QString nonlinearityCoeffsName = QDir::cleanPath(query.calFileOutputDirectory + QDir::separator() + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + ".nonLinear"); // for (int i = 0; i < numberOfNonlinearityCoeffs; ++i) // { // printf("\n"); // // printf("nonlinearityCoeffs(第%d个): %1.2e\n",i , nonlinearityCoeffs[i]); // // printf("\n"); // } std::ofstream outfile(nonlinearityCoeffsName.toStdString().c_str()); for (int i = 0; i < numberOfNonlinearityCoeffs; i++) { outfile << nonlinearityCoeffs[i] << std::endl; } outfile.close(); free(nonlinearityCoeffs); } //断开光谱仪 m_FiberSpectrometer->disconnectFiberSpectrometer();//要放在这句代码之后:free(nonlinearityCoeffs); //return a.exec(); } CommandLineParseResult parseCommandLine2(QCommandLineParser &parser, TcQuery *query, QString *errorMessage) { parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); QCommandLineOption deviceType("deviceType", "Device type. Options are OPTOSKY and OceanOptics", "deviceType"); parser.addOption(deviceType); QCommandLineOption serialPort("serialPort", "Serial port.", "serialPort"); parser.addOption(serialPort); QCommandLineOption sleepTimeinSecond("t", "The time app sleep.", "sleepTimeinSecond"); sleepTimeinSecond.setDefaultValue("30");//设置默认参数 parser.addOption(sleepTimeinSecond); QCommandLineOption averageTimes("a", "Average times.", "average_times"); averageTimes.setDefaultValue("5");//设置默认参数 parser.addOption(averageTimes);// QCommandLineOption position("position", "Position.", "position"); parser.addOption(position); QCommandLineOption integratingSphereDetectorValue("integratingSphereDetectorValue", "integratingSphereDetectorValue.", "integratingSphereDetectorValue"); parser.addOption(integratingSphereDetectorValue); // parser.addPositionalArgument("name", "The name to look up.");//???????????????????????????????????????????????????????????????????????????? QCommandLineOption helpOption = parser.addHelpOption();//Adds the help option (-h, --help and -? on Windows) This option is handled automatically by QCommandLineParser. QCommandLineOption versionOption = parser.addVersionOption();//This option is handled automatically by QCommandLineParser. //// A boolean option with a single name (-p) //QCommandLineOption showProgressOption("p", QCoreApplication::translate("main", "Show progress during copy")); //parser.addOption(showProgressOption); // A boolean option with multiple names (-r, --record) QCommandLineOption recordOption(QStringList() << "f" << "record", QCoreApplication::translate("main", "Just record one spectral.")); parser.addOption(recordOption); //标准灯文件 QCommandLineOption standardLightFilePath(QStringList() << "slfp" << "standard-light-file-path", QCoreApplication::translate("main", "set standard light file."), QCoreApplication::translate("main", "file")); parser.addOption(standardLightFilePath); QCommandLineOption standardLightFileSelector(QStringList() << "slfs" << "standard-light-file-selector", QCoreApplication::translate("main", "select standard light file."), QCoreApplication::translate("main", "file")); parser.addOption(standardLightFileSelector); //定标文件输出路径 // An option with a value QCommandLineOption calFileOutputDirectory(QStringList() << "cfod" << "calibration-file-output-directory", QCoreApplication::translate("main", "Save cal file into ."), QCoreApplication::translate("main", "directory")); // QString tmpPath1 = QDir::cleanPath(QDir::rootPath() + QDir::separator()+"calFile"); QString tmpPath1 = "/home/data/Cal/"; calFileOutputDirectory.setDefaultValue(tmpPath1);//设置默认参数,QCoreApplication::applicationDirPath(),standardLightFile parser.addOption(calFileOutputDirectory); //定标文件输出文件名 // An option with a value QCommandLineOption calFileOutputName(QStringList() << "cfon" << "calibration-file-output-name", QCoreApplication::translate("main", "Cal file name."), QCoreApplication::translate("main", "fileName")); parser.addOption(calFileOutputName); if (!parser.parse(QCoreApplication::arguments()))//Process the actual command line arguments given by the user { *errorMessage = parser.errorText(); return CommandLineError; } if (parser.isSet(versionOption)) return CommandLineVersionRequested; if (parser.isSet(helpOption)) return CommandLineHelpRequested; if (parser.isSet(deviceType)) { const QString deviceTypeTmp = parser.value(deviceType); if (deviceTypeTmp=="OPTOSKY") { query->deviceType = OPTOSKY; } else if(deviceTypeTmp=="OceanOptics") { query->deviceType = OceanOptics; } else { *errorMessage = "DeviceType set error."; return CommandLineError; } } else//默认参数 { *errorMessage = "No deviceType set."; return CommandLineError; } if (parser.isSet(serialPort)) { const QString serialPortTmp = parser.value(serialPort); query->serialPort = serialPortTmp; } else//默认参数 { if (query->deviceType == OceanOptics) { ; } else if (query->deviceType == OPTOSKY) { *errorMessage = "No serialPort set."; return CommandLineError; } } if (parser.isSet(sleepTimeinSecond)) { const QString timeTmp = parser.value(sleepTimeinSecond); query->sleepTimeinSecond = timeTmp.toInt(); } else//默认参数 { QStringList tmp = sleepTimeinSecond.defaultValues(); query->sleepTimeinSecond = tmp[0].toInt(); } if (parser.isSet(averageTimes)) { const QString averageTimesTmp = parser.value(averageTimes); string tttt=averageTimesTmp.toStdString(); query->averageTimes = averageTimesTmp.toInt(); } else//默认参数 { QStringList tmp = averageTimes.defaultValues(); query->averageTimes = tmp[0].toInt(); } if (parser.isSet(position)) { const QString positionTmp = parser.value(position); query->position = positionTmp.toInt(); } else { *errorMessage = "No position set."; return CommandLineError; } query->justRecord = parser.isSet(recordOption); if (!parser.isSet(standardLightFilePath) && !parser.isSet(standardLightFileSelector))//没有设置定标保存文件路径 { *errorMessage = "No standard light file set."; return CommandLineError; } if (parser.isSet(standardLightFileSelector))// { QString selector = parser.value(standardLightFileSelector); // QString standardLightFilePath_tmp = QDir::cleanPath(QDir::rootPath() + QDir::separator() + "standardLightFile" + QDir::separator() + selector); QString tmp = "/home/data/Setting/StandardLightFile"; QString standardLightFilePath_tmp = tmp + QDir::separator() + selector; string xx=standardLightFilePath_tmp.toStdString(); //判断定标文件是否存在 if (!isFileExist(standardLightFilePath_tmp)) { *errorMessage = "Standard light file '" + selector + "' does not exist!"; return CommandLineError; } query->standardLightFilePath = standardLightFilePath_tmp; } if (parser.isSet(standardLightFilePath))// { query->standardLightFilePath = parser.value(standardLightFilePath); } if (parser.isSet(integratingSphereDetectorValue)) { if(query->standardLightFilePath.contains("ocean_optics.lmp",Qt::CaseSensitive)) { query->integratingSphereDetectorValue = -1; } else { const QString integratingSphereDetectorValueTmp = parser.value(integratingSphereDetectorValue); query->integratingSphereDetectorValue = integratingSphereDetectorValueTmp.toInt(); } } else { *errorMessage = "No integratingSphereDetectorValue set."; return CommandLineError; } if (parser.isSet(calFileOutputDirectory))//定标保存文件路径 { query->calFileOutputDirectory = parser.value(calFileOutputDirectory); createDirectory(query->calFileOutputDirectory);//如果文件夹不存在 则创建 } else//默认参数 { QStringList tmp = calFileOutputDirectory.defaultValues(); QString directory = tmp[0]; createDirectory(directory);//如果文件夹不存在 则创建 query->calFileOutputDirectory = directory; } if (parser.isSet(calFileOutputName))//------- { QString calFileOutputNameTmp = QDir::cleanPath(query->calFileOutputDirectory + QDir::separator() + parser.value(calFileOutputName)); query->calFileOutputName = calFileOutputNameTmp; } else//默认参数 { query->calFileOutputName = "";//使用此参数时,如果query->calFileOutputName为空 → 会给此变量赋值 } // const QStringList positionalArguments = parser.positionalArguments(); // if (positionalArguments.isEmpty()) // { // *errorMessage = "Argument 'name' missing."; // return CommandLineError; // } // if (positionalArguments.size() > 1) // { // *errorMessage = "Several 'name' arguments specified."; // return CommandLineError; // } return CommandLineOk; } bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist) { toDir.replace("\\","/"); if (sourceDir == toDir){ return true; } if (!QFile::exists(sourceDir)){ return false; } QDir *createfile = new QDir; bool exist = createfile->exists(toDir); if (exist){ if(coverFileIfExist){ createfile->remove(toDir); } }//end if if(!QFile::copy(sourceDir, toDir)) { return false; } return true; } void logout(QString str) { std::cout << str.toStdString() << "
"; std::fflush(stdout); } void createDirectory(QString fullPath)// { QDir dir(fullPath); if (dir.exists()) { return; } else { bool ok = dir.mkdir(fullPath);//只创建一级子目录,即必须保证上级目录存在 return; } } bool isFileExist(QString fullFileName) { QFileInfo fileInfo(fullFileName); if (fileInfo.isFile()) { return true; } return false; } int getNonlinearityCoeffs1(double * nonlinearityCoeffs) { int number_of_devices; long *device_ids; int i; int test_index; int flag; int error = 0; char nameBuffer[80]; /* Give the driver a chance to initialize itself */ sbapi_initialize(); // printf("Probing for devices...\n"); fflush(stdout); sbapi_probe_devices(); //#define RS232_TEST #ifdef RS232_TEST printf("Adding an STS at 9600 baud...\n"); /* Uncomment for Linux */ //sbapi_add_RS232_device_location("STS", "/dev/ttyS0", 9600); //sbapi_add_RS232_device_location("STS", "/dev/ttyUSB0", 9600); /* Uncomment for Windows */ //sbapi_add_RS232_device_location("STS", "COM1", 9600); /* Uncomment for e.g. USB-RS232 adapter under OSX */ //sbapi_add_RS232_device_location("STS", "/dev/tty.KeySerial1", 9600); //sbapi_add_RS232_device_location("STS", "/dev/tty.usbserial", 9600); #endif /* This shows how to add network devices (note that most use TCP/IP) */ //sbapi_add_TCPIPv4_device_location("Jaz", "192.168.1.150", 7654); //sbapi_add_TCPIPv4_device_location("Blaze", "192.168.1.151", 57357); // printf("Getting device count...\n"); fflush(stdout); number_of_devices = sbapi_get_number_of_device_ids(); // printf("Device count is %d\n", number_of_devices); if(0 == number_of_devices) { return 0; } // printf("Getting device IDs...\n"); device_ids = (long *)calloc(number_of_devices, sizeof(long)); number_of_devices = sbapi_get_device_ids(device_ids, number_of_devices); // printf("Got %d device ID%s.\n", number_of_devices, number_of_devices == 1 ? "" : "s"); int number; for(i = 0; i < number_of_devices; i++) { // printf("%d: Device 0x%02lX:\n", i, device_ids[i]); // printf("\tGetting device type...\n"); flag = sbapi_get_device_type(device_ids[i], &error, nameBuffer, 79); // printf("\t\tResult is (%d) [%s]\n", flag, sbapi_get_error_string(error)); if(flag > 0) { // printf("\tDevice type: [%s]\n", nameBuffer); } /* Open the device */ // printf("\tAttempting to open:\n"); flag = sbapi_open_device(device_ids[i], &error); // printf("\t\tResult is (%d) [%s]\n", flag, sbapi_get_error_string(error)); // jump to the next iteration if there was a problem if(flag != 0) { continue; } number = getNonlinearityCoeffs2(device_ids[i],nonlinearityCoeffs); /* Close the device */ // printf("\tAttempting to close:\n"); sbapi_close_device(device_ids[i], &error); // printf("\t\tResult is (%d) [%s]\n", flag, sbapi_get_error_string(error)); } free(device_ids); // printf("Finished testing.\n"); /* Clean up memory allocated by the driver */ sbapi_shutdown(); return number; }// //返回值是非线性校正系数的个数 int getNonlinearityCoeffs2(long deviceID, double * nonlinearityCoeffs) { int error = 0; int number_of_nonlinearity_coeff_features; long *nonlinearity_coeff_feature_ids = 0; double buffer[10]; int i; int length = 0; // printf("\n\tTesting nonlinearity coefficient features:\n"); // printf("\t\tGetting number of nonlinearity coefficient features:\n"); number_of_nonlinearity_coeff_features = sbapi_get_number_of_nonlinearity_coeffs_features(deviceID, &error); // printf("\t\t\tResult is %d [%s]\n", number_of_nonlinearity_coeff_features, // sbapi_get_error_string(error)); if(0 == number_of_nonlinearity_coeff_features) { printf("\tNo nonlinearity coefficient capabilities found.\n"); return 0; } nonlinearity_coeff_feature_ids = (long *)calloc(number_of_nonlinearity_coeff_features, sizeof(long)); // printf("\t\tGetting nonlinearity coefficient feature IDs...\n"); number_of_nonlinearity_coeff_features = sbapi_get_nonlinearity_coeffs_features( deviceID, &error, nonlinearity_coeff_feature_ids, number_of_nonlinearity_coeff_features); // printf("\t\t\tResult is %d [%s]\n", number_of_nonlinearity_coeff_features, // sbapi_get_error_string(error)); for(i = 0; i < number_of_nonlinearity_coeff_features; i++) { // printf("\t\t%d: Testing device 0x%02lX, nonlinearity coeffs 0x%02lX\n", // i, deviceID, nonlinearity_coeff_feature_ids[i]); // printf("\t\t\tAttempting to get nonlinearity coefficients...\n"); memset(nonlinearityCoeffs, (int)0, 20);//---------------------------------------------------------------------------- length = sbapi_nonlinearity_coeffs_get(deviceID, nonlinearity_coeff_feature_ids[i], &error, nonlinearityCoeffs, 20); // printf("\t\t\t\tResult is %d [%s]\n", length, sbapi_get_error_string(error)); if(0 == error && length > 0) { // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[0]); // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[1]); // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[2]); // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[3]); // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[4]); // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[5]); // printf("\t\t\t\tFirst calibration term: %1.2e\n", nonlinearityCoeffs[6]); } // printf("\t\t%d: Finished testing device 0x%02lX, nonlinearity coeffs 0x%02lX\n", // i, deviceID, nonlinearity_coeff_feature_ids[i]); } free(nonlinearity_coeff_feature_ids); // printf("\tFinished testing nonlinearity coefficient capabilities.\n"); return length; }