/* * VirtualInstrument.cc * * Created on: Nov 21, 2014 * Author: AKKA */ #include "DicError.hh" #include "LocalFileInterfaceConfig.hh" #include "VirtualInstrument.hh" #include "VirtualInstrumentManager.hh" #include "VirtualInstrumentInterval.hh" #include "LocalParamData.hh" #include "FileReaderCDF.hh" #include "FileReaderASCII.hh" #include "FileReaderVOTable.hh" #include "FileReaderNetCDF.hh" #include #include namespace AMDA { namespace LocalFileInterface { VirtualInstrument::VirtualInstrument(VirtualInstrumentManager& pVirtualInstrumentManager, const std::string& VIId) : _virtualInstrumentManager(pVirtualInstrumentManager), _VIId(VIId), _globalStartTime(0.), _globalStopTime(0.), _filesFormat(VIFileFormat::FORMAT_UNKNOWN), _timeId(""), _fileReaderPtr(NULL) { } VirtualInstrument::~VirtualInstrument() { //delete the file reader if needed if (_fileReaderPtr != NULL) delete _fileReaderPtr; } void VirtualInstrument::addFileDefinition(const char* pName, double pStart,double pStop) { //push back a file in the files list LocalFileDefinition newDef; newDef._name = pName; newDef._start = pStart; newDef._stop = pStop; _files.push_back(newDef); } bool VirtualInstrument::createFileReader(LocalTimeFormat timeFormat) { if (_fileReaderPtr != NULL) //file reader already created return true; switch (_filesFormat) { case VIFileFormat::FORMAT_CDF : //CDF file format _fileReaderPtr = new FileReaderCDF(); LOG4CXX_INFO(gLogger, "VirtualInstrument::createFileReader - CDF Reader created"); break; case VIFileFormat::FORMAT_ASCII : //ASCII file format _fileReaderPtr = new FileReaderASCII(); reinterpret_cast(_fileReaderPtr)->setTimeFormat(timeFormat); LOG4CXX_INFO(gLogger, "VirtualInstrument::createFileReader - ASCII Reader created"); break; case VIFileFormat::FORMAT_VOT : //VOTable file format _fileReaderPtr = new FileReaderVOTable(); LOG4CXX_INFO(gLogger, "VirtualInstrument::createFileReader - VOTable Reader created"); break; case VIFileFormat::FORMAT_NETCDF : //netCDF file format _fileReaderPtr = new FileReaderNetCDF(); LOG4CXX_INFO(gLogger, "VirtualInstrument::createFileReader - netCDF Reader created"); break; default: LOG4CXX_ERROR(gLogger, "VirtualInstrument::createFileReader - Reader not implemented"); } return (_fileReaderPtr != NULL); } std::string VirtualInstrument::getFileFullPath(int fileIndex) { //build file full path from file index if ((fileIndex >= (int)_files.size()) || (fileIndex < 0)) return ""; std::string filePath = _virtualInstrumentManager.getBasePath()+"/"; filePath += _files[fileIndex]._name; boost::filesystem::path p(filePath); boost::filesystem::path full_p = boost::filesystem::complete(p); // complete == absolute std::string res = full_p.string(); return res; } PusherBase* VirtualInstrument::createPusher(std::string& paramId, LocalParamType ¶mType, int& dim1Size, int& dim2Size) { LOG4CXX_DEBUG(gLogger, "VirtualInstrument::createPusher " << paramId); PusherBase* lPusher = NULL; //Check reader if (_fileReaderPtr == NULL) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - No reader defined"); return NULL; } //Check list of files if (_files.empty()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - No file define for the VirtualInstrument " << _VIId); return NULL; } //use the first file to get the param type std::string filePath = getFileFullPath(0); //open the file if (!_fileReaderPtr->open(filePath)) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Cannot open file " << filePath); return NULL; } //get param type and size bool success = _fileReaderPtr->getParamInfo(paramId, paramType, dim1Size, dim2Size); //close the file if (!_fileReaderPtr->close()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Cannot close file " << filePath); } if (!success) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Cannot get param info for " << paramId); return NULL; } if (paramType == LocalParamType::TYPE_UNKNOWN) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Unknown data type"); return NULL; } //create the pusher if ((dim1Size > 1) && (dim2Size > 1)) { //Tab2D switch (paramType) { case TYPE_FLOAT : lPusher = new Pusher(dim1Size,dim2Size); break; case TYPE_DOUBLE : lPusher = new Pusher(dim1Size,dim2Size); break; case TYPE_SHORT : lPusher = new Pusher(dim1Size,dim2Size); break; case TYPE_INT : lPusher = new Pusher(dim1Size,dim2Size); break; default: lPusher = NULL; LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Data type not implemented"); } } else if ((dim1Size > 1) || (dim2Size > 1)) { //vector int dimSize = (dim1Size > 1) ? dim1Size : dim2Size; switch (paramType) { case TYPE_FLOAT : lPusher = new Pusher(dimSize); break; case TYPE_DOUBLE : lPusher = new Pusher(dimSize); break; case TYPE_SHORT : lPusher = new Pusher(dimSize); break; case TYPE_INT : lPusher = new Pusher(dimSize); break; default: lPusher = NULL; LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Data type not implemented"); } } else if (dim1Size == 1) { //scalar switch (paramType) { case TYPE_FLOAT : lPusher = new Pusher(); break; case TYPE_DOUBLE : lPusher = new Pusher(); break; case TYPE_SHORT : lPusher = new Pusher(); break; case TYPE_INT : lPusher = new Pusher(); break; default: lPusher = NULL; LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Data type not implemented"); } } else { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Incorrect param size"); return NULL; } return lPusher; } bool VirtualInstrument::updateTimeId() { LOG4CXX_DEBUG(gLogger, "VirtualInstrument::updateTimeId"); //Check reader if (_fileReaderPtr == NULL) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::updateTimeId - No reader defined"); return false; } //Check list of files if (_files.empty()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::updateTimeId - No file define for the VirtualInstrument " << _VIId); return false; } //use the first file to get the time param id std::string filePath = getFileFullPath(0); //open the file if (!_fileReaderPtr->open(filePath)) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::updateTimeId - Cannot open file " << filePath); return false; } _timeId = _fileReaderPtr->getTimeParamId(); LOG4CXX_DEBUG(gLogger, "VirtualInstrument::updateTimeId - _timeId: " << _timeId); //close the file if (!_fileReaderPtr->close()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::updateTimeId - Cannot close file " << filePath); } return (_timeId != ""); } ParamFlowSPtr VirtualInstrument::getParamFlow(const std::string& pParamId, TimeIntervalListSPtr pTimeIntervalList, LocalParamType paramType, int dim1Size, int dim2Size) { // Define function to compare two TimeIntervalListSptr. // This used to identify if the requested TimeIntervalList already exist in _intervalList attribute or not. auto lIt = std::find_if( _intervalList.begin(), _intervalList.end(), [&](const IntervalList::value_type& val) -> bool { if (val.first->size() != pTimeIntervalList->size()) { return false; } else { TimeIntervalList::const_iterator itA = val.first->begin(); TimeIntervalList::const_iterator itB = pTimeIntervalList->begin(); while (itA != val.first->end()) { if ( (itA->_startTime != itB->_startTime) || (itA->_stopTime != itB->_stopTime) ) { return false; } else { ++itA; ++itB; } } return true; } }); // TimeIntervalListSPtr not found if (lIt == _intervalList.end()) { std::pair value(pTimeIntervalList, VirtualIntrumentIntervalSPtr(new VirtualInstrumentInterval(*this, pTimeIntervalList.get()))); std::pair lIter = _intervalList.insert(value); lIt = lIter.first; } else { // Nothing to do. } return lIt->second->getParamFlow(pParamId, paramType, dim1Size, dim2Size); } bool VirtualInstrument::getDataPosition(double& startTime, double& stopTime, int& fileIndex, int& recordIndex) { LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getDataPosition"); if (startTime > _globalStopTime || stopTime < _globalStartTime) { LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getDataPosition - Time out of the global interval definition"); return false; } //Check if time is include in a file fileIndex = 0; for (auto fileInfo : _files) { if ((fileInfo._start <= startTime) && (fileInfo._stop >= startTime)) break; ++fileIndex; } if (fileIndex == (int)_files.size()) { //change time to the nearest file start time fileIndex = 0; for (auto fileInfo : _files) { if (fileInfo._start > startTime) { startTime = fileInfo._start; recordIndex = 0; return true; } ++fileIndex; } } //search time position in file std::string filePath = getFileFullPath(fileIndex); //open the file if (!_fileReaderPtr->open(filePath)) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getDataPosition - Cannot open file " << filePath); return false; } recordIndex = _fileReaderPtr->getRecordIndex(_timeId, startTime); //close the file if (!_fileReaderPtr->close()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::createPusher - Cannot close file " << filePath); } return (recordIndex >= 0); } FileReaderStatus VirtualInstrument::getParamPacketData(std::string& paramId, int fileIndex, int recordIndex, double stopTime, LocalParamDataPacket *packet) { LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getParamPacketData"); if (fileIndex >= (int)_files.size()) //no more file available return FRS_FINISH; //get file full path std::string filePath = getFileFullPath(fileIndex); if (filePath == "") return FRS_ERROR; //open the file if (!_fileReaderPtr->open(filePath)) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getParamData - Cannot open file " << filePath); return FRS_ERROR; } FileReaderStatus status = _fileReaderPtr->getParamPacketData(_timeId, paramId, recordIndex, stopTime, packet); //close the file if ((status != FRS_MORE) && !_fileReaderPtr->close()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getParamData - Cannot close file " << filePath); } return status; } InfoValuesSPtr& VirtualInstrument::getFileInfo(const char* pInfoName) { LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getFileInfo " << pInfoName); auto lIt = _infoMap.find(pInfoName); if (lIt == _infoMap.end()) { _infoMap[pInfoName].reset(new std::vector); //Check reader if (_fileReaderPtr == NULL) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getFileInfo - No reader defined"); return _infoMap[pInfoName]; } //Check list of files if (_files.empty()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getFileInfo - No file define for the VirtualInstrument " << _VIId); return _infoMap[pInfoName]; } //use the first file to get the param type std::string filePath = getFileFullPath(0); //open the file if (!_fileReaderPtr->open(filePath)) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getFileInfo - Cannot open file " << filePath); return _infoMap[pInfoName]; } _fileReaderPtr->getInfo(pInfoName,*_infoMap[pInfoName].get()); if (!_fileReaderPtr->close()) { LOG4CXX_ERROR(gLogger, "VirtualInstrument::getParamData - Cannot close file " << filePath); } return _infoMap[pInfoName]; } return lIt->second; } } /* namespace LocalFileInterface */ } /* namespace AMDA */