SpiceKernelMgr.cc 5.65 KB
/**
 * SpiceKernelMgr.cc
 *
 *  Created on: 08 jul. 2016
 *      Author: AKKA IS
 */

#include "SpiceKernelMgr.hh"
#include "SpiceKernelConfigParser.hh"
#include "Helper.hh"
#include "Properties.hh"
#include "SpiceKernelStatus.hh"
#include "TimeUtil.hh"

#include "SpiceUsr.h"

namespace AMDA {
namespace SpiceKernel {

SpiceKernelMgr::SpiceKernelMgr() : ::Singleton<SpiceKernelMgr>(), _genericDataFilesLoaded(false) {
	SpiceKernelStatus::CheckErrors();
	loadConfig();
}

SpiceKernelMgr::~SpiceKernelMgr() {

}

int SpiceKernelMgr::getBodyCenterFromFrameName(const char *frameName) {
	if (_bodyCenterFromFrameNameMap.find(frameName) != _bodyCenterFromFrameNameMap.end())
		return _bodyCenterFromFrameNameMap[frameName];

	SpiceInt frcode = SpiceKernelMgr::getInstance()->getFrameIdFromFrameName(frameName);

	if (frcode == -1)
		return -1;

	SpiceInt     cent;
	SpiceInt     frclss;
	SpiceInt     clssid;
	SpiceBoolean found;

	frinfo_c (frcode, &cent, &frclss, &clssid, &found);

	//THE SPICE convention uses negative integers as spacecraft ID codes.
	if (SpiceKernelStatus::CheckErrors() || (cent < 0))
		return -1;

	_bodyCenterFromFrameNameMap[frameName] = cent;

	return cent;
}

int SpiceKernelMgr::getFrameIdFromFrameName(const char *frameName) {
	if (_frameIdFromFrameNameMap.find(frameName) != _frameIdFromFrameNameMap.end())
		return _frameIdFromFrameNameMap[frameName];

	SpiceInt frcode;

	namfrm_c (frameName, &frcode);

	//If the name input through frname is not recognized,
    //frcode will be returned with a value of zero.
	if (SpiceKernelStatus::CheckErrors() || (frcode == 0))
		return -1;

	_frameIdFromFrameNameMap[frameName] = frcode;

	return frcode;
}

bool SpiceKernelMgr::loadDataFilesForFrameName(const char* frameName) {
	if (std::find(_DataFilesLoadedForFrameName.begin(), _DataFilesLoadedForFrameName.end(), frameName) != _DataFilesLoadedForFrameName.end())
		return true;

	if (!loadGenericDataFiles())
		return false;

	int bodyCenter = SpiceKernelMgr::getInstance()->getBodyCenterFromFrameName(frameName);
	if (bodyCenter == -1)
		return false;

	std::list<std::string> dataFilesForCrtBody = _config->getDataFilesForBodyId(bodyCenter);
	bool loaded = loadListOfDataFiles(dataFilesForCrtBody);

	if (loaded)
		_DataFilesLoadedForFrameName.push_back(frameName);
	return loaded;
}

bool SpiceKernelMgr::loadGenericDataFiles() {
	if (_genericDataFilesLoaded)
		return true;
	std::list<std::string> dataFilesForAllBodies = _config->getDataFilesForBodyId(-1);
	_genericDataFilesLoaded =  loadListOfDataFiles(dataFilesForAllBodies);
	return _genericDataFilesLoaded;
}

bool SpiceKernelMgr::isDataFileLoaded(const char* filePath) {
	return (std::find(_loadedDataFiles.begin(), _loadedDataFiles.end(), filePath) != _loadedDataFiles.end());
}

bool SpiceKernelMgr::loadListOfDataFiles(std::list<std::string> dataFilesList) {
	for (std::list<std::string>::iterator it = dataFilesList.begin(); it != dataFilesList.end(); ++it) {
		std::string path = *it;
		if (isDataFileLoaded(path.c_str()))
			continue;
		std::string fullPath = _config->getFullPath(path.c_str());

		furnsh_c (fullPath.c_str());

		if (SpiceKernelStatus::CheckErrors())
			return false;

		LOG4CXX_INFO(gLogger, "SpiceKernelMgr::loadDataFilesForFrameName - " << fullPath);

		_loadedDataFiles.push_back(path);
	}

	return true;
}

void SpiceKernelMgr::loadConfig() {
	AMDA::helpers::Properties lProperties("app.properties");

	// Retrieve XSD file for DataSet and build a parser
	SpiceKernelConfigParser parser(lProperties["app.spicekernel.configxsd"].c_str());

	// Parse XML file
	std::string configFile = lProperties["app.spicekernel.configfile"];
	_config = parser.parse (configFile);
}

double SpiceKernelMgr::timeStampToEt(double timeStamp) {
	if (!loadGenericDataFiles())
		return 0;

	std::string isoTime = TimeUtil::formatTimeDateInIso(timeStamp);

	double et = 0;
	str2et_c ( isoTime.c_str(), &et);

	if (SpiceKernelStatus::CheckErrors())
		return 0.;

	return et;
}

double SpiceKernelMgr::timeStampToJulianDate(double timeStamp) {
	if (!loadGenericDataFiles())
		return 0;

	double et = timeStampToEt(timeStamp);
	SpiceInt           lenout = 35;
	//ConstSpiceChar * format = "J";
	//SpiceInt prec  =  6;
	SpiceChar      utcstr[lenout+1];
	memset(utcstr,0,sizeof(SpiceChar)*(lenout+1));

	et2utc_c ( et, "J", 7, lenout, utcstr );
	if (SpiceKernelStatus::CheckErrors())
		return 0.;

	double jd;
	sscanf(utcstr, "JD %32lf", &jd);

	return jd;
}


bool SpiceKernelMgr::getRotationMatrix(const char* fromFrame, const char* toFrame, double et, double rotate[3][3]) {
	pxform_c (fromFrame, toFrame, et, rotate) ;

	if (SpiceKernelStatus::CheckErrors())
		return false;

	return true;
}

bool SpiceKernelMgr::getTranslation(const char* fromFrame, const char* toFrame, bool isPosition, double et, double translation[3]) {
	translation[0] = 0;
	translation[1] = 0;
	translation[2] = 0;

	if (isPosition) {
		int fromBodyId = getBodyCenterFromFrameName(fromFrame);
		int toBodyId = getBodyCenterFromFrameName(toFrame);
		if (fromBodyId != toBodyId) {
			SpiceDouble state[6];
			SpiceDouble lt;
			spkgeo_c(fromBodyId, et, toFrame, toBodyId, state, &lt);

			if (SpiceKernelStatus::CheckErrors())
				return false;

			translation[0] = state[0];
			translation[1] = state[1];
			translation[2] = state[2];

		}
	}
	return true;
}

bool SpiceKernelMgr::computeTransformation(double input[3], double translation[3], double rotation[3][3], double output[3]) {
	SpiceDouble vin[3] = {input[0], input[1], input[2]};
	SpiceDouble vout[3];

	mxv_c (rotation, vin, vout);
	if (SpiceKernelStatus::CheckErrors())
		return false;

	output[0] = vout[0] + translation[0];
	output[1] = vout[1] + translation[1];
	output[2] = vout[2] + translation[2];

	return true;
}

} /* SpiceKernel */
} /* AMDA */