/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2016 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include namespace { const std::string _loggerCat = "HongKangParser"; const std::string keyTranslation = "DataInputTranslation"; const std::string PlaybookIdentifierName = "HongKang"; } namespace openspace { HongKangParser::HongKangParser(std::string name, const std::string& fileName, std::string spacecraft, ghoul::Dictionary translationDictionary, std::vector potentialTargets) : _name(std::move(name)) , _defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder.png")) { _fileName = fileName; _spacecraft = spacecraft; _potentialTargets = potentialTargets; //get the different instrument types const std::vector& decoders = translationDictionary.keys(); //for each decoder (assuming might have more if hong makes changes) for (int i = 0; i < decoders.size(); i++){ //create dictionary containing all {playbookKeys , spice IDs} if (decoders[i] == "Instrument"){ ghoul::Dictionary typeDictionary; translationDictionary.getValue(decoders[i], typeDictionary); //for each playbook call -> create a Decoder object const std::vector& keys = typeDictionary.keys(); //std::string abort = decoders[i] + "." + keyStopCommand; for (int j = 0; j < keys.size(); j++){ std::string currentKey = decoders[i] + "." + keys[j]; ghoul::Dictionary decoderDictionary; translationDictionary.getValue(currentKey, decoderDictionary); Decoder *decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); //insert decoder to map - this will be used in the parser to determine //behavioral characteristics of each instrument _fileTranslation[keys[j]] = decoder; } } //Hong's playbook needs _only_ instrument translation though. } } void HongKangParser::findPlaybookSpecifiedTarget(std::string line, std::string& target){ //remembto add this lua later... std::vector ptarg = _potentialTargets; for (auto p : ptarg){ // loop over all targets and determine from 4th col which target this instrument points to std::transform(line.begin(), line.end(), line.begin(), toupper); if (line.find(p) != std::string::npos){ target = p; break; } else{ // not found - we set void until we have more info. target = "VOID"; } } } void HongKangParser::writeUTCEventFile(const Image image){ std::string time_beg = SpiceManager::ref().dateFromEphemerisTime(image.startTime); std::string time_end = SpiceManager::ref().dateFromEphemerisTime(image.stopTime); _eventsAsUTCFile << std::fixed << std::setw(10) << time_beg << "->" << std::setw(10) << time_end << std::setw(10) << (int)getMetFromET(image.startTime) << "->" << std::setw(10) << (int)getMetFromET(image.stopTime) << std::setw(10) << image.target << std::setw(10); for (auto instrument : image.activeInstruments){ _eventsAsUTCFile << " " << instrument; } } bool HongKangParser::create(){ //check input for errors. int tmp; bool hasObserver = SpiceManager::ref().hasNaifId(_spacecraft); tmp = SpiceManager::ref().naifId(_spacecraft); if (!hasObserver){ LERROR("SPICE navigation system has no pooled observer: '" << _spacecraft << "' in kernel" << "Please check that all necessary kernels are loaded"<< "along with correct modfile definition."); return hasObserver; } if (_potentialTargets.size() == 0){ LERROR("In order to find targeting from event file user has to provide list of potential targets " << "please check modfile"); } _eventsAsUTCFile.open("utcEvents.txt"); if (size_t position = _fileName.find_last_of(".") + 1){ if (position != std::string::npos){ std::string extension = ghoul::filesystem::File(_fileName).fileExtension(); if (extension == "txt") {// Hong Kang. pre-parsed playbook LINFO("Using Preparsed Playbook V9H"); std::ifstream file(_fileName , std::ios::binary); if (!file.good()){ LERROR("Failed to open event file '" << _fileName << "'"); return false; } std::string line = ""; double shutter = 0.01; std::string previousTarget; std::string previousCamera; std::string previousScanner; TimeRange cameraRange; TimeRange scanRange; std::vector scannerSpiceID; std::vector cameraSpiceID; double capture_start = -1; double capture_stop = -1; double scan_start = -1; double scan_stop = -1; std::string cameraTarget = "VOID"; std::string scannerTarget = "VOID"; while (!file.eof()){ std::getline(file, line); std::string event = line.substr(0, line.find_first_of(" ")); auto it = _fileTranslation.find(event); bool foundEvent = (it != _fileTranslation.end()); std::string met = line.substr(25, 9); double time = getETfromMet(met); Image image; if (foundEvent){ //store the time, this is used for getNextCaptureTime() _captureProgression.push_back(time); if (it->second->getDecoderType() == "CAMERA"){ if (capture_start == -1){ //encountered new camera sequence- store start time capture_start = time; previousCamera = it->first; } //always store individual image for camera cameraSpiceID = it->second->getTranslation(); //rely on playboook mdl column to determine target findPlaybookSpecifiedTarget(line, cameraTarget); //fill image createImage(image, time, time + shutter, cameraSpiceID, cameraTarget, _defaultCaptureImage); writeUTCEventFile(image); //IFF spaccraft has decided to switch target, store in target map (used for: 'next observation focus') if (previousTarget != image.target){ previousTarget = image.target; std::pair v_target = std::make_pair(time, image.target); _targetTimes.push_back(v_target); } //store actual image in map. All targets get _only_ their corresp. subset. _subsetMap[image.target]._subset.push_back(image); //compute and store the range for each subset _subsetMap[image.target]._range.setRange(time); } if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START scan_start = time; InstrumentDecoder* scanner = static_cast(it->second); std::string endNominal = scanner->getStopCommand(); // store current position in file std::streampos len = file.tellg(); std::string linePeek; bool foundstop = false; while (!file.eof() && !foundstop){ //continue grabbing next line until we find what we need getline(file, linePeek); if (linePeek.find(endNominal) != std::string::npos){ foundstop = true; met = linePeek.substr(25, 9); scan_stop = getETfromMet(met); findPlaybookSpecifiedTarget(line, scannerTarget); scannerSpiceID = it->second->getTranslation(); scanRange._min = scan_start; scanRange._max = scan_stop; _instrumentTimes.push_back(std::make_pair(it->first, scanRange)); //store individual image createImage(image, scan_start, scan_stop, scannerSpiceID, scannerTarget, _defaultCaptureImage); writeUTCEventFile(image); _subsetMap[image.target]._subset.push_back(image); _subsetMap[image.target]._range.setRange(scan_start); } } //go back to stored position in file file.seekg(len, std::ios_base::beg); } } else{ // we have reached the end of a scan or consecutive capture sequence! if (capture_start != -1){ //end of capture sequence for camera, store end time of this sequence capture_stop = time; cameraRange._min = capture_start; cameraRange._max = capture_stop; _instrumentTimes.push_back(std::make_pair(previousCamera, cameraRange)); capture_start = -1; } } _eventsAsUTCFile << std::endl; } } } } sendPlaybookInformation(PlaybookIdentifierName); return true; } bool HongKangParser::augmentWithSpice(Image& image, std::string spacecraft, std::vector payload, std::vector potentialTargets){ image.target = "VOID"; // we have (?) to cast to int, unfortunately // Why? --abock // because: old comment --m int exposureTime = image.stopTime - image.startTime; if (exposureTime == 0) exposureTime = 1; for (int i = 0; i < potentialTargets.size(); i++){ bool success = false; bool _withinFOV = false; for (int j = 0; j < image.activeInstruments.size(); j++){ double time = image.startTime; for (int k = 0; k < exposureTime; k++){ time += k; _withinFOV = SpiceManager::ref().isTargetInFieldOfView( potentialTargets[i], spacecraft, image.activeInstruments[j], SpiceManager::FieldOfViewMethod::Ellipsoid, {}, time ); if (_withinFOV){ image.target = potentialTargets[i]; _withinFOV = false; } } } } return false; } void HongKangParser::createImage(Image& image, double startTime, double stopTime, std::vector instr, std::string targ, std::string path) { image.startTime = startTime; image.stopTime = stopTime; image.path = path; for (int i = 0; i < instr.size(); i++){ image.activeInstruments.push_back(instr[i]); } image.target = targ; image.projected = false; } double HongKangParser::getETfromMet(std::string line){ std::string::size_type sz; return getETfromMet(std::stod(line, &sz)); } double HongKangParser::getETfromMet(double met){ double diff; double referenceET = SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00"); double et = referenceET; //_metRef += 3; // MET reference time is off by 3 sec? diff = std::abs(met - _metRef); if (met > _metRef){ et = referenceET + diff; } else if (met < _metRef){ et = referenceET - diff; } return et; } double HongKangParser::getMetFromET(double et){ double met; double referenceET = SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00"); if (et >= referenceET){ met = _metRef + (et - referenceET); }else{ met = _metRef - (referenceET - et); } return met; } }