FileWriterCDFISTP.cc 11 KB
/**
 * FileWriterCDFISTP.cc
 *
 *  Created on: 28 feb. 2022
 *      Author: AKKA
 */

#include "FileWriterCDFISTP.hh"
#include "FileWriterCDF.hh"
#include "TimeUtil.hh"

#include "FileWriter.hh"
#include "ParamMgr.hh"
#include "DataSetMgr.hh"
#include "InstrumentMgr.hh"
#include "MissionMgr.hh"

#include <sstream>
#include <cstring>
#include <stdlib.h>
#include <boost/cast.hpp>

#define CDF_TIME_VAR "AMDA_TIME"

namespace AMDA {
	namespace ParamOutputImpl {
		namespace Download {
			namespace FileWriter {

				using namespace AMDA::Info;

				FileWriterCDFISTP::FileWriterCDFISTP(AMDA::Parameters::ParameterManager& pParameterManager) :
					FileWriterCDF(pParameterManager)
				{
				}

				FileWriterCDFISTP::~FileWriterCDFISTP(void)
				{
					closeFile();
				}

				void FileWriterCDFISTP::addInfoInMap(std::string key, std::string value){
					_infoMap.push_back(std::pair<std::string,std::string>(key,value));
				}

				bool FileWriterCDFISTP::writeAMDAInfo(std::string version, std::string createdby, std::string acknowledgement)
				{
					addAttribute("Data_type", "AMDA>Generated by Automated Multi Dataset Analysis tool", GLOBAL_SCOPE);
					addAttribute("Data_version", "01", GLOBAL_SCOPE);
					addAttribute("Acknowledgement", acknowledgement, GLOBAL_SCOPE);
					addAttribute("Software_version", version, GLOBAL_SCOPE);
					addAttribute("PI_affiliation", "CDPP", GLOBAL_SCOPE);
					addAttribute("PI_name", "AMDA Team", GLOBAL_SCOPE);
					addAttribute("Project", "AMDA>Automated Multi Dataset Analysis", GLOBAL_SCOPE);
					addAttribute("Source_name", "N/A", GLOBAL_SCOPE);
					addAttribute("TEXT", "N/A", GLOBAL_SCOPE);
					addAttribute("Generated_by", createdby, GLOBAL_SCOPE);
					addAttribute("HTTP_LINK", "http://amda.cdpp.eu/", GLOBAL_SCOPE);
					return true;
				}

				bool FileWriterCDFISTP::writeRequestInfo(std::string structure, std::string /* timeFormat */,
													 int timeResolution, std::string outputParams, std::string ttName)
				{

					addAttribute("Descriptor", outputParams, GLOBAL_SCOPE);
					addAttribute("Instrument_type", "Plasma and Solar Wind", GLOBAL_SCOPE);
					addAttribute("Logical_file_id", _fileName, GLOBAL_SCOPE);
					addAttribute("Logical_source", _filePrefix, GLOBAL_SCOPE);
					addAttribute("Logical_source_description", _filePrefix, GLOBAL_SCOPE);
					addAttribute("Mission_group", "N/A", GLOBAL_SCOPE);
					addAttribute(REQUEST_STRUCTURE, structure, GLOBAL_SCOPE);
					if (timeResolution > 0)
					{
						std::string resolution = std::to_string(timeResolution)+" sec";
						addAttribute("Time_resolution", resolution, GLOBAL_SCOPE);
					}
					if (!ttName.empty())
						addAttribute(REQUEST_TTNAME,ttName, GLOBAL_SCOPE);
					return true;
				}

				void FileWriterCDFISTP::writeTimeInfo()
				{
					int varNum = _cdfVarMap[CDF_TIME_VAR].varNum;
					
					addAttribute("CATDESC", "Epoch", VARIABLE_SCOPE, varNum);
					addAttribute("FIELDNAM", "Time", VARIABLE_SCOPE, varNum);
					addAttribute("FORMAT", _cdfVarMap[CDF_TIME_VAR].format, VARIABLE_SCOPE, varNum);
					addAttribute("VAR_TYPE", "support_data", VARIABLE_SCOPE, varNum);

					if(_cdfVarMap[CDF_TIME_VAR].type == CDF_TIME_TT2000){
						addAttribute("FILLVAL", "9999-12-31:23:59:59.999999999", VARIABLE_SCOPE, varNum);
						addAttribute("TIME_BASE", "J2000", VARIABLE_SCOPE, varNum);
						addAttribute("SI_CONVERSION", "1.0E-9>Second", VARIABLE_SCOPE, varNum);
						//addAttribute("UNITS", "ns", VARIABLE_SCOPE, varNum);
					}
					else{
						addAttribute("TIME_BASE", "UTC", VARIABLE_SCOPE, varNum);
						if (_cdfVarMap[CDF_TIME_VAR].type == CDF_EPOCH)
						{
							addAttribute("FILLVAL", "9999-12-31:23:59:59.999", VARIABLE_SCOPE, varNum);
							addAttribute("SI_CONVERSION", "1.0E-3>Second", VARIABLE_SCOPE, varNum);
							//addAttribute("UNITS", "ms", VARIABLE_SCOPE, varNum);
						}
						else
						{
							addAttribute("FILLVAL", "9999-12-31:23:59:59.999999999999", VARIABLE_SCOPE, varNum);
							addAttribute("SI_CONVERSION", "1.0E-12>Second", VARIABLE_SCOPE, varNum);
							//addAttribute("UNITS", "ps", VARIABLE_SCOPE, varNum);
						}
					}

					addAttribute("VALIDMIN", _cdfVarMap[CDF_TIME_VAR].validMin, VARIABLE_SCOPE, _cdfVarMap[CDF_TIME_VAR].type, varNum);
					addAttribute("VALIDMAX", _cdfVarMap[CDF_TIME_VAR].validMax, VARIABLE_SCOPE, _cdfVarMap[CDF_TIME_VAR].type, varNum);
				}
				void FileWriterCDFISTP::writeParamVariableAttributes(ParamInfoSPtr paramInfo, std::string paramId)
				{
					int varNum = _cdfVarMap[paramId].varNum;
					addInfoInMap("CATDESC", paramInfo->getName());
					addInfoInMap("DATA", "N/A");
					if(paramInfo->getTables().size() > 0)
						addInfoInMap("DISPLAY_TYPE", "spectrogram");
					else
						addInfoInMap("DISPLAY_TYPE", "time_series");

					addInfoInMap("FIELDNAM", paramInfo->getShortName());
					addAttribute("FILLVAL", paramInfo->getFillValue(), VARIABLE_SCOPE, varNum);
					addInfoInMap("FORMAT", _cdfVarMap[paramId].format);
					addInfoInMap("LABLAXIS", paramInfo->getShortName());
					//addInfoInMap("REPRESENTATION_i", paramInfo->getComponents());
					addInfoInMap("SI_CONVERSION", paramInfo->getSiConversion());
					//addInfoInMap("SIZES", "ToDo");	
					addInfoInMap("TENSOR_FRAME", paramInfo->getCoordinatesSystem());			
					addInfoInMap("TENSOR_ORDER", std::to_string(paramInfo->getTensorOrder()));	
					addInfoInMap("UNITS", paramInfo->getUnits());	
					
					addAttribute("VALIDMIN", _cdfVarMap[paramId].validMin, VARIABLE_SCOPE, _cdfVarMap[paramId].type, varNum);
					addAttribute("VALIDMAX", _cdfVarMap[paramId].validMax, VARIABLE_SCOPE, _cdfVarMap[paramId].type, varNum);
					//addInfoInMap("VALUE_TYPE", "ToDo");
					if (_cdfVarMap[paramId].isTableParam)
						addInfoInMap("VAR_TYPE", "support_data");
					else
						addInfoInMap("VAR_TYPE", "data");

					addInfoInMap("VAR_NOTES", paramInfo->getProcessInfo());
					addInfoInMap("DEPEND_0", CDF_TIME_VAR);	

					for (auto info : _infoMap)
						addAttribute(info.first, info.second, VARIABLE_SCOPE, varNum);	
				}
				bool FileWriterCDFISTP::writeTableParamsInfo(std::map<int, boost::shared_ptr<ParamTable>> &dependTables, std::string currentParamId)
				{
					for (auto dependTable : dependTables)
						{
							if(dependTable.second != nullptr)
							{
								if (!dependTable.second->isVariable(&_parameterManager))
								{
									std::string tableLabel = dependTable.second->getName(&_parameterManager);
									std::string tableName =  currentParamId;
									tableName += "_";
									tableName += tableLabel;

									int tableSize = dependTable.second->getSize(&_parameterManager);
									std::string tableUnits = dependTable.second->getUnits(&_parameterManager);

									long dimSizes[1] = {tableSize};
									long dimVarys[1] = {VARY};
									long recVary= {NOVARY};
									long tableNum = 0;

									std::string dependName = "DEPEND_";
									dependName += std::to_string(dependTable.first +1);
									addAttribute(dependName, tableName, VARIABLE_SCOPE, _cdfVarMap[currentParamId].varNum);

									// Creation of the new parameter.
									

									CDFstatus status =  CDFcreatezVar(FileWriterCDF::_cdfid, tableName.c_str(), CDF_DOUBLE, 1, 1L,
											dimSizes, recVary, dimVarys, &tableNum);	
									if (status == CDF_OK)
									{
										double* paramList = (double*)malloc(tableSize*sizeof(double));
										for (int i = 0; i <tableSize; ++i ){
											AMDA::Info::t_TableBound minMax =  dependTable.second->getBound(&_parameterManager, i);
											paramList[i] = (minMax.max+minMax.min)/2.;
										}
									
										status = CDFputzVarRecordData(_cdfid, tableNum, 0, (void*) paramList);
										free(paramList);

										addAttribute("CATDESC", tableLabel, VARIABLE_SCOPE, tableNum);
										addAttribute("DATA", "N/A", VARIABLE_SCOPE, tableNum);
										addAttribute("FIELDNAM", tableLabel,VARIABLE_SCOPE, tableNum);
										addAttribute("FILLVAL", "nan", VARIABLE_SCOPE, tableNum);
										addAttribute("FORMAT", "F14.3", VARIABLE_SCOPE, tableNum);
										addAttribute("LABLAXIS", tableLabel, VARIABLE_SCOPE, tableNum);
										addAttribute("UNITS", tableUnits, VARIABLE_SCOPE, tableNum);

										double validMin = -std::numeric_limits<double>::max();
										double validMax = std::numeric_limits<double>::max();
										
										addAttribute("VALIDMIN", (void*)&validMin, VARIABLE_SCOPE, CDF_DOUBLE, tableNum);
										addAttribute("VALIDMAX", (void*)&validMax, VARIABLE_SCOPE, CDF_DOUBLE, tableNum);
										addAttribute("VAR_TYPE", "support_data", VARIABLE_SCOPE, tableNum);

									}
								}
								else{
									AMDA::Parameters::ParameterSPtr paramTable = dependTable.second->createRelatedParameter(&_parameterManager);

									std::string dependName = "DEPEND_";
									dependName += std::to_string(dependTable.first +1);
									addAttribute(dependName, paramTable->getId(), VARIABLE_SCOPE, _cdfVarMap[currentParamId].varNum);
								}
							}
						}
					return true;
				}
				bool FileWriterCDFISTP::writeParamsInfo(ParamPropertiesList &paramPropertiesList, OutputStructure outputStructure,
													std::string currentParamId)
				{

					for (auto paramProperties : paramPropertiesList)
					{
						if ((outputStructure == ONE_FILE_PER_PARAMETER_PER_INTERVAL) &&
							(currentParamId != paramProperties->getOutputId()))
							// add info only for current parameter
							continue;
						ParameterSPtr p = _parameterManager.getParameter(paramProperties->getOutputId());
						AMDA::Info::ParamInfoSPtr paramInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(p->getInfoId());
						writeParamVariableAttributes(paramInfo, paramProperties->getOutputId());
						if(paramInfo != nullptr){

							// Adding DEPEND_S, only for non-variable case.

							writeTableParamsInfo(paramInfo->getTables(), paramProperties->getOutputId());
						}
					}
					return true;
				
				}

				/*bool FileWriterCDFISTP::writeMissionInfo(MissionInfoSPtr missionInfo, long varNum)
				{
					if (missionInfo == nullptr) {
						std::cout <<  std::endl << std::endl << std::endl <<  "FER - HAHAHAHA" << std::endl << std::endl << std::endl<< std::endl;
						addAttribute("Source_name", "unk>Unknown mission", GLOBAL_SCOPE);
						return false;
					}

					std::vector<std::pair<std::string,std::string>> infoMap = missionInfo->getInfoMap();
					
					for (auto info : infoMap)
						std::cout <<  std::endl << std::endl << std::endl  << "FER - " << &info << std::cout <<  std::endl << std::endl << std::endl << std::endl;
					//for (auto info : infoMap)
					//	if(info.first == "MISSION_NAME")
					//		addAttribute(info.first + ">" + info["MISSION_DESCRIPTION"]);

						//write info about mission

						//        std::vector<std::pair<std::string,std::string>> infoMap = missionInfo->getInfoMap();
						//
						//                for (auto info : infoMap)
						//                                addAttribute(info.first, info.second, VARIABLE_SCOPE, varNum);
						//                                        return true;
						//                                        }
					return true; 
				}*/
			} /* namespace FileWriter */
		} /* namespace Download */
	} /* namespace ParamOutputImpl */
} /* namespace AMDA */