From bd9dfce2c8b349bae57f4af486fa23dea382bfe0 Mon Sep 17 00:00:00 2001 From: Benjamin Renard <benjamin.renard@akka.eu> Date: Fri, 25 Sep 2015 17:45:10 +0200 Subject: [PATCH] Add CALLEXT and DECODERS for access to external datasets --- CMakeLists.txt | 10 ++++++++++ src/CALLEXT/cdaweb_cfg.php | 9 +++++++++ src/CALLEXT/createHeaderMAPSKP.php | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/createHeaderVEXGRAZ.php | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/createVI.php | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/ddserver_ini.php | 23 +++++++++++++++++++++++ src/CALLEXT/ftpWrapper.php | 24 ++++++++++++++++++++++++ src/CALLEXT/getDataCDAWEB.php | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/getDataCDPP.php | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/getDataMAPSKP.php | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/getDataSKR.php | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/getDataTHEMIS.php | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/getDataVEXGRAZ.php | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/makeRPWS_KEYinfo.php | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CALLEXT/mapskp_cfg.php | 5 +++++ src/DECODERS/ascii2nc/CMakeLists.txt | 24 ++++++++++++++++++++++++ src/DECODERS/ascii2nc/ascii2nc.c | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/cdf2nc/CMakeLists.txt | 26 ++++++++++++++++++++++++++ src/DECODERS/cdf2nc/cdf2nc.c | 1616 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/cdf2nc/cdf_to_netcdf_mapping.dat | 12 ++++++++++++ src/DECODERS/nc2nc/CMakeLists.txt | 24 ++++++++++++++++++++++++ src/DECODERS/nc2nc/nc2nc.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/themis/esa2nc/CMakeLists.txt | 26 ++++++++++++++++++++++++++ src/DECODERS/themis/esa2nc/themis_esa2nc.c | 551 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/themis/esafull2nc/CMakeLists.txt | 26 ++++++++++++++++++++++++++ src/DECODERS/themis/esafull2nc/themis_esafull2nc.c | 659 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/themis/esamom2nc/CMakeLists.txt | 26 ++++++++++++++++++++++++++ src/DECODERS/themis/esamom2nc/themis_esamom2nc.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/themis/fgm2nc/CMakeLists.txt | 26 ++++++++++++++++++++++++++ src/DECODERS/themis/fgm2nc/themis_fgm2nc.c | 351 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DECODERS/themis/sst2nc/CMakeLists.txt | 26 ++++++++++++++++++++++++++ src/DECODERS/themis/sst2nc/themis_sst2nc.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/INCLUDE/DD_comm.h | 4 ++-- 33 files changed, 5727 insertions(+), 2 deletions(-) create mode 100644 src/CALLEXT/cdaweb_cfg.php create mode 100644 src/CALLEXT/createHeaderMAPSKP.php create mode 100644 src/CALLEXT/createHeaderVEXGRAZ.php create mode 100755 src/CALLEXT/createVI.php create mode 100644 src/CALLEXT/ddserver_ini.php create mode 100644 src/CALLEXT/ftpWrapper.php create mode 100755 src/CALLEXT/getDataCDAWEB.php create mode 100755 src/CALLEXT/getDataCDPP.php create mode 100644 src/CALLEXT/getDataMAPSKP.php create mode 100644 src/CALLEXT/getDataSKR.php create mode 100644 src/CALLEXT/getDataTHEMIS.php create mode 100644 src/CALLEXT/getDataVEXGRAZ.php create mode 100644 src/CALLEXT/makeRPWS_KEYinfo.php create mode 100644 src/CALLEXT/mapskp_cfg.php create mode 100644 src/DECODERS/ascii2nc/CMakeLists.txt create mode 100755 src/DECODERS/ascii2nc/ascii2nc.c create mode 100644 src/DECODERS/cdf2nc/CMakeLists.txt create mode 100755 src/DECODERS/cdf2nc/cdf2nc.c create mode 100644 src/DECODERS/cdf2nc/cdf_to_netcdf_mapping.dat create mode 100644 src/DECODERS/nc2nc/CMakeLists.txt create mode 100644 src/DECODERS/nc2nc/nc2nc.c create mode 100644 src/DECODERS/themis/esa2nc/CMakeLists.txt create mode 100644 src/DECODERS/themis/esa2nc/themis_esa2nc.c create mode 100644 src/DECODERS/themis/esafull2nc/CMakeLists.txt create mode 100644 src/DECODERS/themis/esafull2nc/themis_esafull2nc.c create mode 100644 src/DECODERS/themis/esamom2nc/CMakeLists.txt create mode 100644 src/DECODERS/themis/esamom2nc/themis_esamom2nc.c create mode 100644 src/DECODERS/themis/fgm2nc/CMakeLists.txt create mode 100644 src/DECODERS/themis/fgm2nc/themis_fgm2nc.c create mode 100644 src/DECODERS/themis/sst2nc/CMakeLists.txt create mode 100644 src/DECODERS/themis/sst2nc/themis_sst2nc.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fedf9a..3dd747e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") find_package( Threads REQUIRED ) find_package( CRYPT REQUIRED ) find_package( NetCDF REQUIRED ) +find_package( CDF REQUIRED ) get_filename_component(NETCDFLIB_DIR ${NETCDFLIBRARIES} PATH) @@ -36,9 +37,18 @@ configure_file ( MESSAGE( STATUS "Build DD_Server Project" ) add_subdirectory(src/CLIENT) add_subdirectory(src/SERVER) +add_subdirectory(src/DECODERS/ascii2nc) +add_subdirectory(src/DECODERS/cdf2nc) +add_subdirectory(src/DECODERS/nc2nc) +add_subdirectory(src/DECODERS/themis/esa2nc) +add_subdirectory(src/DECODERS/themis/esafull2nc) +add_subdirectory(src/DECODERS/themis/esamom2nc) +add_subdirectory(src/DECODERS/themis/fgm2nc) +add_subdirectory(src/DECODERS/themis/sst2nc) add_subdirectory(tests) install(FILES "scripts/StartServer" DESTINATION . PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY "src/INCLUDE/" DESTINATION include) +install(DIRECTORY "src/CALLEXT/" DESTINATION bin/CALLEXT) SET(CMAKE_VERBOSE_MAKEFILE ON) diff --git a/src/CALLEXT/cdaweb_cfg.php b/src/CALLEXT/cdaweb_cfg.php new file mode 100644 index 0000000..4eb728a --- /dev/null +++ b/src/CALLEXT/cdaweb_cfg.php @@ -0,0 +1,9 @@ +<?php + define("ftp_server", "cdaweb.gsfc.nasa.gov"); + define("ftp_user_name", "anonymous"); + define("ftp_user_pass", "budnik@irap.omp.eu"); + define("ftp_dir", "pub/software/cdawlib/0MASTERS/"); + + define ("wsdlCDAWEB", "http://cdaweb.gsfc.nasa.gov/WS/jaxrpc?WSDL"); + define ("viewID" , "istp_public"); +?> \ No newline at end of file diff --git a/src/CALLEXT/createHeaderMAPSKP.php b/src/CALLEXT/createHeaderMAPSKP.php new file mode 100644 index 0000000..2a07084 --- /dev/null +++ b/src/CALLEXT/createHeaderMAPSKP.php @@ -0,0 +1,84 @@ +<?php +/* $Id: createHeaderMAPSKP.php,v 1.5 2008/03/05 14:03:45 elena Exp $ */ +/** +* \file createHeaderMAPSKP.php +* \brief Function to create header.nc for MapsKP datasets which are not self-described +* \todo Exclude absolute path for /usr/local/bin/ncgen +*/ + +function createHeaderMAPSKP($remSetID) { + + $url = "http://planetoweb.cesr.fr/mapskp-amda/MapskpService.php?"; + $passwd = "ftp://amda:dd;mapskp@"; + + $args = array('service'=>'getInfoUrl', + 'datasetId'=>$remSetID); + + $url .= http_build_query($args); + $infoDom = new DOMDocument(); + $infoDom->load($url); + $File = $infoDom->getElementsByTagName("infoUrl")->item(0)->nodeValue; + + $fileName_ = explode("ftp://",$File); + $fileName = $fileName_[0].$passwd.$fileName_[1]; + + $infoDom->load($fileName); + + $sampling = $infoDom->getElementsByTagName("TIME_RESOLUTION")->item(0)->nodeValue; + $globalAttrs = ":minSampling = ".$sampling.";"; + + $params = $infoDom->getElementsByTagName("PARAM_METADATA"); + + $Dimensions = "Time = unlimited, TimeLength = 17 "; + $charVariables = "char Time(Time,TimeLength), StartTime(TimeLength), StopTime(TimeLength);"; + $floatVariables = "float "; + + $Size = array(); + $addDim = true; + + for ($i = 0; $i < $params->length; $i++) { + + $Name = $params->item($i)->getElementsByTagName("PARAM_ID")->item(0)->nodeValue; + $Size[$i] = $params->item($i)->getElementsByTagName("SIZES")->item(0)->nodeValue; + $Type = $params->item($i)->getElementsByTagName("DATA_TYPE")->item(0)->nodeValue; + + if ($i > 0) $floatVariables .= ","; + + if ($Size[$i] != "1" ) { + for ($j = 0; $j < $i+1; $j++) + if ($Size[$i] == $Size[$j]) { + if ($i != 0 && $j != $i) $addDim = false; + break; + } + if ($addDim) $Dimensions .= ", Dim".$j." = ".$Size[$j]; + $floatVariables .= $Name."(Time, Dim".$j.")"; + $addDim = true; + } + else + $floatVariables .= $Name."(Time)"; +// + } + +// Create CDL ASCII file + $cdl = fopen("header.cdl","w"); + fwrite($cdl, "netcdf header { \n \n dimensions: \n"); + fwrite($cdl,$Dimensions."; \n\n"); + + fwrite($cdl, "variables: \n "); + fwrite($cdl, $charVariables."\n"); + fwrite($cdl, $floatVariables."; \n \n"); + fwrite($cdl, $globalAttrs."\n"); + fwrite($cdl, "data: \n\n }"); + fclose($cdl); +// transform to nc + system("/usr/bin/ncgen -o header.nc header.cdl"); +// make constant Energy Tables in info.nc +// For MIMI also ... + if ($remSetID == "RPWS_KEY") { + $StartTime = $infoDom->getElementsByTagName("START_DATE")->item(0)->nodeValue; + $function = "make".$remSetID."info"; + include($function.".php"); + if ($OK = $function($StartTime)) system("join_nc ".strtolower($remSetID)."_constant.nc ".strtolower($remSetID)."_info.nc"); + } + } +?> diff --git a/src/CALLEXT/createHeaderVEXGRAZ.php b/src/CALLEXT/createHeaderVEXGRAZ.php new file mode 100644 index 0000000..550ea46 --- /dev/null +++ b/src/CALLEXT/createHeaderVEXGRAZ.php @@ -0,0 +1,64 @@ +<?php +/** +* @file createHeaderVEXGRAZ.php +* @version $Id: createHeaderVEXGRAZ.php,v 1.1 2009/03/23 14:02:39 budnik Exp $ +* @brief Function to create header.nc for MapsKP datasets which are not self-described +* @todo Exclude absolute path for /usr/local/bin/ncgen +*/ + + +function createHeaderVEXGRAZ($remSetID) { + + $infoDom = new DOMDocument(); + $infoDom->load(INFODIR."../AmdaInfo/MAG_VSO.xml"); + + $sampling = $infoDom->getElementsByTagName("TIME_RESOLUTION")->item(0)->nodeValue; + $globalAttrs = ":minSampling = ".$sampling.";"; + + $params = $infoDom->getElementsByTagName("PARAM_METADATA"); + + $Dimensions = "Time = unlimited, TimeLength = 17 "; + $charVariables = "char Time(Time,TimeLength), StartTime(TimeLength), StopTime(TimeLength);"; + $floatVariables = "float "; + + $Size = array(); + $addDim = true; + + for ($i = 0; $i < $params->length; $i++) { + + $Name = $params->item($i)->getElementsByTagName("PARAM_ID")->item(0)->nodeValue; + $Size[$i] = $params->item($i)->getElementsByTagName("SIZES")->item(0)->nodeValue; + $Type = $params->item($i)->getElementsByTagName("DATA_TYPE")->item(0)->nodeValue; + + if ($i > 0) $floatVariables .= ","; + + if ($Size[$i] != "1" ) { + for ($j = 0; $j < $i+1; $j++) + if ($Size[$i] == $Size[$j]) { + if ($i != 0 && $j != $i) $addDim = false; + break; + } + if ($addDim) $Dimensions .= ", Dim".$j." = ".$Size[$j]; + $floatVariables .= $Name."(Time, Dim".$j.")"; + $addDim = true; + } + else + $floatVariables .= $Name."(Time)"; +// + } + +// Create CDL ASCII file + $cdl = fopen("header.cdl","w"); + fwrite($cdl, "netcdf header { \n \n dimensions: \n"); + fwrite($cdl,$Dimensions."; \n\n"); + + fwrite($cdl, "variables: \n "); + fwrite($cdl, $charVariables."\n"); + fwrite($cdl, $floatVariables."; \n \n"); + fwrite($cdl, $globalAttrs."\n"); + fwrite($cdl, "data: \n\n }"); + fclose($cdl); +// transform to nc + system("/usr/local/bin/ncgen -o header.nc header.cdl"); + } +?> diff --git a/src/CALLEXT/createVI.php b/src/CALLEXT/createVI.php new file mode 100755 index 0000000..64f2ab2 --- /dev/null +++ b/src/CALLEXT/createVI.php @@ -0,0 +1,298 @@ +<?php +/*---------------------------------------------------------------------- + * DD SERVER TOOLS + * data update collection + * createVI.php + * 17 Jun 2007 V.1.0 + * 01 Aug 2007 V.1.1 Only one argument in info2nc call + * 02 Aug 2007 V.1.2 rebuild, clean & cash from templates in DDLIB + * 05 Sep 2007 V.1.3 creates empty *times.nc + * 24 Nov 2007 V.1.4 DDrehash -> TimesUpdate + * 14 Feb 2008 V.1.5 added Mission & Instrument tags ; and createHeader if neccessary + * 11 Sep 2012 V.1.6 get dataset info from remote DB to keep it at server side in the only one place + *-----------------------------------------------------------------------*/ + +function getCDF($remSetID){ + + $client = new SoapClient(wsdlCDAWEB); +/* Get "VIEW" descriptions, select "istp_public" and set endPoint address*/ + $metaData = $client->__soapCall("getAllViewDescriptions", array()); + + for ($k = 0; $k < count($metaData); $k++) { + if ($metaData[$k]->id != viewID) continue; + try { + $client->__setLocation($metaData[$k]->endpointAddress); + break; + } + catch (SoapFault $exception){ + error_log($exception.PHP_EOL, 3, err); + return false; + } + } + $fileXML = INFODIR.'CDAWEB/'.$remSetID.'.xml'; + if (!file_exists($fileXML)) { + error_log('No DDServer XML description '.$remSetID.PHP_EOL, 3, err); + return false; + } + $XML= new DomDocument("1.0"); + $XML->load($fileXML); + + $Start = $XML->getElementsByTagName('GlobalStart')->item(0)->nodeValue; + $fileName = strtolower($remSetID)."_00000000_v01.cdf"; + $Stop = strftime("%Y-%m-%dT%H:%M:%S.000Z",strtotime($Start) + 82800); + $nFiles = 0; + $INFO_DIR = INFODIR."../CDAWEB/DATASETS/"; + + while ($nFiles == 0){ + $dataFileDesc = $client->__soapCall("getDataFiles", array($remSetID, $Start, $Stop)); + $nFiles = count($dataFileDesc); + if ($nFiles > 0) { + if (!copy($dataFileDesc[0]->name, $INFO_DIR.$fileName)){ + error_log('Cannot copy '.$dataFileDesc[0]->name.PHP_EOL, 3, err); + return false; + } + } + $Start = strftime("%Y-%m-%dT%H:%M:%S.000Z",strtotime($Stop) + 82800); + $Stop = strftime("%Y-%m-%dT%H:%M:%S.000Z",strtotime($Start) + 82800); + } + if ($nFiles == 0) { + error_log('No data file '.$remSetID.' '.$Start.PHP_EOL, 3, err); + return false; + } + + return true; +} + +function getInfoFromRemoteBase($dataBaseID, $remSetID){ + + $INFO_DIR = INFODIR."../".$dataBaseID."/DATASETS/"; + if (!is_dir($INFO_DIR)) mkdir($INFO_DIR, 0755, true); + + switch ($dataBaseID) { + case 'CDAWEB' : + require_once "ftpWrapper.php"; + require_once "cdaweb_cfg.php"; + + $fileName = strtolower($remSetID)."_00000000_v01.cdf"; + if (file_exists($INFO_DIR.$fileName)) return true; + + // Get master CDF + if (!ftpWrapper(ftp_server, ftp_user_name, ftp_user_pass, + ftp_dir.$fileName, $INFO_DIR.$fileName)) { + error_log('No master CDF for '.$remSetID.PHP_EOL, 3, err); + // No master CDF - try regular file + return getCDF($remSetID); + } + + return true; + + break; + case "MAPSKP": + + require_once "mapskp_cfg.php"; + + $XML_NAME = $remSetID.".xml"; + if (file_exists($INFO_DIR.$XML_NAME)) return true; + + $args = array('service'=>'getInfoUrl', 'datasetId'=>$remSetID); + + $url = url.http_build_query($args); + + $infoDom = new DOMDocument(); + $infoDom->load($url); + $File = $infoDom->getElementsByTagName("infoUrl")->item(0)->nodeValue; + + $fileName_ = explode("ftp://",$File); + $fileName = $fileName_[0].passwd.$fileName_[1]; + + if (!copy($fileName,$INFO_DIR.$XML_NAME)) return false; + return true; + + break; + + case "VEXGRAZ" : + $fileName = "MAG_VSO.xml"; + if (file_exists($INFO_DIR.$fileName)) return true; + return false; + break; + + case "CDPP" : + + break; + + default: + } + + return true; + +}; + +function getInfoFromAmda($dataBaseID, $remSetID) +{ + + global $DDsysInfo; + + if (file_exists(BASEDIR.'info.xml')) unlink(BASEDIR.'info.xml'); + + $DDinfo = new DomDocument("1.0"); + $VI = $DDinfo->createElement("VI"); + + $InfoArr = $DDsysInfo->getElementsByTagName("VI")->item(0)->childNodes; + for ($i = 0; $i < $InfoArr->length; $i++) + if ($InfoArr->item($i)->nodeName != '#text' && $InfoArr->item($i)->nodeName != 'PARAMETER') + $VI->appendChild($DDinfo->importNode($InfoArr->item($i), true)); + $VI->appendChild($DDinfo->createElement("LocalStart")); + $VI->appendChild($DDinfo->createElement("LocalStop")); + $DDinfo->appendChild($VI); + $DDinfo->save(BASEDIR.'info.xml'); + + return true; +} + +/** +* @file createVI.php +* @brief DD_Server tool <br> Creates New Virtual Instrument +* @version $Id: createVI.php,v 1.11 2013/09/23 09:02:28 budnik Exp $ +* Creates New VI at DD_Server Side \n +* Args: dataBaseID ddDataSetID remoteDataSetID \n +* Env Vars: $DDBASE $DDBASEBIN $DDLIB \n +* Executables: makeDDsys info2nc TimesUpdate \n +* Functions: getInfoFromAmda +* +* @arg Checks if VI already exists in dataBase desctiptor $DDBASE/DDsys.xml +* @arg Adds non-existing VI to DDres.xml +* @arg $DDBASEBIN/makeDDsys creats refer.nc file from DDsys.xml +* @arg Gets dataSet Info from INFO/DDServer dir +* @arg Creates dir, *_cash.nc, *_info.nc and empty *_times.nc +* +*/ + + global $DDsysInfo; + + define("verbose", true); + + + define("BASEDIR",getenv("DDBASE")."/"); + define("INFODIR",BASEDIR."../INFO/DDServer/"); + define("DDBASEBIN",getenv("DDBASEBIN")); + define("DDLIB", getenv("DDLIB")."/"); + + define ("log",BASEDIR."../INFO/addVI.log"); + define ("err",BASEDIR."../INFO/addVI.err"); + + + if ($argc != 4) { + error_log("Usage: php createVI.php <BaseID> <RemSetID> <NewVIName>".PHP_EOL, 3, err); + exit("Usage: php createVI.php <BaseID> <RemSetID> <NewVIName>".PHP_EOL); + } + + $dataBaseID = strtoupper($argv[1]); + $remSetID = $argv[2]; + $VIID = strtolower($argv[3]); + + + + $MAX_VI_NAME_LENGTH = 16; + $nc_prefix = strlen($VIID) > $MAX_VI_NAME_LENGTH ? substr($VIID,0,15): $VIID; + + $newDataSet = false; + $DDsysRefer = BASEDIR."DDsys.xml"; + if (verbose) + error_log("request to add Data Set ".$dataBaseID.":".$remSetID." as ".$VIID.PHP_EOL, 3, log); +// Check if dataSet exists already + $DDsys = new DomDocument("1.0"); + $DDsys->preserveWhiteSpace = false; + $DDsys->formatOutput = true; + $DDsys->load($DDsysRefer); + + $xp = new domxpath($DDsys); + $dataSet = $xp->query("//NAME[.='".$VIID."']"); + + if ($dataSet->item(0) != NULL) + if ($dataSet->item(0)->getAttribute("base") != $dataBaseID) { + error_log(" Data Set ".$VIID." exists! Corresponding BaseID is " + .$dataSet->item(0)->getAttribute("base")." not ".$dataBaseID.PHP_EOL, 3, err); + + $newDataSet = true; + } + if ($dataSet->item(0) == NULL) $newDataSet = true; + +//-------------- Get Full Dataset Info file from distant database------------- +//TODO error processing here + $res = getInfoFromRemoteBase($dataBaseID, $remSetID); + if (!$res) + error_log("Error: Can't get dataset info for ".$remSetID." from ".$dataBaseID.PHP_EOL, 3, err); + + if (verbose) error_log("Get dataset info for ".$remSetID." from ".$dataBaseID." returns ".$res.PHP_EOL, 3, log); + if ($newDataSet) { + +//----------- Gets INFO from INFO/DDServer ------------------- + if (verbose) error_log("Ready to Add ".$VIID.PHP_EOL, 3, log); + $DDsysInfo = new DomDocument("1.0"); + +//----------- Getting INFO file for DataSet + $XmlName = INFODIR.$dataBaseID."/".$remSetID.".xml"; + + if (file_exists($XmlName)){ + + $DDsysInfo->load($XmlName); + $mission = $DDsysInfo->getElementsByTagName("Mission")->item(0)->nodeValue; + $instrument = $DDsysInfo->getElementsByTagName("Instrument")->item(0)->nodeValue; + +//--------- Check if additional Info should be added to VI + + $theFormat = $DDsysInfo->getElementsByTagName("Format")->item(0); + if ($theFormat != NULL) + $AddInfo = ($theFormat->nodeValue == "Text"); + if (!$AddInfo) + $AddInfo = ($DDsysInfo->getElementsByTagName("AdditionalInfoNeed")->item(0) != NULL); + + //--------------------------------------------------------- + $newVIdir = BASEDIR.$dataBaseID."/".strtoupper($VIID)."/"; +// New Data Set - add to DDsys.xml + $base = $xp->query("/DD_BASE")->item(0); + $newVI= $DDsys->createElement("VI"); + $newName = $DDsys->createElement("NAME",$VIID); + $newattrBase = new DomAttr('base', $dataBaseID); + $newattrMission = new DomAttr('mission', $mission); + $newattrIns = new DomAttr('instrument', $instrument); + $newName->appendChild($newattrBase); + $newName->appendChild($newattrMission); + $newName->appendChild($newattrIns); + $newVI->appendChild($newName); + $newVI->appendChild($DDsys->createElement("LOCATION", $newVIdir)); + $newVI->appendChild($DDsys->createElement("TIMES", $VIID."_times.nc")); + $newVI->appendChild($DDsys->createElement("INFO", $VIID."_info.nc")); + $newVI->appendChild($DDsys->createElement("CACHE", $VIID."_cash.nc")); + $base->appendChild($newVI); + + $DDsys->save($DDsysRefer); +// xml to refer.nc + exec(DDBASEBIN.'/makeDDsys'); + +// Now make new dir ..... + if (!is_dir(BASEDIR.$dataBaseID)) mkdir(BASEDIR.$dataBaseID."/", 0755, true); + if (!is_dir($newVIdir)) mkdir($newVIdir, 0755, true); + copy (DDLIB."Cash.template", $newVIdir."/".$VIID."_cash.nc"); + $SED = "sed 's/NAME/".$nc_prefix."/g' ".DDLIB."Clean.template | sed 's/CACHE/".$VIID."/g' > ".$newVIdir."/clean"; + exec($SED); + exec('chmod ugo+x '.$newVIdir.'/clean'); +// Now info.nc from metadonnees + $err = getInfoFromAmda($dataBaseID, $remSetID); + if ($err) exec(DDBASEBIN.'/info2nc '.$newVIdir.'/'.$VIID.'_info.nc'); +// Create empty times file + chdir($newVIdir); + exec(DDBASEBIN.'/TimesUpdate -r '.$VIID.'_times.nc '.$VIID.'_[0-9]*.nc'); + + if ($AddInfo) { + $function_name = "createHeader".$dataBaseID; + require_once(DDLIB.$function_name.".php"); + $function_name($remSetID); + } + if (verbose) error_log("Added ".$VIID.PHP_EOL, 3, log); + } + else { + error_log("Error: ".$VIID." not added: no XML DDServer info file ".PHP_EOL, 3, err); + } + } +?> \ No newline at end of file diff --git a/src/CALLEXT/ddserver_ini.php b/src/CALLEXT/ddserver_ini.php new file mode 100644 index 0000000..2ee314e --- /dev/null +++ b/src/CALLEXT/ddserver_ini.php @@ -0,0 +1,23 @@ +<? +/** +* @file ddserver_ini.php +* @brief All DD Server External Data initialisations +*/ + + define("DDBASEBIN", getenv("DDBASEBIN")); + define("DDBASE", getenv("DDBASE")); + define("DDLIB", getenv("DDLIB")); + $old_include_path = set_include_path("./:".DDLIB); + /* + * Open STDERR stream + */ + $STDERR = fopen("php://stderr","w"); + + + if (!function_exists('__autoload')) { + function __autoload($class_name) { + require_once $class_name . '.php'; + } + } + +?> diff --git a/src/CALLEXT/ftpWrapper.php b/src/CALLEXT/ftpWrapper.php new file mode 100644 index 0000000..3bb49c8 --- /dev/null +++ b/src/CALLEXT/ftpWrapper.php @@ -0,0 +1,24 @@ +<?php +/** \file ftpWrapper.php +* \brief FTP Wrapper for FTP Servers passive +* +? +/*Wrapper to FTP - standard wrapper doesn't work in our case - we need passive mode */ +function ftpWrapper($ftp_server, $ftp_user_name, $ftp_user_pass, $server_file, $local_file) { + + try + { + $conn_id = ftp_connect($ftp_server); + $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass); + ftp_pasv($conn_id, true); + $ftp_get = ftp_get($conn_id, $local_file, $server_file, FTP_BINARY); + ftp_close($conn_id); + } + catch (Exception $e) + { + return false; + } + + + return $ftp_get; +} diff --git a/src/CALLEXT/getDataCDAWEB.php b/src/CALLEXT/getDataCDAWEB.php new file mode 100755 index 0000000..d99ed53 --- /dev/null +++ b/src/CALLEXT/getDataCDAWEB.php @@ -0,0 +1,103 @@ +<?php +/** +* @file getDataCDAWEB.php +* @version $Id: getDataCDAWEB.php,v 1.5 2009/08/26 09:32:40 budnik Exp $ +* @brief DD_Server tools <br> Gets Data from CDAWEB +* +* Args: remDataSetID ddVIdir StartTime StopTime \n +* Env Vars: $DDBASE $DDBASEBIN \n +* Executables: cdf2nc(DECODERS) TimesUpdate clean +* +* +* @todo General getData.php(dataBaseID) +*/ + +/*---------------------------------------------------------------------- + * DD SERVER TOOLS + * data update collection + * getDataCDAWEB.php + * php getDataCDAWEB.php <remDataSetID> <ddVIdir> <StartTime> <StopTime> + * 17 June 2007 V.1.0 + * 02 Aug 2007 V.1.1 + * 06 Aug 2007 V.1.2, cd to Data directory + * 23 Aug 2007 V.1.3, Another program for VI times update + * 23 Aug 2007 V.1.4, ZIP files before updating + * 23 Nov 2007 V.1.5 Copy LOCK file + * 21 jan 2008 V.1.6 Process all SOAP exceptions + * cut file names longer than 32 + *-----------------------------------------------------------------------*/ + +// Args + $id = $argv[1]; + $ViDir = $argv[2]; + $Start = $argv[3]; + $Stop = $argv[4]; +// Env variables + $DDBASEBIN = getenv("DDBASEBIN"); + $DDBASE = getenv("DDBASE"); + $MAX_NAME_LENGTH = 31; + $MAX_VI_NAME_LENGTH = 16; + + $wsdl = "http://cdaweb.gsfc.nasa.gov/WS/istp_public/jaxrpc?WSDL"; +// Opent STDERR stream + $STDERR = fopen("php://stderr","w"); + + try { + $client = new SoapClient($wsdl); + } + catch (SoapFault $exception) { + +fprintf($STDERR,"CDAWEB WSDL is unreachable \n"); + exit(0); + } + +// Stamp -> this directory is being updated + $LockName = $ViDir."/LOCK"; + touch($LockName); + +fprintf($STDERR,$ViDir." is LOCKED\n"); + + system("cd ".$ViDir."; ./clean"); +// If name is too long. + $nc_prefix = strlen($id) > $MAX_VI_NAME_LENGTH ? substr(strtolower($id),0,15): strtolower($id); + + try + { + $dataFileDesc = $client->__soapCall("getDataFiles", array($id, $Start, $Stop)); +fprintf($STDERR, "FILES GOT ".count($dataFileDesc)."\n"); + } + catch (SoapFault $exception) + { + unlink($LockName); + fprintf($STDERR, $exception."\n"); + exit(0); + } + if (count($dataFileDesc) > 0) + { + for ($i = 0; $i < count($dataFileDesc); $i++) { + $file = $dataFileDesc[$i]->name; + $fileArr = split("/",$file); +// fprintf($STDERR, $fileArr[count($fileArr)-1]."\n"); + if (copy($file, $fileArr[count($fileArr)-1])) { + system($DDBASEBIN."/cdf2nc ".$fileArr[count($fileArr)-1]); +fprintf($STDERR, "FILES TRANSLATED ".$i."\n"); + $ncFile = str_replace(".cdf", ".nc", $fileArr[count($fileArr)-1]); + unlink($fileArr[count($fileArr)-1]); + + $ncFileTrue = ($strLength = strlen($ncFile)) > $MAX_NAME_LENGTH ? + $nc_prefix."_".time().$i.".nc" : $ncFile; + + rename($ncFile,$ViDir."/".$ncFileTrue); + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdate -u ".strtolower($id)."_times.nc ".$ncFileTrue); +fprintf($STDERR, "TIMES IS UPDATED ".$i."\n"); + } + else fprintf($STDERR, $file." is not found\n"); + } + } + + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdateNoData ".strtolower($id)."_times.nc ".$argv[3]." ".$argv[4]); + unlink($LockName); +fprintf($STDERR, "UNLOCK \n"); + + +?> diff --git a/src/CALLEXT/getDataCDPP.php b/src/CALLEXT/getDataCDPP.php new file mode 100755 index 0000000..547da87 --- /dev/null +++ b/src/CALLEXT/getDataCDPP.php @@ -0,0 +1,119 @@ +<?php + +/** +* @file getDataCDPP.php +* @version $Id: getDataCDPP.php,v 1.4 2009/08/26 09:32:56 budnik Exp $ +* @brief DD_Server tools <br> Gets Data from CDPP +* +* Args: remDataSetID ddVIdir StartTime StopTime \n +* Env Vars: $DDBASE $DDBASEBIN \n +* Executables: TimesUpdate TimesUpdateNoData clean +* +* +* @todo General getData.php(dataBaseID) +*/ + +/*---------------------------------------------------------------------- + * DD SERVER TOOLS + * data update collection + * getDataCDPP.php + *-----------------------------------------------------------------------*/ + +// Args + $id = $argv[1]; + $ViDir = $argv[2]; + $Start = $argv[3]; + $Stop = $argv[4]; + + +// Env variables + $DDBASEBIN = getenv("DDBASEBIN"); + $DDBASE = getenv("DDBASE"); + $MAX_NAME_LENGTH = 31; + $MAX_VI_NAME_LENGTH = 16; + + $wsdl = "http://cdpp2.cesr.fr:8080/AMDA/services/AMDAServer?WSDL"; +// Opent STDERR stream + $STDERR = fopen("php://stderr","w"); + + define("restrictions", $DDBASE."/../INFO/CDPP_restrictions.xml"); + + try { + $client = new SoapClient($wsdl); + } + catch (SoapFault $exception) { + +fprintf($STDERR,"CDPP WSDL is unreachable \n"); + exit(-1); + } + +// Stamp -> this directory is being updated + $LockName = $ViDir."/LOCK"; + touch($LockName); + +fprintf($STDERR,$ViDir." is LOCKED\n"); + + system("cd ".$ViDir."; ./clean"); +// If name is too long.... + $nc_prefix = strlen($id) > $MAX_VI_NAME_LENGTH ? substr(strtolower($id),0,15): strtolower($id); + + +// If restrictions exists... + $dataset->parameters = null; + if (file_exists(restrictions)) { + $restrictionsDom = new DomDocument('1.0'); + $restrictionsDom -> load(restrictions); + + $dataSetRestrictions = $restrictionsDom->getElementById($id); + + if ($dataSetRestrictions != null) { + $parametres = $dataSetRestrictions->getElementsByTagName("PARAMETER_ID"); + foreach ($parametres as $parameter) { + $param_id = phpversion() >= "5.2.0" ? $parameter->getAttribute("xml:id") : $parameter->getAttribute("id"); + $dataset->parameters .= strtoupper($param_id)." "; + } + } + } + $dataset->datasetID = $id; + $dataset->timeStart = $Start; + $dataset->timeStop = $Stop; + try + { + $result = $client->__soapCall("getNcdfUrls", array($dataset)); + } + catch (SoapFault $exception) + { + unlink($LockName); + fprintf($STDERR, "EXCEPTION".$exception->faultstring."\n"); + exit(-1); + } + + $files = $result->getNcdfUrlsReturn; +fprintf($STDERR, "FILES GOT ".count($files)."\n"); + + if (count($files) > 0) + { + for ($i = 0; $i < count($files); $i++) { + $file = count($files) == 1 ? $files : $files[$i]; + $fileArr = split("/",$file); + $ncFile = $fileArr[count($fileArr)-1]; + $ncFileTrue = ($strLength = strlen($ncFile)) > $MAX_NAME_LENGTH ? + $nc_prefix."_".time().$i.".nc" : $ncFile; + + + if (copy($file,$ViDir."/".$ncFileTrue)) { + + if (strpos($ViDir, "CP_CIS_CODIF_HS_H1_MOMENTS") !== false) system("nc2nc ".$ViDir."/".$ncFileTrue); + + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdate -u ".strtolower($id)."_times.nc ".$ncFileTrue); +fprintf($STDERR, "TIMES IS UPDATED ".$i."\n"); + } + else fprintf($STDERR, $file." is not found\n"); + } + } + + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdateNoData ".strtolower($id)."_times.nc ".$argv[3]." ".$argv[4]); + unlink($LockName); +fprintf($STDERR, "UNLOCK \n"); + +?> diff --git a/src/CALLEXT/getDataMAPSKP.php b/src/CALLEXT/getDataMAPSKP.php new file mode 100644 index 0000000..9bd02cb --- /dev/null +++ b/src/CALLEXT/getDataMAPSKP.php @@ -0,0 +1,95 @@ +<?php +/** +* @file getDataMAPSKP.php +* @version $Id: getDataMAPSKP.php,v 1.6 2009/08/26 09:32:56 budnik Exp $ +* @brief DD_Server tools <br> Gets Data from MAPSKP +* +* Args: remDataSetID ddVIdir StartTime StopTime \n +* Env Vars: $DDBASE $DDBASEBIN \n +* Executables: ascii2nc(DECODERS) TimesUpdate TimesUpdateNoData clean +* +* +* @todo General getData.php(dataBaseID) +*/ + function name2DD($fileName) { + $pairs = array(".tab" => ".nc","__" => "_"); + return strtr(strtolower($fileName),$pairs) ; +} +// Args + $id = $argv[1]; + $ViDir = $argv[2]; + $Start = $argv[3]; + $Stop = $argv[4]; + +// Env variables + $DDBASEBIN = getenv("DDBASEBIN"); + $DDBASE = getenv("DDBASE"); + $MAX_NAME_LENGTH = 31; + $MAX_VI_NAME_LENGTH = 16; + +// MAPSKP STUFF + $passwd = "//amda:dd;mapskp@"; + $url = "http://planetoweb.cesr.fr/mapskp-amda/MapskpService.php?"; + + $args = array('service'=>'getDataUrl', + 'datasetId'=> $id, + 'dateBegin'=> strtr($Start,".000Z","Z"), + 'dateEnd'=> strtr($Stop,".000Z","Z")); + +// Open STDERR stream + $STDERR = fopen("php://stderr","w"); + +// Lock VI directory for Updating +// Stamp -> this directory is being updated + $LockName = $ViDir."/LOCK"; + touch($LockName); + +fprintf($STDERR,$ViDir." is LOCKED\n"); + +// Send - Receive query + $url .= http_build_query($args); + $fileList = new DOMDocument(); + $fileList->load($url); + + $Files = $fileList->getElementsByTagName("url"); + + fprintf($STDERR, "FILES RETURN ". $Files->length."\n"); + +// Clean VI directory + system("cd ".$ViDir."; ./clean"); +// If name is too long.... + $nc_prefix = strlen($id) > $MAX_VI_NAME_LENGTH ? substr(strtolower($id),0,15): strtolower($id); + + if ($Files->length > 0) { + for ($i = 0; $i < $Files->length; $i++) { + + copy($ViDir."/header.nc","temp.nc"); + $fileName_ = explode("//",$Files->item($i)->nodeValue); + $fileName = $fileName_[0].$passwd.$fileName_[1]; + $fileArr = split("/",$fileName); +// Copy URL file to DD_Server dir + $ok = copy($fileName, $fileArr[count($fileArr)-1]); + if ($ok) { +// Convert ascii TAB to nc using header.nc + system($DDBASEBIN."/ascii2nc ".$fileArr[count($fileArr)-1]); + fprintf($STDERR, "FILE $i TRANSLATED \n"); + unlink($fileArr[count($fileArr)-1]); + $ncFile = name2DD($fileArr[count($fileArr)-1]); +// Truncate file if it is too long + $ncFileTrue = ($strLength = strlen($ncFile)) > $MAX_NAME_LENGTH ? + $nc_prefix."_".time().$i.".nc" : $ncFile; +// Move nc file to VIdir + rename("temp.nc", $ViDir."/".$ncFileTrue); + +// Updates VI time info + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdate -u ".strtolower($id)."_times.nc ".$ncFileTrue); + } + } + fprintf($STDERR, "TIMES IS UPDATED \n"); + } + + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdateNoData ".strtolower($id)."_times.nc ".$argv[3]." ".$argv[4]); +// Unlock VI dir + unlink($LockName); + fprintf($STDERR, "UNLOCK \n"); +?> diff --git a/src/CALLEXT/getDataSKR.php b/src/CALLEXT/getDataSKR.php new file mode 100644 index 0000000..0e17ab8 --- /dev/null +++ b/src/CALLEXT/getDataSKR.php @@ -0,0 +1,80 @@ +<?php +/** +* @file getDataSKR.php +* @brief DD_Server tools <br> Gets Data from SKR +* +* @arg remDataSetID ddVIdir StartTime StopTime +* @arg Env Vars: $DDBASE $DDBASEBIN \n +* @arg Executables: skr2nc(DECODERS) TimesUpdate TimesUpdateNoData clean +* +* +* @todo General getData.php(dataBaseID) +* @version $Id: $ +* @date 20 june 2008 +*/ + +// Args + $id = $argv[1]; + $ViDir = $argv[2]; + $Start = $argv[3]; + $Stop = $argv[4]; + +// Env variables + $DDBASEBIN = getenv("DDBASEBIN"); + $DDBASE = getenv("DDBASE"); + $MAX_NAME_LENGTH = 31; + +// SKR STUFF + + $url = "http://rpwsTeam:KronoS04@www.lesia.obspm.fr/kronos/" + +// Open STDERR stream + $STDERR = fopen("php://stderr","w"); + +// Lock VI directory for Updating +// Stamp -> this directory is being updated + $LockName = $ViDir."/LOCK"; + touch($LockName); + +fprintf($STDERR,$ViDir." is LOCKED\n"); +// Send - Receive query + $url .= http_build_query($args); + $fileList = new DOMDocument(); + $fileList->load($url); + $Files = $fileList->getElementsByTagName("url"); + + fprintf($STDERR, "FILES RETURN ". $Files->length."\n"); + +// Clean VI directory + system("cd ".$ViDir."; clean"); + if ($Files->length > 0) { + for ($i = 0; $i < $Files->length; $i++) { + + copy($ViDir."/header.nc","temp.nc"); + $fileName_ = explode("//",$Files->item($i)->nodeValue); + $fileName = $fileName_[0].$passwd.$fileName_[1]; + $fileArr = split("/",$fileName); +// Copy URL file to DD_Server dir + copy($fileName, $fileArr[count($fileArr)-1]); +// Convert ascii TAB to nc using header.nc + system($DDBASEBIN."/ascii2nc ".$fileArr[count($fileArr)-1]); + fprintf($STDERR, "FILE $i TRANSLATED \n"); + unlink($fileArr[count($fileArr)-1]); + $ncFile = name2DD($fileArr[count($fileArr)-1]); +// Truncate file if it is too long + $ncFileTrue = ($strLength = strlen($ncFile)) > $MAX_NAME_LENGTH ? + "t".substr(substr($ncFile, 0, $strLength-3), $strLength-$MAX_NAME_LENGTH+1, $MAX_NAME_LENGTH-4).".nc" : $ncFile; +// Move nc file to VIdir + rename("temp.nc", $ViDir."/".$ncFileTrue); + +// Updates VI time info + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdate -u ".strtolower($id)."_times.nc ".$ncFileTrue); + } + fprintf($STDERR, "TIMES IS UPDATED \n"); + } + + system("cd ".$ViDir."; ".$DDBASEBIN."/TimesUpdateNoData ".strtolower($id)."_times.nc ".$argv[3]." ".$argv[4]); +// Unlock VI dir + unlink($LockName); + fprintf($STDERR, "UNLOCK \n"); +?> diff --git a/src/CALLEXT/getDataTHEMIS.php b/src/CALLEXT/getDataTHEMIS.php new file mode 100644 index 0000000..4caed41 --- /dev/null +++ b/src/CALLEXT/getDataTHEMIS.php @@ -0,0 +1,152 @@ +<?php +/** +* @file getDataTHEMIS.php +* @version $Id: getDataTHEMIS.php,v 1.7 2010/01/11 18:16:46 budnik Exp $ +* @brief DD_Server tools <br> Gets Data from /THEMIS_B1 (NFS) +* +* @arg remDataSetID ddVIdir StartTime StopTime \n +* Env Vars: $DDBASE $DDBASEBIN \n +* Executables: [DataSet]2nc(DECODERS) TimesUpdate TimesUpdateNoData clean +* +* +* @todo General getData.php(dataBaseID) +*/ + + + +// Open STDERR stream + $STDERR = fopen("php://stderr","w"); + +// Args + $id = $argv[1]; + + $ViDir = $argv[2]; + $Start = $argv[3]; + $Stop = $argv[4]; +// NFS direcory + define('ThemisDir', '/THEMIS_B1/themisdata/'); + define('DataSetDir', ThemisDir.strtr($id,"_","/")); +// Env variables + define('DDBASEBIN', getenv("DDBASEBIN")); + define('DDBASE', getenv("DDBASE")); + + + + $arr = explode("/", $ViDir); + $instrument = $arr[5]; + $mission = $arr[4]; + $mode = strpos($arr[6],"_") === false ? $arr[6] : substr($arr[6],0,4); + + + switch ($mode) { + case "psif" : + case "psef" : + case "peif" : + case "peef" : + case "peim" : + case "peem" : + case "h" : + case "l" : + $realDir = DDBASE."/".$mission."/".$instrument."/".$arr[6]."/"; + system("cd $realDir ; ./clean"); + touch($realDir."/LOCK"); +fprintf($STDERR,$realDir." is LOCKED\n"); + break; + case "peir" : + case "peer" : + case "peib" : + case "peeb" : + $dirAdd = array("/sp", "/mom"); + $fileAdd = array("s", ""); + $realDir = DDBASE."/".$mission."/".$instrument."/".$mode."/"; + for ($n = 0; $n < 2; $n++) { + $theDir = $realDir.$dirAdd[$n]; + system("cd $theDir ; ./clean "); + touch($theDir."/LOCK"); +fprintf($STDERR,$theDir." is LOCKED\n"); + } + break; + } + + + switch ($mode) { + case "peif" : + case "peef" : + $program = DDBASEBIN."/themis_esafull2nc "; + break; + case "peim" : + case "peem" : + $program = DDBASEBIN."/themis_esamom2nc "; + break; + case "peir" : + case "peer" : + case "peib" : + case "peeb" : + $program = DDBASEBIN."/themis_esa2nc "; + break; + case "psif" : + case "psef" : + $program = DDBASEBIN."/themis_sst2nc "; + break; + case "h" : + case "l" : + $program = DDBASEBIN."/themis_fgm2nc "; + break; + } +// fprintf($STDERR, "REALDIR ".$realDir." \n"); + +// Which files + $currTime = strtotime($Start); + $stopTime = strtotime($Stop); + + $currTime -= 3600.0; + + while ($currTime <= $stopTime) { + $fileName = DataSetDir."/".date('Y', $currTime)."/".$id."_".date('Ymd', $currTime)."_v01.cdf"; + + if (file_exists($fileName)) { + system($program." ".$fileName." ".$mission." ".$mode); + fprintf($STDERR, "FILE $fileName is TRANSLATED \n"); + + } + else { + fprintf($STDERR,"NO SUCH FILE $fileName \n"); + } + $currTime += 24*60*60; + } + + + switch ($mode) { + case "psif" : + case "psef" : + case "peif" : + case "peef" : + case "peim" : + case "peem" : + system("mv ".$mode."[0-9]*.nc $realDir"); + system("cd $realDir ;".DDBASEBIN."/TimesUpdate -u ".$mode."_times.nc ".$mode."[0-9]*.nc; ".DDBASEBIN."/TimesUpdateNoData ".$mode."_times.nc ".$argv[3]." ".$argv[4]); + unlink($realDir."/LOCK"); + break; + case "peir" : + case "peer" : + case "peib" : + case "peeb" : + for ($n = 0; $n < 2; $n++) { + $theDir = $realDir.$dirAdd[$n]; + system("mv ".$fileAdd[$n].$mode."[0-9]*.nc $theDir"); + system("cd $theDir ;".DDBASEBIN."/TimesUpdate -u ".$mode."_times.nc ".$fileAdd[$n].$mode."[0-9]*.nc; ".DDBASEBIN."/TimesUpdateNoData ".$mode."_times.nc ".$argv[3]." ".$argv[4]); + unlink($theDir."/LOCK"); + } + break; + case "h" : + case "l" : + system("mv fgm".$mode."[0-9]*.nc $realDir"); + system("cd $realDir ;".DDBASEBIN."/TimesUpdate -u fgm".$mode."_times.nc fgm".$mode."[0-9]*.nc; ".DDBASEBIN."/TimesUpdateNoData fgm".$mode."_times.nc ".$argv[3]." ".$argv[4]); + unlink($realDir."/LOCK"); + break; + } + + fprintf($STDERR, "TIMES IS UPDATED \n"); + + fprintf($STDERR, "UNLOCK \n"); +?> diff --git a/src/CALLEXT/getDataVEXGRAZ.php b/src/CALLEXT/getDataVEXGRAZ.php new file mode 100644 index 0000000..9033009 --- /dev/null +++ b/src/CALLEXT/getDataVEXGRAZ.php @@ -0,0 +1,90 @@ +<?php + +/** +* @file getDataVEXGRAZ.php +* @version $Id: getDataVEXGRAZ.php,v 1.4 2009/08/26 09:32:56 budnik Exp $ +* @brief DD_Server tools <br> Gets Data from VEXGRAZ +* +* @arg remDataSetID ddVIdir StartTime StopTime +* Env Vars: $DDBASE $DDBASEBIN \n +* Executables: ascii2nc(DECODERS) TimesUpdate TimesUpdateNoData clean +* +*/ + + require_once 'ddserver_ini.php'; + require_once 'vexgraz_ini.php'; + + function name2DD($fileName) { + + $ncName = prefix.substr($fileName,3,11).".nc"; + + return $ncName; +} + +/* +* Args +*/ + + $id = $argv[1]; + $ViDir = $argv[2]; + $Start = $argv[3]; + $Stop = $argv[4]; + +/* +* Lock VI directory for Updating +* Stamp -> this directory is being updated +*/ + $LockName = $ViDir."/LOCK"; + touch($LockName); + fprintf(STDERR,$ViDir." is LOCKED \n"); + + +/* +* Clean VI directory +*/ + system("cd ".$ViDir."; ./clean"); + +/* +* SPASE Web Service getDatasetUrl() +*/ + $mySpaseDataAccess = new DataAccessSpase(); + + $urlArray = $mySpaseDataAccess->getDatasetUrl($id, $Start, $Stop); + + if ($urlArray !== "NODATA") + foreach ($urlArray as $theUrl) { + + copy($ViDir."/header.nc","temp.nc"); + $fileArr = split("/",$theUrl); + $fileName = $fileArr[count($fileArr)-1]; +/* +* Copy URL file to DD_Server dir and +* Convert ascii TAB to nc using header.nc +*/ + copy($theUrl, $fileName); + system(DDBASEBIN."/ascii2nc ".$fileName." 1"); + fprintf(STDERR, "FILE $theUrl TRANSLATED \n"); + unlink($fileName); + $ncFile = name2DD($fileName); +/* +* Move new nc file to VIdir +*/ + rename("temp.nc", $ViDir."/".$ncFile); + +/* +* Updates VI time info +*/ + system("cd ".$ViDir."; ".DDBASEBIN."/TimesUpdate -u ".prefix."_times.nc ".$ncFile); + + fprintf(STDERR, "TIMES IS UPDATED \n"); + } +/* +* Fill NODATA times in VI time info +*/ + system("cd ".$ViDir."; ".DDBASEBIN."/TimesUpdateNoData ".prefix."_times.nc ".$argv[3]." ".$argv[4]); +/* +* Unlock VI dir +*/ + unlink($LockName); + fprintf(STDERR, "UNLOCK \n"); +?> diff --git a/src/CALLEXT/makeRPWS_KEYinfo.php b/src/CALLEXT/makeRPWS_KEYinfo.php new file mode 100644 index 0000000..2046031 --- /dev/null +++ b/src/CALLEXT/makeRPWS_KEYinfo.php @@ -0,0 +1,65 @@ +<?php +/* $Id: makeRPWS_KEYinfo.php,v 1.1 2008/03/05 14:04:22 elena Exp $ */ +/** +* \file makeRPWS_KEYinfo.php +* \brief Function to create energy info.nc for RPWS +* +*/ + + function makeRPWS_KEYinfo($StartTime) { + + $OK = false; + $E_PARAM = "ELECTRIC_SPECTRAL_DENSITIES"; + $M_PARAM = "MAGNETIC_SPECTRAL_DENSITIES"; + $OK = true; + $url = "http://planetoweb.cesr.fr/mapskp-amda/MapskpService.php?"; + $passwd = "//amda:dd;mapskp@"; + + $Stop = date("Y-m-d", strtotime("+10 days",strtotime($StartTime))); + + $args = array('service'=>'getDataUrl', + 'datasetId'=> "RPWS_KEY", + 'dateBegin'=> $StartTime."Z", + 'dateEnd'=> $Stop."T00:00:00Z"); + + + $url .= http_build_query($args); + $fileList = new DOMDocument(); + $fileList->load($url); + $Files = $fileList->getElementsByTagName("url"); + + if ($Files->length > 0) { + + $fileName_ = explode("//",$Files->item(0)->nodeValue); + $fileName = $fileName_[0].$passwd.$fileName_[1]; + $fileArr = split("/",$fileName); +// Copy URL file VI dir + copy($fileName, $fileArr[count($fileArr)-1]); + $file = fopen($fileArr[count($fileArr)-1], "r"); + $buffer = fgets($file); + $arrFreq = explode(" ", $buffer); + $Frequency_E = implode(",",array_slice($arrFreq,2,73)); + + $Frequency_M = implode(",",array_slice($arrFreq,75,42)); + + fclose($file); + unlink($fileArr[count($fileArr)-1]); + +// Create CDL ASCII file + $cdl = fopen("constant.cdl","w"); + fwrite($cdl, "netcdf header { \n \n dimensions: \n"); + fwrite($cdl," DIM_E = 73, DIM_M = 42; \n\n"); + + fwrite($cdl, "variables: \n"); + fwrite($cdl, " float ".$E_PARAM."(DIM_E), ".$M_PARAM."(DIM_M); \n\n"); + fwrite($cdl, ":units = \"Hz\"; \n"); + fwrite($cdl, "data: \n".$E_PARAM." = ".trim($Frequency_E).";\n".$M_PARAM." = ".trim($Frequency_M).";\n }"); + fclose($cdl); +// transform to nc + system("/usr/bin/ncgen -o rpws_key_constant.nc constant.cdl"); + $OK = true; + } + + return $OK; + } +?> diff --git a/src/CALLEXT/mapskp_cfg.php b/src/CALLEXT/mapskp_cfg.php new file mode 100644 index 0000000..3d8e05f --- /dev/null +++ b/src/CALLEXT/mapskp_cfg.php @@ -0,0 +1,5 @@ +<?php + + define("url","http://planetoweb2.cesr.fr/mapskp-amda/MapskpService.php?"); + define("passwd","ftp://amda:dd;mapskp@"); +?> diff --git a/src/DECODERS/ascii2nc/CMakeLists.txt b/src/DECODERS/ascii2nc/CMakeLists.txt new file mode 100644 index 0000000..cc3fba6 --- /dev/null +++ b/src/DECODERS/ascii2nc/CMakeLists.txt @@ -0,0 +1,24 @@ + +PROJECT(ascii2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (ascii2nc ${source_files} ) + +target_link_libraries( + ascii2nc + DD_Client + ${NETCDFLIBRARY} +) + +install (TARGETS ascii2nc DESTINATION bin) diff --git a/src/DECODERS/ascii2nc/ascii2nc.c b/src/DECODERS/ascii2nc/ascii2nc.c new file mode 100755 index 0000000..cdd30ac --- /dev/null +++ b/src/DECODERS/ascii2nc/ascii2nc.c @@ -0,0 +1,249 @@ + +/** @file ascii2nc.c +* @brief Stand alone executable to tranform ASCII to DD netCDF +* @version $Id: ascii2nc.c,v 1.8 2011/09/05 11:26:55 budnik Exp $ +* @arg FileName, [any symbol] +* 2 args => DOY2DDTime; 3 args => MonthDay2DDTime +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#include <math.h> +#include <DD.h> + +#define MAX_FILE_NAME_LEN 120 /* Max. file name length */ +#define MAXLEN 4096 + +/************************************* + Global variables and structures +**************************************/ +int ncid; /*netCDF file ID*/ + +char Time[TIMELENGTH]; +char *StartT; // Start time +char *StopT; // Stop time + +size_t TimeCount[2] = {1L, TIMELENGTH}; +size_t Start[2] = {0L, 0L}; +size_t buffCount[2]; + +/************************** + Function prototypes +**************************/ + +void handle_netcdf_error (int); +void mapskp2DD(char *buffer, char *Time); +void monthday2DD(char *buffer, char *Time); + +/**************************************************************************** + +*****************************************************************************/ +int main(int argc, char *argv[]) +{ + FILE *inFile; + int status, /* netCDF status code */ + dummy, i, j, n; + int ndims, nvars, ngatts, unlimitdimid; + int var_ndims, var_dims[NC_MAX_DIMS], var_natts; + nc_type var_type, t_type; + char var_name[NC_MAX_NAME+1]; + size_t dimsize, t_length; + int First = 1; + + char fileName[MAX_FILE_NAME_LEN]; + char *buffer, *tempBuff; + + float buffFloat[NC_MAX_DIMS][NC_MAX_DIMS], attFloat; + double buffDouble[NC_MAX_DIMS][NC_MAX_DIMS], attDouble; + int buffInt[NC_MAX_DIMS][NC_MAX_DIMS], attInt; + size_t buffSize[NC_MAX_DIMS]; + + nc_type buffType[NC_MAX_DIMS]; + + double deltaT, ddTime; + + buffer = (char *)malloc(MAXLEN*sizeof(char)); + tempBuff = buffer; + + buffCount[0] = 1L; + + if (argc <= 1) { + printf ("** inputFile file is not specified **\n"); /* input file name not specified */ + exit (1); + } + else { + strcpy(fileName, argv[1]); /* Get the input file name */ + } + + /***********************************************/ + /* Open Input File */ + /***********************************************/ + if ((inFile = fopen(fileName, "r")) == NULL) { + printf ("** Cannot open inputFile file: %s **\n", fileName); + exit (1); + } + + + status = nc_open("temp.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) { + handle_netcdf_error(status); + exit (1); + } + + +// Now inquire + + status = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimitdimid); + + // printf (" ndims %d, nvars %d, ngatts %d, unlimitdimid %d\n",ndims, nvars, ngatts, unlimitdimid); + + + for (i = 0; i < nvars; i++) { + + status = nc_inq_var(ncid, i, var_name, &var_type, &var_ndims, var_dims, &var_natts); + if (status != NC_NOERR) handle_netcdf_error(status); + // printf ("\n varname %s, var_type %d, var_ndims %d, var_natts %d ", + // var_name, var_type, var_ndims, var_natts); + if ( var_ndims == 1 ) buffSize[i] = 1; + else { + status = nc_inq_dimlen(ncid, var_dims[1], &dimsize); + buffSize[i] = dimsize; + } + buffType[i] = var_type; + } + + status = nc_inq_att(ncid, NC_GLOBAL, "minSampling", &t_type, &t_length); + if (status != NC_NOERR) deltaT = 0.0; + else + switch (t_type) { + case NC_FLOAT: status = nc_get_att_float(ncid, NC_GLOBAL, "minSampling", &attFloat); + deltaT = (double)(attFloat)/2.0 ; + break; + case NC_DOUBLE: status = nc_get_att_double(ncid, NC_GLOBAL, "minSampling", &attDouble); + deltaT = attDouble/2.0; + break; + case NC_INT: status = nc_get_att_int(ncid, NC_GLOBAL, "minSampling", &attInt); + deltaT = (double)attInt/2.0; + break; + default: status = nc_get_att_float(ncid, NC_GLOBAL, "minSampling", &attFloat); + deltaT = (double)(attFloat)/2.0 ; + } + // printf (" deltaT %lf\n", deltaT); + /*********************************************************************** + + ***********************************************************************/ +// Skip first line in RPWS_KEY.... + if (strncmp(fileName,"RPWS_KEY",8) == 0) fgets(buffer, MAXLEN, inFile); + + while (!feof(inFile) && !ferror(inFile)) { + + fgets(buffer, MAXLEN, inFile); + + if (strlen(buffer) > 10 && !feof(inFile)) { + + if (argc > 2) + monthday2DD(buffer, Time); + else + mapskp2DD(buffer, Time); + + status = nc_put_vara_text(ncid, 0, Start, TimeCount, Time); + + if (First) { + // add +/- deltaT from attribute.... + ddTime = DD_Time2Double(Time); + StartT = Double2DD_Time(ddTime - deltaT); + status = nc_put_vara_text(ncid, 1, &Start[1], &TimeCount[1], StartT); + } + First = 0; + +// Time variables are defined already + for (i = 3; i < nvars; i++) { + for (j = 0; j < buffSize[i]; j++) { + while (isspace(buffer[0])) buffer++; + buffer = strpbrk(buffer," "); + + switch (buffType[i]) { + case NC_FLOAT: sscanf(buffer, "%f", &buffFloat[i][j]); break; + case NC_DOUBLE: sscanf(buffer, "%lf", &buffDouble[i][j]); break; + case NC_INT: sscanf(buffer, "%d", &buffInt[i][j]); break; + default: sscanf(buffer, "%f", &buffFloat[i][j]); + } + + buffCount[1] = buffSize[i]; + + switch (buffType[i]) { + case NC_FLOAT: status = nc_put_vara_float(ncid, i, Start, buffCount, &(buffFloat[i][0])); + break; + case NC_DOUBLE: status = nc_put_vara_double(ncid, i, Start, buffCount, &(buffDouble[i][0])); + break; + case NC_INT: status = nc_put_vara_int(ncid, i, Start, buffCount, &(buffInt[i][0])); + break; + default: status = nc_put_vara_float(ncid, i, Start, buffCount, &(buffFloat[i][0])); + } + } + } + + Start[0]++; +// return pointer to the beginning + buffer = tempBuff; + } // if ! "\n" + } + // add +/- deltaT from attribute.... + ddTime = DD_Time2Double(Time); + StopT = Double2DD_Time(ddTime + deltaT - 1.0); + status = nc_put_vara_text(ncid, 2, &Start[1], &TimeCount[1], StopT); + + status = nc_close(ncid); + if (status != NC_NOERR) handle_netcdf_error(status); + fclose(inFile); +} + + + +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void handle_netcdf_error(int status) { + fprintf(stderr, "%s\n", nc_strerror(status)); +} +/*-------------------------------------------------------------------------- + * MAPSKP time to DD + *--------------------------------------------------------------------------*/ + void mapskp2DD(char *buffer, char *Time) { + int err; + int YEAR, DAY, HOUR, MINUTE, SEC, MSK = 0; + err = sscanf(buffer, "%d-%dT%d:%d:%d.%d", + &YEAR, &DAY, &HOUR, &MINUTE, &SEC, &MSK); + if (err == 5) MSK = 0; + sprintf(Time,"%04d%03d%02d%02d%02d%03d\0", YEAR, DAY-1, HOUR, MINUTE, SEC, MSK); +} +/*-------------------------------------------------------------------------- + * MONTH-DAY time to DD + *--------------------------------------------------------------------------*/ + void monthday2DD(char *buffer, char *Time) { + + int days[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + int i, YEAR, MONTH, DAY, HOUR, MINUTE, SEC, MSK, DOY=0; + + sscanf(buffer, "%d-%d-%dT%d:%d:%d.%d", + &YEAR, &MONTH, &DAY, &HOUR, &MINUTE, &SEC, &MSK); + + // Leap year + // if ((YEAR % 4 == 0) && (YEAR % 100 != 0)) days[1] += 1; + if (YEAR % 4 == 0) days[1] += 1; + // if (YEAR % 400 == 0) + // if (YEAR == 2000) days[1] += 1; + + // Sum of days from Jan 1 to the input date + for (i = 0; i < MONTH - 1; i++) DOY += days[i]; + DOY += DAY; + + sprintf(Time,"%04d%03d%02d%02d%02d%03d\0", YEAR, DOY-1, HOUR, MINUTE, SEC, MSK); +} + diff --git a/src/DECODERS/cdf2nc/CMakeLists.txt b/src/DECODERS/cdf2nc/CMakeLists.txt new file mode 100644 index 0000000..8213f69 --- /dev/null +++ b/src/DECODERS/cdf2nc/CMakeLists.txt @@ -0,0 +1,26 @@ + +PROJECT(cdf2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} + ${libcdf_INCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (cdf2nc ${source_files} ) + +target_link_libraries( + cdf2nc + DD_Client + ${NETCDFLIBRARY} + ${libcdf_LIBRARIES} +) + +install (TARGETS cdf2nc DESTINATION bin) diff --git a/src/DECODERS/cdf2nc/cdf2nc.c b/src/DECODERS/cdf2nc/cdf2nc.c new file mode 100755 index 0000000..4b4aa24 --- /dev/null +++ b/src/DECODERS/cdf2nc/cdf2nc.c @@ -0,0 +1,1616 @@ +/** +* @file cdf2nc.c +* @version $Id: cdf2nc.c,v 1.7 2014/06/25 10:32:50 budnik Exp $ +* @brief DD Server Decoder +*/ + +/*===================================================================== + * cdf2nc.c + * V.1.2 + * CDF to NetCDF converter + * usage: cdf2nc <FILE NAME>.cdf + * + * Versions: + * Aug 4, 2007, V.1.0, Knizhnikova-Fedorova + * Aug 6, 2007, V.1.1, Fedorov, "Time" dimension + * Jan 16, 2008 V.1.2 Exclude "false" CDF dimension (1) + *=====================================================================*/ + +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <cdf.h> +#include <string.h> +#include <time.h> +#include <math.h> +#include <DD.h> + +#define MAX_FILE_NAME_LEN 120 /* Max. file name length */ +#define MAX_ATTRS 3000 /* Max # of CDF attributes */ +#define UNKNOWN_DT -99 /* Unsupported CDF datatype indicator */ + +#define DEFAULT_MAPPING_FILE "cdf_to_netcdf_mapping.dat" +#define MAX_REC_LENGTH NC_MAX_NAME+CDF_ATTR_NAME_LEN+2 + /* Max record length of DEFAULT_MAPPING_FILE */ + +#define TRUE 1 +#define FALSE 0 + +#define TIMESHIFT 62167219200.0 /*01/01/1970 - 01/01/0000 Gregorian Calendar*/ +#define UNLIMITDIM "Time" /* Name of unlimided dimension */ +#define DD_TIME_STRING_LEN 17 + +/************************************* + Global variables and structures +**************************************/ +CDFid id; /* CDF file ID */ +int ncid; /* netCDF file ID */ + +short isTimeSet = 0; + +long nZvars, /* Number of zVariables in a CDF file */ + nAttrs; /* Number of attributes (global & variable) in a CDF file */ + +typedef struct ncdim { /* netCDF dimension structure */ + char name[NC_MAX_NAME+1]; /* Dimension name */ + int size; /* Dimension size */ + int id; /* Dimension id */ +} netcdfDimension; + +netcdfDimension ncDims[NC_MAX_DIMS]; /* max dimensions per netCDF file */ +int totNCdims = 0; /* Total # of netCDF dimensions created */ + +int StartTimeID, StopTimeID, TimeLengthID; + +char StartT[TIMELENGTH]; // Start time +char StopT[TIMELENGTH]; // Stop time + +dd_time_t StartTime, StopTime; + +typedef struct cdfvar { /* CDF variable structure */ + char name[CDF_VAR_NAME_LEN+1]; + long datatype; + long numElements; /* string length for CDF_CHAR, 1 otherwise */ + long dimensionality; /* variable dimensionality */ + long dimSizes[CDF_MAX_DIMS]; /* variable dimension sizes */ + long recVariance; /* record variance */ + long numRecs; /* # of records this variable contains */ +} CDFvar; + +char SpecialSymbol[9] = {' ', '#', '%', '@', '+', '.', '>', '<', '/'}; + +/**************************************************************************** + * Arrays to hold the CDF-to-netCDF mapping information that are loaded + * from the default or user-define mapping file. + ****************************************************************************/ +char netcdfAttrNames[MAX_ATTRS][NC_MAX_NAME]; +char cdfAttrNames[MAX_ATTRS][CDF_ATTR_NAME_LEN+1]; +char comments[MAX_ATTRS][CDF_ATTR_NAME_LEN+1]; + +int totAttrsInMappingFile; /* # of attributes in the mapping file */ +char mappingFile[MAX_FILE_NAME_LEN]; /* Mapping file name */ + +int DEBUG = FALSE; + + +/************************** + Function prototypes +**************************/ +int endsWith(char *, char *); +char * strlaststr(char *, char *); +void get_cdf_attribute(long, long, long, int); +void get_cdf_attr_data(char *, long, long, long, int); +char * cdf_str_datatype (long); +char * NC_datatype (nc_type); +nc_type get_netcdf_datatype (long); +void usage(); +CDFid cdf_open(char *); +void read_cdf_file_info(); +void get_zVariables(); +void create_netcdf_dimensions (CDFvar, int *, int *); +int create_netcdf_variable (CDFvar, int, short *); +void get_cdf_variable_data (long, CDFvar); +void read_cdf_variable_data (long, long, long, long, long [], void *); +void removeFilepath(); +void handle_netcdf_error (int); +void memory_error(char *, char *); +void cdf_status_handler (CDFstatus, char *); +void insufficient_memory(); /* used for debug */ +char * getNextArgument (int, char *[], int); +void parseCmdLine (int, char *[]); +void errorMsg (char *); +void map_CDF_attr_to_netCDF (char *, char *); +char * isotime_to_dd_time (char * str_isotime); + +/**************************************************************************** + NOTE: + + CDF has the following features that are not supported by netCDF: + + - CDF_EPOCH datatype (8-byte real number) that is used to store time + values referenced from a particular epoch that is + 01-Jan-0000 00:00:00.000. CDF_EPOCH values are the number of + milliseconds since the epoch described above. + + - CDF_EPOCH16 datatype (16-byte real number) that is used to store time + values referenced from a particular epoch that is + 01-Jan-0000 00:00:00.000.000.000.000. CDF_EPOCH16 values are the + number of milliseconds since the epoch described above. + + - CDF global attribute (not variable attribute) can have multiple + attribute entries and each entry can have a different datatype. +*****************************************************************************/ +int main(int argc, char *argv[]) +{ + FILE *inFile; /* Pointer to the CDF-to-netCDF mapping file */ + char rec[MAX_REC_LENGTH]; /* CDF-to-netCDF mapping record */ + + /************************/ + /* netCDF declaration */ + /************************/ + int status, /* netCDF status code */ + dummy, i; + + char *ptr, fileName[MAX_FILE_NAME_LEN]; + + /**********************/ + /* CDF declaration */ + /**********************/ + CDFstatus cstatus; /* CDF status code */ + long attrId; /* CDF attribute ID */ + + if (argc <= 1) + usage(); /* CDF input file name not specified */ + else { + strcpy(fileName, argv[argc-1]); /* Get the input file name */ + strcpy(mappingFile, "UNSPECIFIED"); + parseCmdLine(argc, argv); + if (strcmp(mappingFile, fileName) == 0) + errorMsg("** Error - either input file or mapping file is missing"); + if (strcmp(mappingFile,"UNSPECIFIED") == 0) + { + strcpy(mappingFile,getenv("DDLIB")); + strcat(mappingFile, DEFAULT_MAPPING_FILE); + } + } + + /***********************************************/ + /* Load the CDF-to-netCDF mapping information */ + /***********************************************/ + if ((inFile = fopen(mappingFile, "r")) == NULL) { + printf ("** Cannot open file: %s **\n", mappingFile); + exit (1); + } + + totAttrsInMappingFile = 0; + while (fgets(rec, MAX_REC_LENGTH, inFile) != NULL) { + rec[strlen(rec)-1] = '\0'; /* Remove the newline character */ + + /* Process the mapping record if it's not a comment */ + if (rec[0] != '#' && rec[0] != ' ' && strlen(rec) > 0) { + sscanf(rec, "%s %s", + netcdfAttrNames[totAttrsInMappingFile], + cdfAttrNames[totAttrsInMappingFile]); + ptr = (char *) strstr(rec, "//"); + if (ptr != NULL) { + ptr += 3; + strcpy (comments[totAttrsInMappingFile], ptr); + + } + if (DEBUG) + printf("%s %s %s\n", + netcdfAttrNames[totAttrsInMappingFile], + cdfAttrNames[totAttrsInMappingFile], + comments[totAttrsInMappingFile]); + totAttrsInMappingFile++; + } + } + + /*********************************************************** + * Process the CDF information and create a netCDF file + ***********************************************************/ + // printf ("\nInput file name: %s\n", fileName); + id = cdf_open (fileName); + + /* Remove the file path if it exists (/home/mydata.cdf => mydata.cdf). */ + removeFilepath(fileName); + + if (endsWith(fileName,".cdf")) { + /* Strip off the .cdf file extension. */ + ptr = (char *) strlaststr(fileName, ".cdf"); + if (ptr != NULL) *ptr = '\0'; + } + strcat(fileName, ".nc"); + status = nc_create(fileName, NC_CLOBBER, &ncid); + if (status != NC_NOERR) handle_netcdf_error(status); + // printf ("Output file name: %s\n", fileName); + + /*********************************************************************** + * Get the number of dimensions, number of variables, number of global + * attributes. + * + * Note that the information retrieved from read_cdf_file_info are stored + * into the global variables defined at the top. + ***********************************************************************/ + read_cdf_file_info (); + if (DEBUG) printf ("nAttrs=%d, nZvars=%d\n", nAttrs, nZvars); + + /* Get the CDF global attributes and create netCDF global attributes. */ + if (DEBUG) printf ("Global attributes:\n"); + dummy = -1; + for (attrId = 0; attrId < nAttrs; attrId++) + get_cdf_attribute(attrId, GLOBAL_SCOPE, (long) dummy, dummy); + + /* Write the placeholder attributes. */ + for (i=0; i < totAttrsInMappingFile; i++) { + if (strcmp(cdfAttrNames[i],"*") == 0) { + status = nc_put_att_text (ncid, + NC_GLOBAL, /* vavriable ID */ + netcdfAttrNames[i], /* Attribute name */ + strlen(comments[i]), /* # of attr values */ + comments[i]); + } + } + + /* Process CDF variables and create netCDF variables */ + if (nZvars > 0) get_zVariables(); + + /* Close the netCDF and CDF files */ + cstatus = CDFlib (CLOSE_, CDF_, NULL_); + if (cstatus != CDF_OK) cdf_status_handler (cstatus, "CLOSE_, CDF_"); + + status = nc_close(ncid); + if (status != NC_NOERR) handle_netcdf_error(status); +} + + +/*---------------------------------------------------------------------------- + * TRUE if s1 ends with s2. Otherwise, FALSE is returned. + *---------------------------------------------------------------------------*/ +int endsWith (char *s1, char *s2) +{ + int i; + char *ps1, *ps2; + + if (strlen(s2) > strlen(s1)) + return FALSE; + + ps1 = s1 + strlen(s1) - strlen(s2); + ps2 = s2; + + for (i=0; i < strlen(s2); i++) + if (*(ps1++) != *(ps2++)) + return FALSE; + + return TRUE; +} + + +/*--------------------------------------------------------------------------------- + * Find the last occurence of s2 in s1. If s21 is not found, s1 is returned. + *--------------------------------------------------------------------------------*/ +char * strlaststr (char *s1, char *s2) +{ + char *sc2, *psc1, *ps1; + + if (*s2 == '\0') + return((char *)s1); + + ps1 = s1 + strlen(s1); + + while(ps1 != s1) { + --ps1; + for (psc1 = ps1, sc2 = s2; ; ) + if (*(psc1++) != *(sc2++)) + break; + else if (*sc2 == '\0') + return ((char *)ps1); + } + return ((char *)NULL); +} + + +/*-------------------------------------------------------------------------- + * This routine opens a CDF file + *-------------------------------------------------------------------------*/ +CDFid cdf_open (char *fileName) +{ + CDFstatus status; + CDFid id; + char msg[80]; + + status = CDFlib (OPEN_, CDF_, fileName, /* in - file name to be opened */ + &id, /* out - CDF file ID */ + NULL_); + if (status != CDF_OK) { + strcpy(msg, "OPEN_, CDF_, "); + strcat(msg, fileName); + cdf_status_handler (status, msg); + } + return id; +} + + +/*--------------------------------------------------------------------------- + * This routine retrievs the following information: + * + * nAttr - number of attributes (including global and variable) + * nZvars - number of zVariables + * + * CDF file can have both rVariables (old style) and zVariables (new style) + * simultaneously. zVariable is a superset of rVariable, and it is a lot + * more efficient and offers all the functionality a rVariable offers and + * more. Treat all CDF variables as zVariables. + *--------------------------------------------------------------------------*/ +void read_cdf_file_info () +{ + CDFstatus status; + + status = CDFlib (SELECT_, CDF_zMODE_, zMODEon2, + GET_, CDF_NUMATTRS_, &nAttrs, + CDF_NUMzVARS_, &nZvars, + NULL_); + if (status != CDF_OK) cdf_status_handler (status, "GET_, CDF_FILEINFO_"); +} + + +/*---------------------------------------------------------------------------- + * This routine retrieves the CDF attribute (global or variable) name + * and its data for the given CDF attribute ID. + *---------------------------------------------------------------------------*/ +void get_cdf_attribute(long attrNum, /* in - CDF attribute number/id */ + long scope, /* in - CDF attribute scope */ + long cdfVarId, /* in - CDF variable number/id */ + int netcdfVarId) /* in - netCDF variable ID */ +{ + int ncstatus, i, len; + long status, numEntries, datatype, attrScope, entryNum, + numElements; + nc_type ncDatatype; /* netCDF datatype */ + + char *cPtr, attrName[CDF_ATTR_NAME_LEN+1], + mappedAttrName[CDF_ATTR_NAME_LEN+1]; + signed char *scPtr; + short *sPtr; + int *iPtr; + float *fPtr; + double *dPtr; + + status = CDFlib (SELECT_, ATTR_, attrNum, + GET_, ATTR_NAME_, attrName, + ATTR_SCOPE_, &attrScope, + NULL_); + if (status != CDF_OK) cdf_status_handler (status, "SELECT_, ATTR_"); + + /****************************************************************/ + /* If the attribute scope is not the requested attribute scope */ + /* (VARIABLE_SCOPE or GLOBAL_SCOPE), do not process the current */ + /* attribute. */ + /****************************************************************/ + if (attrScope != scope) return; + + map_CDF_attr_to_netCDF(attrName, mappedAttrName); + strcpy(attrName, mappedAttrName); + + if (attrScope == GLOBAL_SCOPE) { + status = CDFlib (GET_, ATTR_NUMgENTRIES_, &numEntries, NULL_); + if (status != CDF_OK) + cdf_status_handler (status, "GET_, ATTR_NUMgENTRIES_"); + if (DEBUG) printf ("\t%s", attrName); + + /********************************************************************* + * While the CDF global attribute can have multiple entries of + * of different datatypes, the CDF variable attribute can only have + * one attribute entry. netCDF doesn't allow more than 1 attribute + * entry - handle this case + ********************************************************************/ + for (entryNum=0; entryNum < numEntries; entryNum++) { + if (entryNum > 0) /* Attribute has more than 1 entry */ + sprintf (attrName, "%s_%d", mappedAttrName, entryNum); + status = CDFlib (SELECT_, gENTRY_, entryNum, + GET_, gENTRY_DATATYPE_, &datatype, + gENTRY_NUMELEMS_, &numElements, + NULL_); + if (status == NO_SUCH_ENTRY) return; + if (status != CDF_OK) cdf_status_handler(status,"GET_ATTR_INFO_"); + get_cdf_attr_data (attrName, gENTRY_DATA_, datatype, numElements, + netcdfVarId); + } + } + else { + /********************************************************************* + * IMPORTANT NOTE: + * For the variable attribute, entry number is the variable ID. + *********************************************************************/ + status = CDFlib (SELECT_, zENTRY_, cdfVarId, + GET_, zENTRY_DATATYPE_, &datatype, + zENTRY_NUMELEMS_, &numElements, + NULL_); + /******************************************************************/ + /* If there's no attribute entry for the current attribute number */ + /* selected, process the next attribute. */ + /******************************************************************/ + if (status == NO_SUCH_ENTRY) return; + + if (status != CDF_OK) cdf_status_handler (status,"GET_ATTR_INFO_"); + if (DEBUG) printf ("\t%s", attrName); + get_cdf_attr_data (attrName, zENTRY_DATA_, datatype, numElements, + netcdfVarId); + } +} + + +/*-------------------------------------------------------------------------- + * This routine retrieves the CDF attribute data (a.k.a. attribute entries) + * and write its values to the target netCDF file. + *--------------------------------------------------------------------------*/ +void get_cdf_attr_data (char *attrName, /* in - attribute name */ + long entryData, /* in - type of attr entry data */ + long datatype, /* in - attribute datatype */ + long numElements, /* in - # of attribute values */ + int netcdfVarId) /* in - netCDF variable ID */ +{ + char entryDataType[20], msg[100], + epString[EPOCH_STRING_LEN+1], + ep16String[EPOCH16_STRING_LEN+1]; + double epoch16[2]; + + nc_type ncDatatype; /* netCDF datatype */ + int nc_status, /* netCDF status code */ + varId; /* netCDF variable ID */ + long status; /* CDF status code */ + + char *cPtr; + signed char *scPtr; + short *sPtr; + int *iPtr, i; + float *fPtr; + double *dPtr; + + /************************************************* + * entryData has one of following values: + * + * gENTRY_DATA_ - global attribute entry + * rENTRY_DATA_ - rVariable attribute entry + * zENTRY_DATA_ - zVariable attribute entry + *************************************************/ + if (entryData == gENTRY_DATA_) { + varId = NC_GLOBAL; + strcpy(entryDataType, "gENTRY_DATA_"); + } + else { + varId = netcdfVarId; + strcpy(entryDataType, "zENTRY_DATA_"); + } + strcpy (msg, "get_cdf_attr_data, GET_, "); + strcat (msg, entryDataType); + strcat (msg, cdf_str_datatype(datatype)); + + /* Map the CDF datatype to an appropriate netCDF datatype. */ + ncDatatype = get_netcdf_datatype (datatype); + + /* Remove trailing blank spaces if there are any */ + for (i=strlen(attrName)-1; i >= 0; i--) { + if (attrName[i] != ' ') { + attrName[i+1] = '\0'; + break; + } + } + /* Replace blanks space(s) with underscore(s). */ + for (i=0; i < strlen(attrName); i++) { + if (attrName[i] == ' ') attrName[i] = '_'; + } + + switch (datatype) { + case CDF_CHAR: + cPtr = (char *) malloc(numElements * sizeof(char) + 1); + if (cPtr == NULL) memory_error("get_cdf_attr_data", "NC_CHAR"); + status = CDFlib (GET_, entryData, cPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + *(cPtr+numElements) = '\0'; /* End of string mark */ + if (DEBUG) printf (" = \"%s\"", cPtr); + nc_status = nc_put_att_text(ncid, varId, attrName, numElements, cPtr); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + free(cPtr); + break; + + case CDF_BYTE: + case CDF_INT1: + scPtr = (signed char *) malloc (sizeof(signed char) * numElements); + if (scPtr == NULL) memory_error("get_cdf_attr_data", "NC_BYTE"); + status = CDFlib (GET_, entryData, scPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) { + printf (" = "); + for (i=0; i < numElements; i++) { + if (i > 0) printf (", "); + printf ("%d", *(scPtr+i)); + } + } + nc_status = nc_put_att_schar(ncid, varId, attrName, ncDatatype, + numElements, scPtr); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + free (scPtr); + break; + + case CDF_INT2: + case CDF_UCHAR: + case CDF_UINT1: + sPtr = (short *) malloc (sizeof(short) * numElements); + if (sPtr == NULL) memory_error("get_cdf_attr_data", "NC_SHORT"); + status = CDFlib (GET_, entryData, sPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) { + printf (" = "); + for (i=0; i < numElements; i++) { + if (i > 0) printf (", "); + printf ("%d", *(sPtr+i)); + } + } + nc_status = nc_put_att_short(ncid, varId, attrName, ncDatatype, + numElements, sPtr); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + free (sPtr); + break; + + case CDF_INT4: + case CDF_UINT2: + iPtr = (int *) malloc (sizeof(int) * numElements); + if (iPtr == NULL) memory_error("get_cdf_attr_data", "NC_INT"); + status = CDFlib (GET_, entryData, iPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) { + printf (" = "); + for (i=0; i < numElements; i++) { + if (i > 0) printf (", "); + printf ("%d", *(iPtr+i)); + } + } + nc_status = nc_put_att_int(ncid, varId, attrName, ncDatatype, + numElements, iPtr); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + free (iPtr); + break; + + case CDF_FLOAT: + case CDF_REAL4: + fPtr = (float *) malloc (sizeof(float) * numElements); + if (fPtr == NULL) memory_error("get_cdf_attr_data", "NC_FLOAT"); + status = CDFlib (GET_, entryData, fPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) { + printf (" = "); + for (i=0; i < numElements; i++) { + if (i > 0) printf (", "); + printf ("%g", *(fPtr+i)); + } + } + nc_status = nc_put_att_float(ncid, varId, attrName, ncDatatype, + numElements, fPtr); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + free (fPtr); + break; + + case CDF_DOUBLE: + case CDF_REAL8: + case CDF_UINT4: + dPtr = (double *) malloc (sizeof(double) * numElements); + if (dPtr == NULL) memory_error("get_cdf_attr_data", "NC_DOUBLE"); + status = CDFlib (GET_, entryData, dPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) { + printf (" = "); + for (i=0; i < numElements; i++) { + if (i > 0) printf (", "); + printf ("%g", *(dPtr+i)); + } + } + nc_status = nc_put_att_double(ncid, varId, attrName, + ncDatatype, numElements, dPtr); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + free (dPtr); + break; + + case CDF_EPOCH: /* 8-byte real number */ + dPtr = (double *) malloc (sizeof(double) * numElements); + if (dPtr == NULL) memory_error("get_cdf_attr_data", "CDF_EPOCH"); + status = CDFlib (GET_, entryData, dPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) printf (" = "); + for (i=0; i < numElements; i++) { + encodeEPOCH (*(dPtr+i), epString); + nc_status = nc_put_att_text(ncid, varId, attrName, + EPOCH_STRING_LEN, epString); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + if (DEBUG) { + if (i > 0) printf (", "); + printf (epString); + } + } + free (dPtr); + break; + + case CDF_EPOCH16: /* 16-byte real number */ + dPtr = (double *) malloc (sizeof(double) * numElements * 2); + if (dPtr == NULL) memory_error("get_cdf_attr_data", "CDF_EPOCH16"); + status = CDFlib (GET_, entryData, dPtr, NULL_); + if (status != CDF_OK) cdf_status_handler (status, msg); + if (DEBUG) printf (" = "); + for (i=0; i < numElements; i++) { + epoch16[0] = *(dPtr+i*2); + epoch16[1] = *(dPtr+i*2+1); + encodeEPOCH16 (epoch16, ep16String); + nc_status = nc_put_att_text(ncid, varId, attrName, + strlen(ep16String), ep16String); + if (nc_status != NC_NOERR) handle_netcdf_error(nc_status); + if (DEBUG) { + if (i > 0) printf (", "); + printf (ep16String); + } + } + free (dPtr); + break; + + default: + printf ("** Error in get_cdf_attribute: bad data type"); + } + if (DEBUG) printf (" ;\n"); +} + + +/*-------------------------------------------------------------------------- + * Get the zVariables in the CDF file. + *--------------------------------------------------------------------------*/ +void get_zVariables() +{ + CDFstatus status; + int i, ncstatus, createUnlimitedDim, unlimitedDimId, + attrId, netcdfVarId; + char netcdfDimName[NC_MAX_NAME+1]; /* netCDF dimension name */ + long holdDim, holdDim0; + long varId, + recInterval, /* No. of recors to skip */ + dimIndices[CDF_MAX_DIMS], /* Beginning location of the array */ + /* to be dumped */ + dimIntervals[CDF_MAX_DIMS]; /* No. of elements to skip */ + CDFvar var; + size_t start[NC_MAX_DIMS], /* index for where to read first */ + count[NC_MAX_DIMS]; /* # of values to read */ + short timeDefined = 0; + + if (DEBUG) printf ("\n"); + + createUnlimitedDim = TRUE; + + for (varId=0; varId < nZvars; varId++) { + status = CDFlib (SELECT_,zVAR_, varId, + GET_, zVAR_NAME_, var.name, + zVAR_DATATYPE_, &var.datatype, + zVAR_NUMELEMS_, &var.numElements, + zVAR_NUMDIMS_, &var.dimensionality, + zVAR_DIMSIZES_, var.dimSizes, + zVAR_NUMRECS_, &var.numRecs, + zVAR_RECVARY_, &var.recVariance, + NULL_); + if (status != CDF_OK) cdf_status_handler (status, "GET_, zVARS_"); + + if (DEBUG) { + printf ("\nvar name = %s, %s/%d, %d:[", + var.name, cdf_str_datatype(var.datatype), + var.numElements, var.dimensionality); + for (i=0; i < var.dimensionality; i++) { + if (i > 0) printf (","); + printf ("%d", var.dimSizes[i]); + } + printf("], numRecs = %d\n", var.numRecs); + } + + create_netcdf_dimensions (var, &createUnlimitedDim, &unlimitedDimId); + + + netcdfVarId = create_netcdf_variable (var, unlimitedDimId, &timeDefined); + + /* Leave the define mode before adding data */ + ncstatus = nc_enddef(ncid); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + + get_cdf_variable_data (varId, var); + + /* Enter the define mode before writing netCDF variable attributes */ + /* and creating a variable. */ + ncstatus = nc_redef(ncid); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + + /* Get the variable attributes */ + for (attrId = 0; attrId < nAttrs; attrId++) + get_cdf_attribute(attrId, VARIABLE_SCOPE, varId, netcdfVarId); + } +// DD Variables + nc_def_dim (ncid, "TimeLength", TIMELENGTH, &TimeLengthID); + nc_def_var (ncid, "StartTime", NC_CHAR, 1, &TimeLengthID, &StartTimeID); + nc_def_var (ncid, "StopTime", NC_CHAR, 1, &TimeLengthID, &StopTimeID); + ncstatus = nc_enddef(ncid); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + start[0] = 0L; + start[1] = 0L; + count[0]= 1L; + count[1] = TIMELENGTH; + ncstatus = nc_put_vara_text(ncid, StartTimeID, &start[1], &count[1], StartTime); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + ncstatus = nc_put_vara_text(ncid, StopTimeID, &start[1], &count[1], StopTime); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); +} + + +/*-------------------------------------------------------------------------- + * This routine creates a netCDF dimension. + *--------------------------------------------------------------------------*/ +void create_netcdf_dimensions (CDFvar var, + int *createUnlimitedDim, + int *unlimitedDimId) +{ + int status, /* netCDF status code */ + i, j, dimensionCreated; + long dimensionality; + char netcdfDimName[NC_MAX_NAME+1]; /* netCDF dimension name */ + + if (*createUnlimitedDim) { + if (var.recVariance == VARY) { + status = nc_def_dim(ncid, UNLIMITDIM, NC_UNLIMITED,unlimitedDimId); + if (status != NC_NOERR) handle_netcdf_error(status); + *createUnlimitedDim = FALSE; + } + } + + dimensionality = var.dimensionality; + + if (var.datatype == CDF_CHAR) { + var.dimSizes[dimensionality] = var.numElements; + dimensionality++; + } + else if (var.datatype == CDF_EPOCH) { + var.dimSizes[dimensionality] = TIMELENGTH; //EPOCH_STRING_LEN; + dimensionality++; + } + else if (var.datatype == CDF_EPOCH16) { + var.dimSizes[dimensionality] = TIMELENGTH; //EPOCH16_STRING_LEN; + dimensionality++; + } + + for (i=0; i < dimensionality; i++) { + dimensionCreated = FALSE; + for (j=0; j < totNCdims; j++) { + if (ncDims[j].size == var.dimSizes[i]) { + dimensionCreated = TRUE; + break; + } + } + if (!dimensionCreated && var.dimSizes[i] > 1) { + ncDims[totNCdims].size = var.dimSizes[i]; + sprintf (netcdfDimName, "dim%d", totNCdims); + strcpy(ncDims[totNCdims].name, netcdfDimName); + status = nc_def_dim(ncid, /* in */ + ncDims[totNCdims].name, /* in */ + ncDims[totNCdims].size, /* in */ + &ncDims[totNCdims].id); /* out */ + if (status != NC_NOERR) handle_netcdf_error(status); + totNCdims++; + } + } +} + + +/*-------------------------------------------------------------------------- + * This routine creates a netCDF variable. + *--------------------------------------------------------------------------*/ +int create_netcdf_variable (CDFvar var, /* in - CDF variable */ + int unlimitedDimId, short *timeDefined) /* in - unlimited dim ID */ +{ + int status, /* netCDF status code */ + i, j, k, ii, + varId, /* netCDF variable ID */ + dimensionality, /* netCDF dimensionality */ + dims[NC_MAX_DIMS]; /* netCDF dimensions */ + nc_type datatype; + + int nc_dimensionality, nc_dims[NC_MAX_DIMS]; + char ourTime[]={"Time\0"}; + + dimensionality = var.dimensionality; + datatype = get_netcdf_datatype (var.datatype); + + /********************************************************************* + * While the string value is treated as 0-d in CDF, it is treated as + * 1-D in netCDF. + *********************************************************************/ + if (var.datatype == CDF_CHAR) { + var.dimSizes[dimensionality] = var.numElements; + dimensionality++; + } + + /********************************************************************* + * In CDF, CDF_EPOCH and CDF_EPOCH16 are used to store a date and time + * value into a 8-byte and 16-byte real value, respectively. Since netCDF + * doesn't support EPOCH, the CDF EPOCH variable needs to be translated + * as a string value. + *********************************************************************/ + else if ((var.datatype == CDF_EPOCH) && (! *timeDefined)) { + + *timeDefined = 1; + var.dimSizes[dimensionality] = TIMELENGTH;//EPOCH_STRING_LEN; + strcpy(var.name, ourTime); + dimensionality++; + } + else if (var.datatype == CDF_EPOCH16) { + var.dimSizes[dimensionality] = TIMELENGTH;//EPOCH16_STRING_LEN; + strcpy(var.name, ourTime); + dimensionality++; + } + + /************************************************************************ + * If CDF's record variance is true, then the netCDF's first dimension + * reflects the record number. + ************************************************************************/ + k = 0; + if (var.recVariance == VARY) { + dims[k++] = unlimitedDimId; + dimensionality++; + } + + for (i=0; i < dimensionality; i++) { + for (j=0; j < totNCdims; j++) { + if (ncDims[j].size == var.dimSizes[i]) { + dims[k++] = ncDims[j].id; + break; + } + } + } + + /* Remove trailing blank spaces if there are any */ + for (i=strlen(var.name)-1; i >= 0; i--) { + if (var.name[i] != ' ') { + var.name[i+1] = '\0'; + break; + } + } + + + /* Replace special symbols with underscore(s). */ + for (ii=0; ii < 9; ii++) + for (i=0; i < strlen(var.name); i++) { + if (var.name[i] == SpecialSymbol[ii]) { + var.name[i] = '_'; + } + } + + +/* Exclude "false" dimension */ + nc_dimensionality = dimensionality; + for (i=0; i < dimensionality; i++) { + if ( var.dimSizes[i] == 1 ) { + nc_dimensionality--; + j = i; + break; + } + } + /* Create a netCDF variable. */ + + status = nc_def_var(ncid, var.name, datatype, nc_dimensionality, dims, &varId); + + if (status != NC_NOERR) handle_netcdf_error(status); + + return varId; +} + + +/*-------------------------------------------------------------------------- + * Get the CDF variable data and write the data just read into the + * netCDF variable created in create_netcdf_variable. + *--------------------------------------------------------------------------*/ +void get_cdf_variable_data (long varId, /* in - variable ID/number */ + CDFvar var) /* in - CDF variable structure */ +{ + CDFstatus status; /* CDF status code */ + int ncstatus; /* netCDF status code */ + char epString[EPOCH_STRING_LEN+1]; + char ep16String[EPOCH16_STRING_LEN+1]; + + double epoch16[2]; + + size_t start[NC_MAX_DIMS], /* index for where to read first */ + count[NC_MAX_DIMS]; /* # of values to read */ + + int i, j, k, divide, + dimensionality, + numValues; /* # of values on each record */ + + int nc_dimensionality, + nc_dimSizes[NC_MAX_DIMS]; + + char *cPtr; + signed char *scPtr; + short *sPtr; + int *iPtr; + float *fPtr; + double *dPtr; + long recNo, + totRecs, /* total # of records to read */ + numRecsLeftToRead, + numRecs; /* # of records to read and write at a time */ + + dd_time_t curTime; + + j = 0; + start[0] = 0; + numValues = 1; /* # of values on each CDF record */ + + if (var.recVariance == VARY) { /* Treat it as a netCDF record variable */ + start[j] = 0; /* start record # */ + count[j++] = var.numRecs; /* # of records to write */ + } + + dimensionality = var.dimensionality; + + if (var.datatype == CDF_CHAR) { + var.dimSizes[dimensionality] = var.numElements; + dimensionality++; + } + + /********************************************************************* + * In CDF, CDF_EPOCH and CDF_EPOCH16 are used to store a date and time + * value into a 8-byte and 16-byte real value, respectively. Since netCDF + * doesn't support EPOCH, the CDF EPOCH variable needs to be translated + * as a string value. + *********************************************************************/ + else if (var.datatype == CDF_EPOCH) { + var.dimSizes[dimensionality] = TIMELENGTH; + dimensionality++; + } + else if (var.datatype == CDF_EPOCH16) { + var.dimSizes[dimensionality] = TIMELENGTH; + dimensionality++; + } + + for (i=0; i < dimensionality; i++) { + start[j] = 0; + if (var.dimSizes[i] > 1) count[j++] = var.dimSizes[i]; + numValues *= var.dimSizes[i]; + } + + if (var.datatype == CDF_EPOCH) + numValues /= TIMELENGTH; + else if (var.datatype == CDF_EPOCH16) + numValues /= TIMELENGTH; + + totRecs = var.numRecs; /* total # of records for this var */ + numRecsLeftToRead = var.numRecs; + + while (numRecsLeftToRead > 0) { + recNo = start[0]; /* record # to start reading */ + divide = 1; + numRecs = numRecsLeftToRead; /* # of records to read at a time */ + + switch (var.datatype) { + case CDF_CHAR: + cPtr = NULL; + while (cPtr == NULL) { + cPtr = (char *) malloc (sizeof(char) * numValues * numRecs); + if (cPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + cPtr); /* data pointer */ + if (DEBUG) { + printf (" retrieved CDF data = \n"); + for (k=0; k < numRecs; k++) { + printf("\""); + for (i=0; i < numValues; i++) + printf ("%c", *(cPtr+(k*numValues+i))); + printf("\"\n"); + } + } + + start[0] = 0; + start[1] = 0; + if (var.recVariance == VARY) { + count[0] = numRecs; + } + + if (DEBUG) { + for (i=0; i < dimensionality; i++) + printf (" start[%d] = %d, count[%d] = %d\n", + i, start[i], i, count[i]); + } + ncstatus = nc_put_vara_text(ncid, varId, start, count, cPtr); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + if (DEBUG && ncstatus != NC_NOERR) { + if (ncstatus != NC_NOERR) + printf (" Error putting data...\n"); + else + printf (" Done putting data...\n"); + } + free (cPtr); + break; + + case CDF_BYTE: + case CDF_INT1: + scPtr = NULL; + while (scPtr == NULL) { + scPtr = + (signed char *) malloc (sizeof(signed char)*numValues*numRecs); + if (scPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + scPtr); /* data pointer */ + if (var.recVariance == VARY) + count[0] = numRecs; + ncstatus = nc_put_vara_schar(ncid, varId, start, count, scPtr); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + free (scPtr); + break; + + case CDF_INT2: + case CDF_UCHAR: + case CDF_UINT1: + sPtr = NULL; + while (sPtr == NULL) { + sPtr = (short *) malloc (sizeof(short) * numValues * numRecs); + if (sPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + sPtr); /* data pointer */ + if (var.recVariance == VARY) + count[0] = numRecs; + ncstatus = nc_put_vara_short(ncid, varId, start, count, sPtr); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + free (sPtr); + break; + + case CDF_INT4: + case CDF_UINT2: + iPtr = NULL; + while (iPtr == NULL) { + iPtr = (int *) malloc (sizeof(int) * numValues * numRecs); + if (iPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + iPtr); /* data pointer */ + if (var.recVariance == VARY) + count[0] = numRecs; + ncstatus = nc_put_vara_int(ncid, varId, start, count, iPtr); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + free (iPtr); + break; + + case CDF_FLOAT: + case CDF_REAL4: + fPtr = NULL; + while (fPtr == NULL) { + fPtr = (float *) malloc (sizeof(float) * numValues * numRecs); + if (fPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + fPtr); /* data pointer */ + if (var.recVariance == VARY) + count[0] = numRecs; + ncstatus = nc_put_vara_float(ncid, varId, start, count, fPtr); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + free (fPtr); + break; + + case CDF_DOUBLE: + case CDF_REAL8: + case CDF_UINT4: + dPtr = NULL; + while (dPtr == NULL) { + dPtr = (double *) malloc (sizeof(double) * numValues * numRecs); + if (dPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + dPtr); /* data pointer */ + if (var.recVariance == VARY) + count[0] = numRecs; + + ncstatus = nc_put_vara_double(ncid, varId, start, count, dPtr); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + free (dPtr); + break; + + case CDF_EPOCH: + dPtr = NULL; + while (dPtr == NULL) { + dPtr = (double *) malloc (sizeof(double)*numValues*numRecs); + if (dPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + dPtr); /* data pointer */ + + count[0] = 1L; + + /* Get the EPOCH value into a DD Timestring. */ + + for (i = 0; i < numRecs*numValues; i++) { + *(dPtr+i) /= 1000.0; + + *(dPtr+i) -= TIMESHIFT; + strcpy(curTime,Double2DD_Time((double)*(dPtr+i))); + ncstatus = nc_put_vara_text(ncid, varId, start, count, curTime); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + if ((i == 0) && (isTimeSet == 0)) strcpy(StartTime,curTime); + start[0]++; + } + // First Epoch type is considered as Time + if (isTimeSet == 0) strcpy(StopTime,curTime); + isTimeSet = 1; + free (dPtr); + break; + + case CDF_EPOCH16: + dPtr = NULL; + while (dPtr == NULL) { + dPtr = (double *) malloc (sizeof(double) * numValues*numRecs*2); + if (dPtr == NULL) { + if (DEBUG) insufficient_memory(); + divide *= 2; + numRecs = totRecs / divide; + } + } + read_cdf_variable_data (varId, + recNo, /* starting record # */ + numRecs, /* # of records to read */ + var.dimensionality, + var.dimSizes, /* dimesion sizes */ + dPtr); /* data pointer */ + + count[0] = 1L; + + + /* Get all the EPOCH16 values into a single string. */ + for (i=0; i < numRecs; i++) { + epoch16[0] = *(dPtr+i*2); + epoch16[1] = *(dPtr+i*2+1); + encodeEPOCH16_4 (epoch16, ep16String); + ncstatus = nc_put_vara_text(ncid, varId, start, count, isotime_to_dd_time(ep16String)); + if (ncstatus != NC_NOERR) handle_netcdf_error(ncstatus); + if ((i == 0) && (isTimeSet == 0)) strcpy(StartTime,isotime_to_dd_time(ep16String)); + start[0]++; + } + + free (dPtr); + // First Epoch type is considered as Time + if (isTimeSet == 0) strcpy(StopTime,isotime_to_dd_time(ep16String)); + isTimeSet = 1; + break; + + default: + printf ("** Error in getVarData: bad type"); + } + + numRecsLeftToRead = totRecs - numRecs; + if (numRecsLeftToRead > 0) { + totRecs = numRecsLeftToRead; + start[0] = numRecs; + } + } /* end of the 'while' loop */ + +} + + +/*-------------------------------------------------------------------------- + * This routine returns the string representation of the given CDF + * datatype. + *--------------------------------------------------------------------------*/ +char * cdf_str_datatype (long type) +{ + switch (type) { + case CDF_BYTE: + return "CDF_BYTE"; + + case CDF_INT1: + return "CDF_INT1"; + + case CDF_CHAR: + return "CDF_CHAR"; + + case CDF_INT2: + return "CDF_INT2"; + + case CDF_UCHAR: + return "CDF_UCHAR"; + + case CDF_UINT1: + return "CDF_UINT1"; + + case CDF_INT4: + return "CDF_INT4"; + + case CDF_UINT2: + return "CDF_UINT2"; + + case CDF_FLOAT: + return "CDF_FLOAT"; + + case CDF_REAL4: + return "CDF_REAL4"; + + case CDF_DOUBLE: + return "CDF_DOUBLE"; + + case CDF_REAL8: + return "CDF_REAL8"; + + case CDF_UINT4: + return "CDF_UINT4"; + + case CDF_EPOCH: + return "CDF_EPOCH"; + + case CDF_EPOCH16: + return "CDF_EPOCH16"; + } +} + + +/*-------------------------------------------------------------------------- + * This routine returns the string representation of the given netCDF + * datatype. + *--------------------------------------------------------------------------*/ +char * NC_datatype (nc_type type) +{ + switch (type) { + case NC_BYTE: + return "byte"; + case NC_CHAR: + return "char"; + case NC_SHORT: + return "short"; + case NC_INT: + return "int"; + case NC_FLOAT: + return "float"; + case NC_DOUBLE: + return "double"; + default: + return "UNKNOWN"; + } +} + + +/*-------------------------------------------------------------------------- + * This routine returns the netCDF datatype for the given CDF datatype. + *--------------------------------------------------------------------------*/ +nc_type get_netcdf_datatype (long type) +{ + nc_type netcdf_type; + + switch (type) { + case CDF_BYTE: + case CDF_INT1: + netcdf_type = NC_BYTE; + break; + + case CDF_CHAR: + case CDF_EPOCH: + case CDF_EPOCH16: + netcdf_type = NC_CHAR; + break; + + case CDF_INT2: + case CDF_UCHAR: + case CDF_UINT1: + netcdf_type = NC_SHORT; + break; + + case CDF_INT4: + case CDF_UINT2: + netcdf_type = NC_INT; + break; + + case CDF_FLOAT: + case CDF_REAL4: + netcdf_type = NC_FLOAT; + break; + + case CDF_DOUBLE: + case CDF_REAL8: + case CDF_UINT4: + netcdf_type = NC_DOUBLE; + break; + + default: { + printf ("** ERROR: Unknown CDF datatype\n"); + exit (1); + } + } + return netcdf_type; +} + + +/*--------------------------------------------------------------------------- + * Read the CDF variable data for the given CDF variable number. + *---------------------------------------------------------------------------*/ +void read_cdf_variable_data (long varNum, /* CDF variable number */ + long recNo, /* record # for start reading */ + long recCount, /* # of records to read */ + long dim, /* CDF dimensionality */ + long dimSizes[], /* CDF dimesion sizes */ + void *data) /* data pointer */ +{ + CDFstatus status; + int i; + long recInterval, /* No. of recors to skip */ + dimIndices[CDF_MAX_DIMS], /* Beginning location of the array */ + /* to be dumped */ + dimIntervals[CDF_MAX_DIMS]; /* No. of elements to skip */ + + recInterval = 1L; /* # of records to skip between writes */ + + for (i=0; i < dim; i++) { + dimIndices[i] = 0; /* Dump data from the beginning of array */ + dimIntervals[i] = 1; /* Dump all the elements in the array */ + } + + status = CDFlib (SELECT_,zVAR_, varNum, + zVAR_RECNUMBER_, recNo, + zVAR_RECCOUNT_, recCount, + zVAR_RECINTERVAL_, recInterval, + zVAR_DIMINDICES_, dimIndices, + zVAR_DIMCOUNTS_, dimSizes, + zVAR_DIMINTERVALS_, dimIntervals, + GET_, zVAR_HYPERDATA_, data, + NULL_); + if (status != CDF_OK) cdf_status_handler (status, "GET_, zVAR_HYPERDATA_"); +} + + +/*-------------------------------------------------------------------------- + * Remove the filepath from a file name. + * + * Example: + * /home/data/mydata.txt => mydata.txt + *--------------------------------------------------------------------------*/ +void removeFilepath (char *fileName) { + char *ptr; + + ptr = strrchr(fileName, '/'); /* Unix file path separator */ + if (ptr != NULL) { + ptr++; + strcpy(fileName, ptr); + } + else { + ptr = strrchr(fileName, '\\'); /* Windows file separator */ + if (ptr != NULL) { + ptr++; + strcpy(fileName, ptr); + } + } +} + + +/*-------------------------------------------------------------------------- + * Handles a CDF error. + *--------------------------------------------------------------------------*/ +void cdf_status_handler (CDFstatus status, char *source) +{ + char message[CDF_STATUSTEXT_LEN+1]; + + CDFerror (status, message); /* Get the appropriate message */ + + if (status < CDF_WARN) { + printf ("An error has occurred, halting...\n"); + printf ("%s\n", message); + printf ("** Error source: %s\n", source); + exit (status); + } + else if (status < CDF_OK) { + printf ("Warning, function may not have compeleted as expected...\n"); + printf ("%s\n", message); + } + else if (status > CDF_OK) { + printf ("Function compeleted successfully, but be advised that...\n"); + printf ("%s\n", message); + } +} + + +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void handle_netcdf_error(int status) { + + fprintf(stderr, "%s\n", nc_strerror(status)); +} + + +/*-------------------------------------------------------------------------- + * Handles a memory allocation error. + *--------------------------------------------------------------------------*/ +void memory_error(char *source, char *datatype) { + printf ("** Memory allocation error occurred in %s. data type = %s", + source, datatype); + exit (1); +} + +void insufficient_memory () { + printf("Insufficient memory to load all the records at once"); +} + + +/*--------------------------------------------------------------------------*/ +void usage() +{ + printf ("\nDescription:\n"); + printf (" This program converts a CDF file into a netCDF file."); + printf ("\n"); + printf ("Usage: cdf2nc -[Options] <CDF file name>\n"); + printf ("\n"); + printf ("Options:\n"); + printf (" -map <mapfile> Use the user-supplied mapping file.\n"); + printf (" -debug Show debug information.\n"); + printf ("\n"); + printf ("Examples of usage: \n"); + printf ("1) cdf-to-netCDF test.cdf\n"); + printf (" will convert the test.cdf file into the test.nc file.\n\n"); + printf ("2) cdf-to-netCDF -map mymap.dat test.cdf\n"); + printf (" will convert the test.cdf file into the test.nc file using\n"); + printf (" the user-supplied mapping file called 'mymap.dat' instead\n"); + printf (" of using the default cdf-to-netCDF mapping file.\n"); + printf ("\n"); + exit(1); +} + +void parseCmdLine (int argc, char *argv[]) +{ + int i; + char *nextArg; + + for (i=0; i < argc; i++) { + if (strcmp(argv[i],"-map") == 0) { + nextArg = getNextArgument(argc, argv, i); + if (strcmp(nextArg, "No next argument") == 0 || + *(nextArg+0) == '-') + errorMsg("** Error - mapping file is not defined"); + else + strcpy(mappingFile, nextArg); + } + else if (strcmp(argv[i],"-debug") == 0) + DEBUG = TRUE; + } +} + + +char * getNextArgument (int argc, char *argv[], int currentIndex) +{ + char *nextArg, msg[30]; + int nextIndex; + + nextIndex = currentIndex+1; + if (nextIndex == argc) { + strcpy (msg, "No next argument"); + nextArg = msg; + } + else + nextArg = argv[nextIndex]; + + return nextArg; +} + +void errorMsg (char *msg) +{ + printf ("%s\n", msg); + exit (1); +} + + +void map_CDF_attr_to_netCDF (char *searchAttr, /* in - CDF attr name */ + char *mappedAttrName) /* out - netCDF attr name */ +{ + int i; + + strcpy(mappedAttrName, searchAttr); + + for (i=0; i < totAttrsInMappingFile; i++) { + if (strcmp(cdfAttrNames[i], searchAttr) == 0) { + strcpy(mappedAttrName, netcdfAttrNames[i]); + break; + } + } +} + +/******************************************************************************* + * + * Convert an ISO 8601 date time to a DD Time string + */ +char * isotime_to_dd_time (char * input) +{ + static char output [DD_TIME_STRING_LEN + 1]; + int i, count, ddd; + int yy, mm, dd, h, m, s, ms; + int duration[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + count = sscanf (input, "%d-%d-%dT%d:%d:%d.%3d", & yy, & mm, & dd, & h, & m, & s, &ms); + + if (count != 7) { + printf ("Unexpected time format: %s\n", input); + strcpy (output, "ERROR "); + goto EXIT; + } + + if (leap_year (yy)) duration [2] = 29; + + ddd = dd - 1; /* Jan-01 : 0 => ddd in [0, 366[ */ + + for (i = 1; i < mm; i++) ddd += duration [i]; + + sprintf (output, "%04.4d%03.3d%02.2d%02.2d%02.2d%03.3d", + yy, ddd, h, m, s, ms); + +EXIT: return output; +} +/******************************************************************************* + * + * Check if the given year is a leap one + */ +int leap_year (int year) +{ + if ((year % 400) == 0) return TRUE; + if ((year % 100) == 0) return FALSE; + if ((year % 4) == 0) return TRUE; + return FALSE; +} + diff --git a/src/DECODERS/cdf2nc/cdf_to_netcdf_mapping.dat b/src/DECODERS/cdf2nc/cdf_to_netcdf_mapping.dat new file mode 100644 index 0000000..ae9a844 --- /dev/null +++ b/src/DECODERS/cdf2nc/cdf_to_netcdf_mapping.dat @@ -0,0 +1,12 @@ +#netCDF CDF Comment +#---- --- ------- +history Revise_History // History of revision +_FillValue FILLVAL // Fill value + +# The asterisk (*) is a placeholder indicator and its corresponding mapping +# attribute is created in the output file. The following example creates +# 2 attributes (P1 and P2), if uncommented. The value +# of P1 and P2 will be "Placeholder 1" and "Placeholder 2", resctively. + +#P1 * // Value of P1 +#P2 * // Value of P2 diff --git a/src/DECODERS/nc2nc/CMakeLists.txt b/src/DECODERS/nc2nc/CMakeLists.txt new file mode 100644 index 0000000..ced0d24 --- /dev/null +++ b/src/DECODERS/nc2nc/CMakeLists.txt @@ -0,0 +1,24 @@ + +PROJECT(nc2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (nc2nc ${source_files} ) + +target_link_libraries( + nc2nc + DD_Client + ${NETCDFLIBRARY} +) + +install (TARGETS nc2nc DESTINATION bin) diff --git a/src/DECODERS/nc2nc/nc2nc.c b/src/DECODERS/nc2nc/nc2nc.c new file mode 100644 index 0000000..7511cc8 --- /dev/null +++ b/src/DECODERS/nc2nc/nc2nc.c @@ -0,0 +1,43 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netcdf.h> + + +main(int argc, char **argv) +{ + int ncID; + char varname[NC_MAX_NAME]; + int i, ii, j, status, nvars; + + char SpecialSymbol[9] = {' ', '#', '%', '@', '+', '.', '>', '<', '-'}; + + /* open nc file to write */ + if((status = nc_open(argv[1],NC_WRITE|NC_SHARE,&ncID)) != NC_NOERR) + { + fprintf(stderr,"Can not open file %s to write\n",argv[1]); + exit(0); + } + /* get info on number of variables */ + status = nc_inq_nvars(ncID, &nvars); + + for (j = 0; j < nvars; j++) { + + /* get the name of variable by its ID */ + status = nc_inq_varname(ncID, j, varname); + + /* Replace special symbols with underscore(s) */ + + for (ii = 0; ii < 9; ii++) + for (i = 0; i < strlen(varname); i++) { + if (varname[i] == SpecialSymbol[ii]) varname[i] = '_'; + } + /* Rename the variable */ + + status = nc_rename_var(ncID, j, varname); + nc_sync(ncID); + + } + + status = nc_close(ncID); +} diff --git a/src/DECODERS/themis/esa2nc/CMakeLists.txt b/src/DECODERS/themis/esa2nc/CMakeLists.txt new file mode 100644 index 0000000..99a0e86 --- /dev/null +++ b/src/DECODERS/themis/esa2nc/CMakeLists.txt @@ -0,0 +1,26 @@ + +PROJECT(esa2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} + ${libcdf_INCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (esa2nc ${source_files} ) + +target_link_libraries( + esa2nc + DD_Client + ${NETCDFLIBRARY} + ${libcdf_LIBRARIES} +) + +install (TARGETS esa2nc DESTINATION bin) diff --git a/src/DECODERS/themis/esa2nc/themis_esa2nc.c b/src/DECODERS/themis/esa2nc/themis_esa2nc.c new file mode 100644 index 0000000..a1ea6d3 --- /dev/null +++ b/src/DECODERS/themis/esa2nc/themis_esa2nc.c @@ -0,0 +1,551 @@ +/** +* @file themis_esa2nc.c +* @brief Stand alone executable to tranform Themis (Burst & Reduced modes) CDF to DD netCDF +* @version $Id: themis_esa2nc.c,v 1.5 2013/11/29 14:11:56 budnik Exp $ +*/ + /**************************************************************/ + /* THEMIS ESA ION AND ELECTRON Burst & Reduced CDF -> DD netCDF */ + /* */ + /* Energy in info file */ + /* New CDF with peib & peir and new params */ + /* 04.01.2008 - 2 files (sp & mom) for peir[b] & peer[b] modes */ + /**************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <cdf.h> +#include <DD.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#define TimeGap 3600.0 +#define Source "themis@cdpp2" +#define MAX_FILE_NAME_LEN 250 // Max. file name length +#define MAX_VARS 250 // Max # of VARS in CDF + + +/************************************* + Global variables and structures +**************************************/ +long CDFDims, // Number of dimensions in a CDF file + CDFVars, // Number of variables in a CDF file + CDFDimSizes[CDF_MAX_DIMS], // Dimension Sizes in a CDF file + CDFencoding, // Data encoding + CDFmajority, // Variable majority + CDFmaxRec, // max Record number + CDFAttrs; // number of CDF Attributes + + +struct cdfvar { // CDF variable structure + char name[CDF_VAR_NAME_LEN+1]; + long num; //variable number + long datatype; + long numElem; // variable dimensionality + long recVariance; // variable rec Variance + long dimVariances[CDF_MAX_DIMS]; // # of data values in dimSizes +} cdfVar[MAX_VARS]; + +char mode[4]; +int ncID, ncSpID; +char ncFile[] = "peir000000000.nc"; +char ncSpFile[] = "speir000000000.nc"; +int TimeDimID, TimeLengthID, DataID, DataSpID, Data2ID; +int TimeDimSpID, TimeLengthSpID, FluxDimID; // ID of netCDF dimensions +int TimeDimVector[2], DataDimVector[2], Data2DimVector[2], FluxDimVector[2]; // netCDF Dim vectors +int TimeDimSpVector[2], DataDimSpVector[2]; +size_t Start[2] = {0L,0L}; +size_t TimeCount[2] = {1L,TIMELENGTH}; +size_t Data1Count[2] = {1L,1L}; +size_t DataCount[2] = {1L,3L}; +size_t Data2Count[2] = {1L,6L}; +size_t FluxCount[2] = {1L,32L}; + +CDFstatus cstatus; // CDF status code + +char Version[]="v01"; +char ThemisID[]="tha\0"; +char ThemisTime[]="tha_peif_time"; +char PAR0[]="tha_peif_delta_time"; +char PAR1[]="tha_peif_mode"; +char PAR2[]="tha_peif_density"; +char PAR3[]="tha_peif_velocity_gse"; +char PAR4[]="tha_peif_t3"; // Diagonilized Temperature +char PAR5[]="tha_peif_en_eflux"; +char PAR6[]="tha_peif_en_eflux_yaxis"; +char PAR7[]="tha_peif_avgtemp"; // trace of t3 divided by 3 +char PAR8[]="tha_peif_vthermal"; +char PAR9[]="tha_peif_sc_pot"; +char PAR10[]="tha_peif_sc_current"; +char PAR11[]="tha_peif_magt3"; // Temperature in Mag Field frame +char PAR12[]="tha_peif_ptens"; // Pressure Tensor DSL +char PAR13[]="tha_peif_mftens"; // Momentum Flux Tensor DSL +char PAR14[]="tha_peif_flux"; // particle flux +char PAR15[]="tha_peif_symm"; // Direction of pressure tensor symmetry in DSL +char PAR16[]="tha_peif_symm_ang"; // Angle between Direction of pressure tensor symmetry and B + + +int StartTimeID, StopTimeID; +int StartTimeSpID, StopTimeSpID; +int DeltaTID, DensID, AvTempID, ThVelID, PotID, CurrID, SymAngID; // 1D +int MfTempID, TempID, ModeID, ModeSpID, VelID, Flux2ID, SymmID; // 2D -> 3 +int prTenID, mfTenID; // 2D -> 6 +int FluxID; // 2D -> 32 +int TimeID; // Time netCDF variable +int TimeSpID; + +char StartT[TIMELENGTH]; // Start time from data +char StopT[TIMELENGTH]; // Stop time from data +/************************** + Function prototypes +**************************/ +void usage(); +void cdf_handle_error (CDFstatus); +void nc_handle_error (int); +void removeFilepath(); +void removeCDFext(); +void removeVers(); +void ncdefine(); +/*--------------------------------------------------------------------------*/ +void usage() +{ + printf ("\nDescription:\n"); + printf (" This program converts a themis CDF file into a netCDF file.\n"); + printf ("\n"); + printf ("Usage: esa2nc <CDF file name> <ThemisID> <mode>\n"); + printf ("\n"); + printf ("Example: esa2nc testfile tha peif\n"); + printf ("\n"); + exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a CDF error. + *--------------------------------------------------------------------------*/ +void cdf_handle_error(CDFstatus status) +{ + + char message[CDF_STATUSTEXT_LEN+1]; + + CDFerror (status, message); /* Get the appropriate message */ + fprintf (stderr, "CDF: %s\n", message); +// exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void nc_handle_error(int status) +{ + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(1); +} + +/*-------------------------------------------------------------------------- + * NetCDF File Definition * + *--------------------------------------------------------------------------*/ + void ncdefine(double Time) + { + char *s; + time_t p; + int status; + char *STime; + +/*********************** Create netCDF file *****************************/ + memcpy(&(ncFile[0]),&(mode[0]), 4); + STime = Double2DD_Time(Time); + memcpy(&(ncFile[4]),&(STime[2]), 9); + if ((status = nc_create(ncFile, NC_CLOBBER, &ncID)) != NC_NOERR) + nc_handle_error(status); +/******************netCDF Dimensions *******************************/ + nc_def_dim (ncID, "Time", NC_UNLIMITED, &TimeDimID); + nc_def_dim (ncID, "TimeLength", TIMELENGTH, &TimeLengthID); + nc_def_dim (ncID, "Data",3L, &DataID); + nc_def_dim (ncID, "Data2",6L, &Data2ID); + +/********************netCDF Variables ******************/ + TimeDimVector[0] = TimeDimID; + DataDimVector[0] = TimeDimID; + Data2DimVector[0] = TimeDimID; + TimeDimVector[1] = TimeLengthID; + DataDimVector[1] = DataID; + Data2DimVector[1] = Data2ID; + +// + nc_def_var (ncID, "Time", NC_CHAR, 2, TimeDimVector, &TimeID); + + nc_def_var (ncID, "DeltaT", NC_DOUBLE, 1, &TimeDimID, &DeltaTID); + nc_def_var (ncID, "Mode", NC_FLOAT, 2, DataDimVector, &ModeID); + + nc_def_var (ncID, "Density", NC_DOUBLE, 1, &TimeDimID, &DensID); + nc_def_var (ncID, "AvTemp", NC_DOUBLE, 1, &TimeDimID, &AvTempID); + nc_def_var (ncID, "Potential", NC_DOUBLE, 1, &TimeDimID, &PotID); + nc_def_var (ncID, "Current", NC_DOUBLE, 1, &TimeDimID, &CurrID); + nc_def_var (ncID, "SymAngle", NC_DOUBLE, 1, &TimeDimID, &SymAngID); + nc_def_var (ncID, "V_thermal", NC_DOUBLE, 1, &TimeDimID, &ThVelID); + nc_def_var (ncID, "Velocity", NC_DOUBLE, 2, DataDimVector, &VelID); + nc_def_var (ncID, "Temperature", NC_DOUBLE, 2, DataDimVector, &TempID); + nc_def_var (ncID, "B_Temperature", NC_DOUBLE, 2, DataDimVector, &MfTempID); + nc_def_var (ncID, "Flux_tot", NC_DOUBLE, 2, DataDimVector, &Flux2ID); + nc_def_var (ncID, "Symm", NC_DOUBLE, 2, DataDimVector, &SymmID); + nc_def_var (ncID, "tensor_p", NC_DOUBLE, 2, Data2DimVector, &prTenID); + nc_def_var (ncID, "tensor_mf", NC_DOUBLE, 2, Data2DimVector, &mfTenID); + + nc_def_var (ncID, "StartTime",NC_CHAR, 1, &TimeLengthID, &StartTimeID); + nc_def_var (ncID, "StopTime",NC_CHAR, 1, &TimeLengthID , &StopTimeID); + + + + + nc_put_att_text(ncID, NC_GLOBAL, "Themis", 3, ThemisID); + nc_put_att_text(ncID, NC_GLOBAL, "Source", 12, Source); + nc_put_att_text(ncID, DensID, "Units", 5, "cm^-3"); + nc_put_att_text(ncID, TempID, "Units", 2, "eV"); + nc_put_att_text(ncID, TempID, "Frame", 2, "FA"); + nc_put_att_text(ncID, TempID, "Order", 16, "perp1,perp2,para"); + nc_put_att_text(ncID, MfTempID, "Units", 2, "eV"); + nc_put_att_text(ncID, MfTempID, "Frame", 2, "FA"); + nc_put_att_text(ncID, MfTempID, "Order", 16, "perp1,perp2,para"); + nc_put_att_text(ncID, AvTempID, "Units", 2, "eV"); + nc_put_att_text(ncID, prTenID, "Units", 2, "eV"); + nc_put_att_text(ncID, prTenID, "Frame", 3, "DSL"); + nc_put_att_text(ncID, prTenID, "Order", 17, "xx,xy,xz,yy,zz,yz"); + nc_put_att_text(ncID, mfTenID, "Units", 2, "eV"); + nc_put_att_text(ncID, mfTenID, "Frame", 3, "DSL"); + nc_put_att_text(ncID, mfTenID, "Order", 17, "xx,xy,xz,yy,zz,yz"); + nc_put_att_text(ncID, Flux2ID, "Units", 9, "#/sec/cm2"); + nc_put_att_text(ncID, PotID, "Units", 1, "V"); + nc_put_att_text(ncID, SymmID, "Frame", 3, "DSL"); + nc_put_att_text(ncID, CurrID, "Units", 7, "Unknown"); + nc_put_att_text(ncID, SymAngID, "Units", 7, "degrees"); + nc_put_att_text(ncID, VelID, "Units", 4, "km/s"); + nc_put_att_text(ncID, ThVelID, "Units", 4, "km/s"); + nc_put_att_text(ncID, VelID, "Frame", 3, "GSE"); + + + + time(&p); + s = ctime(&p); + nc_put_att_text(ncID, NC_GLOBAL, "Created", 24, s); + + + + memcpy(&(ncSpFile[1]),&(mode[0]), 4); + STime = Double2DD_Time(Time); + memcpy(&(ncSpFile[5]),&(STime[2]), 9); + if ((status = nc_create(ncSpFile, NC_CLOBBER, &ncSpID)) != NC_NOERR) + nc_handle_error(status); + + status = nc_def_dim (ncSpID, "Time", NC_UNLIMITED, &TimeDimSpID); + status = nc_def_dim (ncSpID, "TimeLength", TIMELENGTH, &TimeLengthSpID); + status = nc_def_dim (ncSpID, "Data",3L, &DataSpID); + status = nc_def_dim (ncSpID, "Flux",32L, &FluxDimID); + + FluxDimVector[0] = TimeDimSpID; + FluxDimVector[1] = FluxDimID; + +//ModeID, DensID, VelID, TempID; + + status = nc_def_var (ncSpID, "Time", NC_CHAR, 2, TimeDimVector, &TimeSpID); + status = nc_def_var (ncSpID, "Mode", NC_FLOAT, 2, DataDimVector, &ModeSpID); + status = nc_def_var (ncSpID, "Flux", NC_DOUBLE, 2, FluxDimVector, &FluxID); + + status = nc_def_var (ncSpID, "StartTime", NC_CHAR, 1, &TimeLengthSpID, &StartTimeSpID); + status = nc_def_var (ncSpID, "StopTime", NC_CHAR, 1, &TimeLengthSpID , &StopTimeSpID); + + status = nc_put_att_text(ncSpID, FluxID, "Units", 17, "eV/(cm^2-s-sr-eV)"); + status = nc_put_att_text(ncSpID, NC_GLOBAL, "Created", 24, s); + + status = nc_enddef(ncID); + status = nc_enddef(ncSpID); + + nc_put_vara_text(ncID, StartTimeID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time)); + nc_put_vara_text(ncSpID, StartTimeSpID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time)); + + } + + void put_double(RecStart, RecCount, ParCDF, ParNC) { + + + long RecInt = 1; + long indices[1] = {0}, intervals[1] = {1}, counts[1] = {1}; + + double *value; + + value = (double *)malloc(sizeof(double)*RecCount); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, ParNC, value); + + free(value); + } + + void put_double3(RecStart, RecCount, ParCDF, ParNC) { + + long RecInt = 1; + long indices[2] = {0,3}, intervals[1] = {1}, counts[1] = {3}; + double *value; + + value = (double *)malloc(sizeof(double)*RecCount*3); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, ParNC, value); + + free(value); + } + +void put_double6(RecStart, RecCount, ParCDF, ParNC) { + + long RecInt = 1; + long indices[2] = {0,6}, intervals[1] = {1}, counts[1] = {6}; + double *value; + + value = (double *)malloc(sizeof(double)*RecCount*6); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, ParNC, value); + + free(value); + } + + void put_mode(RecStart, RecCount, ParCDF, ParNC, ParSpNC) { + + float *value; + long indices[2] = {0,3}, intervals[1] = {1}, counts[1] = {3}; + long RecInt = 1; + + value = (float *)malloc(sizeof(float) * RecCount *3); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_float(ncID, ParNC, value); + nc_put_var_float(ncSpID, ParSpNC, value); + free(value); + } + +void put_spectra(RecStart, RecCount, ParCDF, ParNC) { + + double *value; + long indices[2] = {0,32}, intervals[1] = {1}, counts[1] = {32}; + long RecInt = 1; + + value = (double *)malloc(sizeof(double)*RecCount*32); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncSpID, ParNC, value); + free(value); + } +/*--------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ + long RecStart = 0, RecCount, RecCountF = 1, RecInt = 1, MaxRec; + long indices[1] = {0}, counts[1] = {3}, counts2[1] = {6}, countsFlux[1] = {32}, intervals[1] = {1}; + long countsE[1] = {1}, indicesF[2]={0,3}, indicesF2[2]={0,6}, indicesFlux[2] = {0, 32}; + double *value; + float *value_f; + size_t numElem; + long dimN, varN, par0, par1, par2, par3, par4, par5, par6, par7, par8, par9, par10, par11, par12, par13, par14, par15, par16; + + CDFid id; + int i, j, status; + char fileName[MAX_FILE_NAME_LEN]; + dd_tmstr_t *dtm; + int First = 1; + double par[3], parr[6], doubleVal, parD[32]; + float parF[32], par_f[3], parr_f[6], floatVal; + double DayOld; + + + char *UT; + char data_set[8]="thx_pexx"; +/*-------------------------------- Arguments Decoding ----------------------------------------*/ + if (argc <= 3) usage(); // CDF input file name and THEMIS Number not specified + else + { + strcpy(fileName, argv[1]); + strncpy(ThemisID,argv[2],3); + strncpy(mode,argv[3],4); + } + +/*------------------------------------------ CDF Variables Names Updated according to THEMIS Number -------------*/ + + memcpy(&(data_set[2]),&(ThemisID[2]),1); + memcpy(&(data_set[6]),&(mode[2]),2); + + memcpy(&(ThemisTime[0]),&(data_set[0]),8); + memcpy(&(PAR0[0]),&(data_set[0]),8); + memcpy(&(PAR1[0]),&(data_set[0]),8); + memcpy(&(PAR2[0]),&(data_set[0]),8); + memcpy(&(PAR3[0]),&(data_set[0]),8); + memcpy(&(PAR4[0]),&(data_set[0]),8); + memcpy(&(PAR5[0]),&(data_set[0]),8); + memcpy(&(PAR6[0]),&(data_set[0]),8); + memcpy(&(PAR7[0]),&(data_set[0]),8); + memcpy(&(PAR8[0]),&(data_set[0]),8); + memcpy(&(PAR9[0]),&(data_set[0]),8); + memcpy(&(PAR10[0]),&(data_set[0]),8); + memcpy(&(PAR11[0]),&(data_set[0]),8); + memcpy(&(PAR12[0]),&(data_set[0]),8); + memcpy(&(PAR13[0]),&(data_set[0]),8); + memcpy(&(PAR14[0]),&(data_set[0]),8); + memcpy(&(PAR15[0]),&(data_set[0]),8); + memcpy(&(PAR16[0]),&(data_set[0]),8); + +/*********************** Open CDF file *****************************/ + if ((cstatus = CDFopen(fileName, &id)) != CDF_OK) + cdf_handle_error(cstatus); + printf(" THEMIS %s %s\n", ThemisID, mode); + +/*********** treat all vars as zVars with eliminated false dimensionality **********/ + + if ((cstatus = CDFlib(SELECT_, CDF_zMODE_, zMODEon2, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + +/************************ Get CDF Data ************************************/ + + cstatus = CDFlib(GET_, zVAR_NUMBER_, ThemisTime, &varN, NULL_); + cstatus = CDFlib( SELECT_, zVAR_, varN, GET_, zVAR_MAXREC_, &MaxRec, NULL_); + + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR0, &par0, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR1, &par1, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR2, &par2, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR3, &par3, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR4, &par4, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR5, &par5, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR6, &par6, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR7, &par7, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR8, &par8, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR9, &par9, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR10, &par10, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR11, &par11, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR12, &par12, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR13, &par13, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR14, &par14, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR15, &par15, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR16, &par16, NULL_); + + RecCount = (long)(MaxRec+1); + printf(" Max Rec %d\n", MaxRec); + + if (MaxRec <= 0) exit(0); + + value = (double *)malloc(sizeof(double)* RecCount); + if ((cstatus = CDFlib (SELECT_, + zVAR_, varN, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_) ) + != CDF_OK) cdf_handle_error(cstatus); + + for (i = 0; i < RecCount; i++) { + + + UT = Double2DD_Time(value[i]); + + if ((First == 0) && (value[i] - DayOld) > TimeGap) { + + printf("GAP %f\n",(value[i] - DayOld)/60.0); + put_double(RecStart, (long)i - RecStart, par0, DeltaTID); + put_mode(RecStart, (long)i - RecStart, par1, ModeID, ModeSpID); + put_double(RecStart, (long)i - RecStart, par2, DensID); + put_double3(RecStart, (long)i - RecStart, par3, VelID); + put_double3(RecStart,(long)i - RecStart, par4, TempID); + put_double3(RecStart, (long)i - RecStart, par11, MfTempID); + put_double3(RecStart, (long)i - RecStart, par14, Flux2ID); + put_double3(RecStart, (long)i - RecStart, par15, SymmID); + put_double6(RecStart, (long)i - RecStart, par12, prTenID); + put_double6(RecStart, (long)i - RecStart, par13, mfTenID); + put_double(RecStart, (long)i - RecStart, par7, AvTempID); + put_double(RecStart, (long)i - RecStart, par8, ThVelID); + put_double(RecStart, (long)i - RecStart, par9, PotID); + put_double(RecStart, (long)i - RecStart, par16, SymAngID); + put_spectra(RecStart, (long)i - RecStart, par5, FluxID); + + nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], Double2DD_Time(DayOld)); + nc_put_vara_text(ncSpID,StopTimeSpID, &Start[1], &TimeCount[1], Double2DD_Time(DayOld)); + + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + if ((status = nc_close(ncSpID)) != NC_NOERR) nc_handle_error(status); + First = 1; + RecStart = (long)i; + UT = Double2DD_Time(value[i]); + } + + dtm = ReadTime(UT); + if (First == 1) { + ncdefine(dtm->times); + + First = 0; + Start[0] = 0; + + } + nc_put_vara_text(ncID, TimeID, Start, TimeCount, UT); + nc_put_vara_text(ncSpID, TimeSpID, Start, TimeCount, UT); + Start[0]++; + DayOld = value[i]; + + } + free(value); + nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], UT); + nc_put_vara_text(ncSpID,StopTimeSpID, &Start[1], &TimeCount[1], UT); + + + put_double(RecStart, RecCount - RecStart, par0, DeltaTID); + put_mode(RecStart, RecCount - RecStart, par1, ModeID, ModeSpID); + put_double(RecStart, RecCount - RecStart, par2, DensID); + put_double3(RecStart, RecCount - RecStart, par3, VelID); + put_double3(RecStart, RecCount - RecStart, par4, TempID); + put_double3(RecStart, RecCount - RecStart, par11, MfTempID); + put_double3(RecStart, RecCount - RecStart, par14, Flux2ID); + put_double3(RecStart, RecCount - RecStart, par15, SymmID); + put_double6(RecStart, RecCount - RecStart, par12, prTenID); + put_double6(RecStart, RecCount - RecStart, par13, mfTenID); + put_double(RecStart, RecCount - RecStart, par7, AvTempID); + put_double(RecStart, RecCount - RecStart, par8, ThVelID); + put_double(RecStart, RecCount - RecStart, par9, PotID); + put_double(RecStart, RecCount - RecStart, par16, SymAngID); + put_spectra(RecStart, RecCount - RecStart, par5, FluxID); + +/********************Close Files******************/ + if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + if ((status = nc_close(ncSpID)) != NC_NOERR) nc_handle_error(status); +} diff --git a/src/DECODERS/themis/esafull2nc/CMakeLists.txt b/src/DECODERS/themis/esafull2nc/CMakeLists.txt new file mode 100644 index 0000000..ee6610b --- /dev/null +++ b/src/DECODERS/themis/esafull2nc/CMakeLists.txt @@ -0,0 +1,26 @@ + +PROJECT(esafull2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} + ${libcdf_INCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (esafull2nc ${source_files} ) + +target_link_libraries( + esafull2nc + DD_Client + ${NETCDFLIBRARY} + ${libcdf_LIBRARIES} +) + +install (TARGETS esafull2nc DESTINATION bin) diff --git a/src/DECODERS/themis/esafull2nc/themis_esafull2nc.c b/src/DECODERS/themis/esafull2nc/themis_esafull2nc.c new file mode 100644 index 0000000..904ae49 --- /dev/null +++ b/src/DECODERS/themis/esafull2nc/themis_esafull2nc.c @@ -0,0 +1,659 @@ + /**************************************************************/ + /* THEMIS ESA ION AND ELECTRON MOMENTS CDF -> DD netCDF */ + /* 04.01.2008 */ + /* V 1.1 */ + /* Energy in info file */ + /* New CDF with ALL modes and new params */ + /* 04.01.2008 - 2 files for peir & peer modes */ + /**************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <cdf.h> +#include <DD.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#define TimeGap 1800000.0 +#define Source "themis@cdpp2" +#define MAX_FILE_NAME_LEN 250 // Max. file name length +#define MAX_VARS 250 // Max # of VARS in CDF + + +/************************************* + Global variables and structures +**************************************/ +long CDFDims, // Number of dimensions in a CDF file + CDFVars, // Number of variables in a CDF file + CDFDimSizes[CDF_MAX_DIMS], // Dimension Sizes in a CDF file + CDFencoding, // Data encoding + CDFmajority, // Variable majority + CDFmaxRec, // max Record number + CDFAttrs; // number of CDF Attributes + + +struct cdfvar { // CDF variable structure + char name[CDF_VAR_NAME_LEN+1]; + long num; //variable number + long datatype; + long numElem; // variable dimensionality + long recVariance; // variable rec Variance + long dimVariances[CDF_MAX_DIMS]; // # of data values in dimSizes +} cdfVar[MAX_VARS]; + +char mode[4]; +int ncID, ncSpID; +char ncFile[] = "peif000000000.nc"; +int TimeDimID, TimeLengthID, DataID, Data2ID, FluxDimID;; +int TimeDimVector[2], DataDimVector[2], Data2DimVector[2], FluxDimVector[2]; // netCDF Dim vectors +size_t Start[2] = {0L,0L}; +size_t TimeCount[2] = {1L,TIMELENGTH}; +size_t Data1Count[2] = {1L,1L}; +size_t DataCount[2] = {1L,3L}; +size_t Data2Count[2] = {1L,6L}; +size_t FluxCount[2] = {1L,32L}; + +char Version[]="v01"; +char ThemisID[]="tha\0"; +char ThemisTime[]="tha_peif_time"; +char PAR0[]="tha_peif_delta_time"; +char PAR1[]="tha_peif_mode"; +char PAR2[]="tha_peif_density"; +char PAR3[]="tha_peif_velocity_gse"; +char PAR4[]="tha_peif_t3"; // Diagonilized Temperature +char PAR5[]="tha_peif_en_eflux"; +char PAR6[]="tha_peif_en_eflux_yaxis"; +char PAR7[]="tha_peif_avgtemp"; // trace of t3 divided by 3 +char PAR8[]="tha_peif_vthermal"; +char PAR9[]="tha_peif_sc_pot"; +char PAR10[]="tha_peif_sc_current"; +char PAR11[]="tha_peif_magt3"; // Temperature in Mag Field frame +char PAR12[]="tha_peif_ptens"; // Pressure Tensor DSL +char PAR13[]="tha_peif_mftens"; // Momentum Flux Tensor DSL +char PAR14[]="tha_peif_flux"; // particle flux +char PAR15[]="tha_peif_symm"; // Direction of pressure tensor symmetry in DSL +char PAR16[]="tha_peif_symm_ang"; // Angle between Direction of pressure tensor symmetry and B + + +int StartTimeID, StopTimeID; +int DeltaTID, DensID, AvTempID, ThVelID, PotID, CurrID, SymAngID; // 1D +int MfTempID, TempID, ModeID, VelID, Flux2ID, SymmID; // 2D -> 3 +int prTenID, mfTenID; // 2D -> 6 +int EnID, FluxID; // 2D -> 32 +int TimeID; // Time netCDF variable + + +char StartT[TIMELENGTH]; // Start time from data +char StopT[TIMELENGTH]; // Stop time from data +/************************** + Function prototypes +**************************/ +void usage(); +void cdf_handle_error (CDFstatus); +void nc_handle_error (int); +void removeFilepath(); +void removeCDFext(); +void removeVers(); +void ncdefine(); +/*--------------------------------------------------------------------------*/ +void usage() +{ + printf ("\nDescription:\n"); + printf (" This program converts a themis CDF file into a netCDF file.\n"); + printf ("\n"); + printf ("Usage: esa2nc <CDF file name> <ThemisID> <mode>\n"); + printf ("\n"); + printf ("Example: esa2nc testfile tha peif\n"); + printf ("\n"); + exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a CDF error. + *--------------------------------------------------------------------------*/ +void cdf_handle_error(CDFstatus status) +{ + + char message[CDF_STATUSTEXT_LEN+1]; + + CDFerror (status, message); /* Get the appropriate message */ + fprintf (stderr, "CDF: %s\n", message); +// exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void nc_handle_error(int status) +{ + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(1); +} +/*-------------------------------------------------------------------------- + * Remove the filepath from a file name. * + * Example: + * /home/data/mydata.txt => mydata.txt + *--------------------------------------------------------------------------*/ +void removeFilepath (char *fileName) +{ + char *ptr; + + ptr = strrchr(fileName, '/'); // Unix file path separator + if (ptr != NULL) + { + ptr++; + strcpy(fileName, ptr); + } +} +/*-------------------------------------------------------------------------- + * Decode CDF File Name * + *--------------------------------------------------------------------------*/ +void removeVers (char *fileName) +{ + char *ptr; + char zero = '\0'; + int i; + + for (i = 0; i < 9; i++) + { + ptr = strchr(fileName, '_'); + if (ptr != NULL) + { + ptr++; + strcpy(fileName, ptr); + } + } + ptr = strchr(fileName, '_'); // + + if (ptr != NULL) + { + ptr++; + strncpy(Version, ptr, 2); + } + } + + /*-------------------------------------------------------------------------- + * Remove the CDF extention * + *--------------------------------------------------------------------------*/ +void removeCDFext (char *fileName) +{ + char *ptr; + char zero = '\0'; + + ptr = strchr(fileName, '.'); + if (ptr != NULL) + strcpy(ptr, &zero); +} +/*-------------------------------------------------------------------------- + * NetCDF File Definition * + *--------------------------------------------------------------------------*/ + void ncdefine(double Time) + { + char *s; + time_t p; + int status; + char *STime; + +/*********************** Create netCDF file *****************************/ + memcpy(&(ncFile[0]),&(mode[0]), 4); + STime = Double2DD_Time(Time); + memcpy(&(ncFile[4]),&(STime[2]), 9); + if ((status = nc_create(ncFile, NC_CLOBBER, &ncID)) != NC_NOERR) + nc_handle_error(status); +/******************netCDF Dimensions *******************************/ + nc_def_dim (ncID, "Time", NC_UNLIMITED, &TimeDimID); + nc_def_dim (ncID, "TimeLength", TIMELENGTH, &TimeLengthID); + nc_def_dim (ncID, "Data",3L, &DataID); + nc_def_dim (ncID, "Data2",6L, &Data2ID); + + nc_def_dim (ncID, "Flux",32L, &FluxDimID); + +/********************netCDF Variables ******************/ + TimeDimVector[0] = TimeDimID; + DataDimVector[0] = TimeDimID; + Data2DimVector[0] = TimeDimID; + TimeDimVector[1] = TimeLengthID; + DataDimVector[1] = DataID; + FluxDimVector[0] = TimeDimID; + FluxDimVector[1] = FluxDimID; + Data2DimVector[1] = Data2ID; + +//ModeID, DensID, VelID, TempID; + nc_def_var (ncID, "Time", NC_CHAR, 2, TimeDimVector, &TimeID); + + nc_def_var (ncID, "DeltaT", NC_DOUBLE, 1, &TimeDimID, &DeltaTID); + nc_def_var (ncID, "Mode", NC_FLOAT, 2, DataDimVector, &ModeID); + nc_def_var (ncID, "Density", NC_DOUBLE, 1, &TimeDimID, &DensID); + nc_def_var (ncID, "AvTemp", NC_DOUBLE, 1, &TimeDimID, &AvTempID); + nc_def_var (ncID, "Potential", NC_DOUBLE, 1, &TimeDimID, &PotID); + nc_def_var (ncID, "Current", NC_DOUBLE, 1, &TimeDimID, &CurrID); + nc_def_var (ncID, "SymAngle", NC_DOUBLE, 1, &TimeDimID, &SymAngID); + nc_def_var (ncID, "V_thermal", NC_DOUBLE, 1, &TimeDimID, &ThVelID); + nc_def_var (ncID, "Velocity", NC_DOUBLE, 2, DataDimVector, &VelID); + nc_def_var (ncID, "Temperature", NC_DOUBLE, 2, DataDimVector, &TempID); + nc_def_var (ncID, "B_Temperature", NC_DOUBLE, 2, DataDimVector, &MfTempID); + nc_def_var (ncID, "Flux_tot", NC_DOUBLE, 2, DataDimVector, &Flux2ID); + nc_def_var (ncID, "Symm", NC_DOUBLE, 2, DataDimVector, &SymmID); + nc_def_var (ncID, "tensor_p", NC_DOUBLE, 2, Data2DimVector, &prTenID); + nc_def_var (ncID, "tensor_mf", NC_DOUBLE, 2, Data2DimVector, &mfTenID); + nc_def_var (ncID, "Flux", NC_DOUBLE, 2, FluxDimVector, &FluxID); + // nc_def_var (ncID, "Energy", NC_FLOAT, 2, FluxDimVector, &EnID); + nc_def_var (ncID, "StartTime",NC_CHAR, 1, &TimeLengthID, &StartTimeID); + nc_def_var (ncID, "StopTime",NC_CHAR, 1, &TimeLengthID , &StopTimeID); + + + + + nc_put_att_text(ncID, NC_GLOBAL, "Themis", 3, ThemisID); + nc_put_att_text(ncID, NC_GLOBAL, "Source", 12, Source); + nc_put_att_text(ncID, DensID, "Units", 5, "cm^-3"); + nc_put_att_text(ncID, TempID, "Units", 2, "eV"); + nc_put_att_text(ncID, TempID, "Frame", 2, "FA"); + nc_put_att_text(ncID, TempID, "Order", 16, "perp1,perp2,para"); + nc_put_att_text(ncID, MfTempID, "Units", 2, "eV"); + nc_put_att_text(ncID, MfTempID, "Frame", 2, "FA"); + nc_put_att_text(ncID, MfTempID, "Order", 16, "perp1,perp2,para"); + nc_put_att_text(ncID, AvTempID, "Units", 2, "eV"); + nc_put_att_text(ncID, prTenID, "Units", 2, "eV"); + nc_put_att_text(ncID, prTenID, "Frame", 3, "DSL"); + nc_put_att_text(ncID, prTenID, "Order", 17, "xx,xy,xz,yy,zz,yz"); + nc_put_att_text(ncID, mfTenID, "Units", 2, "eV"); + nc_put_att_text(ncID, mfTenID, "Frame", 3, "DSL"); + nc_put_att_text(ncID, mfTenID, "Order", 17, "xx,xy,xz,yy,zz,yz"); + nc_put_att_text(ncID, Flux2ID, "Units", 9, "#/sec/cm2"); + nc_put_att_text(ncID, PotID, "Units", 1, "V"); + nc_put_att_text(ncID, SymmID, "Frame", 3, "DSL"); + nc_put_att_text(ncID, CurrID, "Units", 7, "Unknown"); + nc_put_att_text(ncID, SymAngID, "Units", 7, "degrees"); + nc_put_att_text(ncID, VelID, "Units", 4, "km/s"); + nc_put_att_text(ncID, ThVelID, "Units", 4, "km/s"); + nc_put_att_text(ncID, VelID, "Frame", 3, "GSE"); + nc_put_att_text(ncID, EnID, "Units", 2, "eV"); + nc_put_att_text(ncID, FluxID, "Units", 17, "eV/(cm^2-s-sr-eV)"); + + time(&p); + s = ctime(&p); + nc_put_att_text(ncID, NC_GLOBAL, "Created", 24, s); + + nc_enddef(ncID); + + nc_put_vara_text(ncID, StartTimeID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time)); + + } +/*--------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ + long RecStart = 0, RecCount, RecCountF = 1, RecInt = 1, MaxRec; + long indices[1] = {0}, counts[1] = {3}, counts2[1] = {6}, countsFlux[1] = {32}, intervals[1] = {1}; + long countsE[1] = {1}, indicesF[2]={0,3}, indicesF2[2]={0,6}, indicesFlux[2] = {0, 32}; + double *value; + float *value_f; + size_t numElem; + long dimN, varN, par0, par1, par2, par3, par4, par5, par6, par7, par8, par9, par10, par11, par12, par13, par14, par15, par16; + CDFstatus cstatus; // CDF status code + CDFid id; + int i, j, status; + char fileName[MAX_FILE_NAME_LEN]; + dd_tmstr_t *dtm; + int First = 1; + double par[3], parr[6], doubleVal, parD[32]; + float parF[32], par_f[3], parr_f[6], floatVal; + long DayOld; + + + char *UT; + char data_set[8]="thx_pexx"; +/*-------------------------------- Arguments Decoding ----------------------------------------*/ + if (argc <= 3) usage(); // CDF input file name and THEMIS Number not specified + else + { + strcpy(fileName, argv[1]); + strncpy(ThemisID,argv[2],3); + strncpy(mode,argv[3],4); + } + +/*------------------------------------------ CDF Variables Names Updated according to THEMIS Number -------------*/ + + memcpy(&(data_set[2]),&(ThemisID[2]),1); + memcpy(&(data_set[6]),&(mode[2]),2); + + memcpy(&(ThemisTime[0]),&(data_set[0]),8); + memcpy(&(PAR0[0]),&(data_set[0]),8); + memcpy(&(PAR1[0]),&(data_set[0]),8); + memcpy(&(PAR2[0]),&(data_set[0]),8); + memcpy(&(PAR3[0]),&(data_set[0]),8); + memcpy(&(PAR4[0]),&(data_set[0]),8); + memcpy(&(PAR5[0]),&(data_set[0]),8); + memcpy(&(PAR6[0]),&(data_set[0]),8); + memcpy(&(PAR7[0]),&(data_set[0]),8); + memcpy(&(PAR8[0]),&(data_set[0]),8); + memcpy(&(PAR9[0]),&(data_set[0]),8); + memcpy(&(PAR10[0]),&(data_set[0]),8); + memcpy(&(PAR11[0]),&(data_set[0]),8); + memcpy(&(PAR12[0]),&(data_set[0]),8); + memcpy(&(PAR13[0]),&(data_set[0]),8); + memcpy(&(PAR14[0]),&(data_set[0]),8); + memcpy(&(PAR15[0]),&(data_set[0]),8); + memcpy(&(PAR16[0]),&(data_set[0]),8); + +/*********************** Open CDF file *****************************/ + if ((cstatus = CDFopen(fileName, &id)) != CDF_OK) + cdf_handle_error(cstatus); + printf(" THEMIS %s %s\n", ThemisID, mode); + +/*********** treat all vars as zVars with eliminated false dimensionality **********/ + + if ((cstatus = CDFlib(SELECT_, CDF_zMODE_, zMODEon2, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + + // Remove the file path (/home/data/mydata => mydata) + removeFilepath(fileName); + // Remove Version Number + removeVers(fileName); + + // Remove .cdf extension + removeCDFext(fileName); + +/************************ Get CDF Data ************************************/ + + cstatus = CDFlib(GET_, zVAR_NUMBER_, ThemisTime, &varN, NULL_); + cstatus = CDFlib( SELECT_, zVAR_, varN, GET_, zVAR_MAXREC_, &MaxRec, NULL_); + + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR0, &par0, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR1, &par1, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR2, &par2, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR3, &par3, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR4, &par4, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR5, &par5, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR6, &par6, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR7, &par7, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR8, &par8, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR9, &par9, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR10, &par10, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR11, &par11, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR12, &par12, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR13, &par13, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR14, &par14, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR15, &par15, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR16, &par16, NULL_); + + RecCount = (long)(MaxRec+1); + printf(" Max Rec %d\n", MaxRec); + + value = (double *)malloc(sizeof(double)* RecCount); + if ((cstatus = CDFlib (SELECT_, + zVAR_, varN, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_) ) + != CDF_OK) cdf_handle_error(cstatus); + + for (i = 0; i < RecCount; i++) { + UT = Double2DD_Time(value[i]); + dtm = ReadTime(UT); + if (First == 1) { + ncdefine(dtm->times); + First = 0; + } + nc_put_vara_text(ncID, TimeID, Start, TimeCount, UT); + + Start[0]++; + + } + nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], UT); + + Start[0] = 0L; +// deltaT + if ((cstatus = CDFlib (SELECT_, zVAR_, par0, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, DeltaTID, value); + + + free(value); + value_f = (float *)malloc(sizeof(float)* RecCount * 3); + + +// Mode + if ((cstatus = CDFlib (SELECT_, zVAR_, par1, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value_f, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_float(ncID, ModeID, value_f); + free(value_f); + + value = (double *)malloc(sizeof(double)* RecCount * 3); + // peif_velocity_gse + if ((cstatus = CDFlib (SELECT_, zVAR_, par3, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, VelID, value); + +// temperature + if ((cstatus = CDFlib (SELECT_, zVAR_, par4, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, TempID,value); + +// temperature regard to B-field + if ((cstatus = CDFlib (SELECT_, zVAR_, par11, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, MfTempID, value); + +// Flux total + if ((cstatus = CDFlib (SELECT_, zVAR_, par14, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, Flux2ID, value); + + +// symmetry + if ((cstatus = CDFlib (SELECT_, zVAR_, par15, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, SymmID, value); + + free(value); + value = (double *)malloc(sizeof(double)* RecCount * 6); + +// + if ((cstatus = CDFlib (SELECT_, zVAR_, par12, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF2, + zVAR_DIMCOUNTS_, counts2, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, prTenID, value); + +// Pressure Tensor with regard to B-field + if ((cstatus = CDFlib (SELECT_, zVAR_, par13, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF2, + zVAR_DIMCOUNTS_, counts2, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, mfTenID, value); + free(value); + value = (double *)malloc(sizeof(double)* RecCount); + +// Density + if ((cstatus = CDFlib (SELECT_, zVAR_, par2, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, DensID, value); +// Average Temperature + if ((cstatus = CDFlib (SELECT_, zVAR_, par7, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, AvTempID, value); +// Thermal Velocity + if ((cstatus = CDFlib (SELECT_, zVAR_, par8, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, ThVelID, value); +// Potential + if ((cstatus = CDFlib (SELECT_, zVAR_, par9, + zVAR_RECNUMBER_, RecStart, + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, PotID, value); +// Current + /* if ((cstatus = CDFlib (SELECT_, zVAR_, par10, + zVAR_RECNUMBER_, RecStart, + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, CurrID, value); + */ +// Symmery Angle with B + if ((cstatus = CDFlib (SELECT_, zVAR_, par16, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, SymAngID, value); + + free(value); + value = (double *)malloc(sizeof(double)* RecCount *32); + + if ((cstatus = CDFlib (SELECT_, zVAR_, par5, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesFlux, + zVAR_DIMCOUNTS_, countsFlux, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, FluxID, value); + + /* + if ((cstatus = CDFlib (SELECT_, zVAR_, par6, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCountF, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesFlux, + zVAR_DIMCOUNTS_, countsFlux, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, parF, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + */ + /* if (!isnan(parF[0])) + nc_put_vara_float(ncID, EnID, Start, FluxCount, parF); + else nc_put_vara_float(ncID, EnID, Start, FluxCount, FillValueF); + */ // for (j = 0; j < 32; i++) printf(" %f ", parF[j]); + + + // } + + + free(value); +/********************Close Files******************/ + if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + +} diff --git a/src/DECODERS/themis/esamom2nc/CMakeLists.txt b/src/DECODERS/themis/esamom2nc/CMakeLists.txt new file mode 100644 index 0000000..6556da5 --- /dev/null +++ b/src/DECODERS/themis/esamom2nc/CMakeLists.txt @@ -0,0 +1,26 @@ + +PROJECT(esamom2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} + ${libcdf_INCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (esamom2nc ${source_files} ) + +target_link_libraries( + esamom2nc + DD_Client + ${NETCDFLIBRARY} + ${libcdf_LIBRARIES} +) + +install (TARGETS esamom2nc DESTINATION bin) diff --git a/src/DECODERS/themis/esamom2nc/themis_esamom2nc.c b/src/DECODERS/themis/esamom2nc/themis_esamom2nc.c new file mode 100644 index 0000000..4c7b6bc --- /dev/null +++ b/src/DECODERS/themis/esamom2nc/themis_esamom2nc.c @@ -0,0 +1,456 @@ + /**************************************************************/ + /* THEMIS ESA ION AND ELECTRON MOMENTS CDF -> DD netCDF */ + /* 04.01.2008 */ + /* V 1.1 */ + /* */ + /* New CDF with ALL modes and new params */ + /* */ + /**************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <cdf.h> +#include <DD.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#define TimeGap 1800000.0 +#define Source "themis@cdpp2" +#define MAX_FILE_NAME_LEN 250 // Max. file name length +#define MAX_VARS 250 // Max # of VARS in CDF + + +/************************************* + Global variables and structures +**************************************/ +long CDFDims, // Number of dimensions in a CDF file + CDFVars, // Number of variables in a CDF file + CDFDimSizes[CDF_MAX_DIMS], // Dimension Sizes in a CDF file + CDFencoding, // Data encoding + CDFmajority, // Variable majority + CDFmaxRec, // max Record number + CDFAttrs; // number of CDF Attributes + + +struct cdfvar { // CDF variable structure + char name[CDF_VAR_NAME_LEN+1]; + long num; //variable number + long datatype; + long numElem; // variable dimensionality + long recVariance; // variable rec Variance + long dimVariances[CDF_MAX_DIMS]; // # of data values in dimSizes +} cdfVar[MAX_VARS]; + +char mode[4]; +int ncID; +char ncFile[] = "peim000000000.nc"; +int TimeDimID, TimeLengthID, DataID, Data2ID; +int TimeDimVector[2], DataDimVector[2], Data2DimVector[2]; // netCDF Dim vectors +size_t Start[2] = {0L,0L}; +size_t TimeCount[2] = {1L,TIMELENGTH}; +size_t Data1Count[2] = {1L,1L}; +size_t DataCount[2] = {1L,3L}; +size_t Data2Count[2] = {1L,6L}; + +char Version[]="v01"; +char ThemisID[]="tha\0"; +char ThemisTime[]="tha_peim_time"; +char PAR0[]="tha_peim_density"; +char PAR1[]="tha_peim_ptot"; +char PAR2[]="tha_peim_flux"; +char PAR3[]="tha_peim_mftens"; // Momentum Flux Tensor DSL +char PAR4[]="tha_peim_eflux"; +char PAR5[]="tha_peim_velocity_gse"; +char PAR6[]="tha_peim_ptens"; // Pressure Tensor DSL +char PAR7[]="tha_peim_mag"; +char PAR8[]="tha_peim_velocity_mag"; +char PAR9[]="tha_peim_t3_mag"; // Diagonilized Temperature +char PAR10[]="tha_peim_ptens_mag"; // + + +int StartTimeID, StopTimeID; +int DeltaTID, DensID, PtotID; // 1D +int FluxID, EfluxID, VelID, MagID, VelMagID, TempMagID; // 2D -> 3 +int MfTensID, PtensID, PtensMagID ; // 2D -> 6 + +int TimeID; // Time netCDF variable + + +char StartT[TIMELENGTH]; // Start time from data +char StopT[TIMELENGTH]; // Stop time from data +/************************** + Function prototypes +**************************/ +void usage(); +void cdf_handle_error (CDFstatus); +void nc_handle_error (int); +void ncdefine(); +/*--------------------------------------------------------------------------*/ +void usage() +{ + printf ("\nDescription:\n"); + printf (" This program converts a themis CDF file into a netCDF file.\n"); + printf ("\n"); + printf ("Usage: esa2nc <CDF file name> <ThemisID>\n"); + printf ("\n"); + printf ("Example: esa2nc testfile tha\n"); + printf ("\n"); + exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a CDF error. + *--------------------------------------------------------------------------*/ +void cdf_handle_error(CDFstatus status) +{ + + char message[CDF_STATUSTEXT_LEN+1]; + + CDFerror (status, message); /* Get the appropriate message */ + fprintf (stderr, "CDF: %s\n", message); +// exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void nc_handle_error(int status) +{ + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(1); +} + + +/*-------------------------------------------------------------------------- + * NetCDF File Definition * + *--------------------------------------------------------------------------*/ + void ncdefine(double Time) + { + char *s; + time_t p; + int status; + char *STime; + +/*********************** Create netCDF file *****************************/ + memcpy(&(ncFile[0]),&(mode[0]),4); + STime = Double2DD_Time(Time); + memcpy(&(ncFile[4]),&(STime[2]), 9); + if ((status = nc_create(ncFile, NC_CLOBBER, &ncID)) != NC_NOERR) + nc_handle_error(status); +/******************netCDF Dimensions *******************************/ + nc_def_dim (ncID, "Time", NC_UNLIMITED, &TimeDimID); + nc_def_dim (ncID, "TimeLength", TIMELENGTH, &TimeLengthID); + nc_def_dim (ncID, "Data",3L, &DataID); + nc_def_dim (ncID, "Data2",6L, &Data2ID); + +/********************netCDF Variables ******************/ + TimeDimVector[0] = TimeDimID; + DataDimVector[0] = TimeDimID; + Data2DimVector[0] = TimeDimID; + TimeDimVector[1] = TimeLengthID; + DataDimVector[1] = DataID; + + Data2DimVector[1] = Data2ID; + +//ModeID, DensID, VelID, TempID; + nc_def_var (ncID, "Time", NC_CHAR, 2, TimeDimVector, &TimeID); + nc_def_var (ncID, "Density", NC_DOUBLE, 1, &TimeDimID, &DensID); + nc_def_var (ncID, "Ptot", NC_DOUBLE, 1, &TimeDimID, &PtotID); + nc_def_var (ncID, "Flux", NC_DOUBLE, 2, DataDimVector, &FluxID); + nc_def_var (ncID, "MfTens", NC_DOUBLE, 2, Data2DimVector, &MfTensID); + nc_def_var (ncID, "Eflux", NC_DOUBLE, 2, DataDimVector, &EfluxID); + nc_def_var (ncID, "Velocity", NC_DOUBLE, 2, DataDimVector, &VelID); + nc_def_var (ncID, "Ptens", NC_DOUBLE, 2, Data2DimVector, &PtensID); + nc_def_var (ncID, "Mag", NC_DOUBLE, 2, DataDimVector, &MagID); + nc_def_var (ncID, "VelocityMag", NC_DOUBLE, 2, DataDimVector, &VelMagID); + nc_def_var (ncID, "TempMag", NC_DOUBLE, 2, DataDimVector, &TempMagID); + nc_def_var (ncID, "PtensMag", NC_DOUBLE, 2, Data2DimVector, &PtensMagID); + + nc_def_var (ncID, "StartTime",NC_CHAR, 1, &TimeLengthID, &StartTimeID); + nc_def_var (ncID, "StopTime",NC_CHAR, 1, &TimeLengthID , &StopTimeID); + + + + + nc_put_att_text(ncID, NC_GLOBAL, "Themis", 3, ThemisID); + nc_put_att_text(ncID, NC_GLOBAL, "Source", 12, Source); + nc_put_att_text(ncID, DensID, "Units", 5, "cm^-3"); + + + time(&p); + s = ctime(&p); + nc_put_att_text(ncID, NC_GLOBAL, "Created", 24, s); + + nc_enddef(ncID); + + nc_put_vara_text(ncID, StartTimeID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time)); + ; + } +/*--------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ + long RecStart = 0, RecCount, RecCountF = 1, RecInt = 1, MaxRec; + long indices[1] = {0}, counts[1] = {3}, counts2[1] = {6}, intervals[1] = {1}; + long countsE[1] = {1}, indicesF[2]={0,3}, indicesF2[2]={0,6}; + double *value; + float *value_f; + size_t numElem; + long dimN, varN, par0, par1, par2, par3, par4, par5, par6, par7, par8, par9, par10; + CDFstatus cstatus; // CDF status code + CDFid id; + int i, j, status; + char fileName[MAX_FILE_NAME_LEN]; + dd_tmstr_t *dtm; + int First = 1; + + char *UT; + char data_set[8]="thx_peim"; +/*-------------------------------- Arguments Decoding ----------------------------------------*/ + if (argc <= 2) usage(); // CDF input file name and THEMIS Number not specified + else + { + strcpy(fileName, argv[1]); + strncpy(ThemisID,argv[2],3); + strncpy(mode,argv[3],4); + } + +/*------------------------------------------ CDF Variables Names Updated according to THEMIS Number -------------*/ + memcpy(&(data_set[2]),&(ThemisID[2]),1); + memcpy(&(data_set[6]),&(mode[2]),2); + + memcpy(&(ThemisTime[0]),&(data_set[0]),8); + memcpy(&(PAR0[0]),&(data_set[0]),8); + memcpy(&(PAR1[0]),&(data_set[0]),8); + memcpy(&(PAR2[0]),&(data_set[0]),8); + memcpy(&(PAR3[0]),&(data_set[0]),8); + memcpy(&(PAR4[0]),&(data_set[0]),8); + memcpy(&(PAR5[0]),&(data_set[0]),8); + memcpy(&(PAR6[0]),&(data_set[0]),8); + memcpy(&(PAR7[0]),&(data_set[0]),8); + memcpy(&(PAR8[0]),&(data_set[0]),8); + memcpy(&(PAR9[0]),&(data_set[0]),8); + memcpy(&(PAR10[0]),&(data_set[0]),8); + +/*********************** Open CDF file *****************************/ + if ((cstatus = CDFopen(fileName, &id)) != CDF_OK) + cdf_handle_error(cstatus); + printf(" THEMIS %s \n", ThemisID); + +/*********** treat all vars as zVars with eliminated false dimensionality **********/ + + if ((cstatus = CDFlib(SELECT_, CDF_zMODE_, zMODEon2, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + + +/************************ Get CDF Data ************************************/ + + cstatus = CDFlib(GET_, zVAR_NUMBER_, ThemisTime, &varN, NULL_); + cstatus = CDFlib( SELECT_, zVAR_, varN, GET_, zVAR_MAXREC_, &MaxRec, NULL_); + + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR0, &par0, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR1, &par1, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR2, &par2, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR3, &par3, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR4, &par4, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR5, &par5, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR6, &par6, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR7, &par7, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR8, &par8, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR9, &par9, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR10, &par10, NULL_); + + + RecCount = (long)(MaxRec+1); + printf(" Max Rec %d\n", MaxRec); + if ( RecCount > 0) { + value = (double *)malloc(sizeof(double)* RecCount); + if ((cstatus = CDFlib (SELECT_, + zVAR_, varN, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_) ) + != CDF_OK) cdf_handle_error(cstatus); + + for (i = 0; i < RecCount; i++) { + UT = Double2DD_Time(value[i]); + dtm = ReadTime(UT); + if (First == 1) { + ncdefine(dtm->times); + First = 0; + } + nc_put_vara_text(ncID, TimeID, Start, TimeCount, UT); + + Start[0]++; + + } + nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], UT); + + +// Density + if ((cstatus = CDFlib (SELECT_, zVAR_, par0, + zVAR_RECNUMBER_, RecStart, + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, DensID, value); +// Ion Total Pressure + if ((cstatus = CDFlib (SELECT_, zVAR_, par1, + zVAR_RECNUMBER_, RecStart, + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, PtotID, value); + + free(value); + value = (double *)malloc(sizeof(double)* RecCount * 3); + // flux + if ((cstatus = CDFlib (SELECT_, zVAR_, par2, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, FluxID, value); + +// Energy Flux + if ((cstatus = CDFlib (SELECT_, zVAR_, par4, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, EfluxID,value); + +// Velocity GSE + if ((cstatus = CDFlib (SELECT_, zVAR_, par5, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + nc_put_var_double(ncID, VelID, value); + +// Magnetic Field Vector DSL + if ((cstatus = CDFlib (SELECT_, zVAR_, par7, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, MagID, value); + +// Velocity Mag + if ((cstatus = CDFlib (SELECT_, zVAR_, par8, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, VelMagID, value); + + // Temperature Mag + if ((cstatus = CDFlib (SELECT_, zVAR_, par9, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, TempMagID, value); + + free(value); + value = (double *)malloc(sizeof(double)* RecCount * 6); + +// Momentum Flux Tensor + if ((cstatus = CDFlib (SELECT_, zVAR_, par3, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF2, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, MfTensID, value); + +// Pressure Tensor + if ((cstatus = CDFlib (SELECT_, zVAR_, par6, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF2, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, PtensID, value); + +// Pressure Tensor Mag + if ((cstatus = CDFlib (SELECT_, zVAR_, par10, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF2, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + + + nc_put_var_double(ncID, PtensMagID, value); + + + + free(value); +/********************Close Files******************/ + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + } + if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + + + +} diff --git a/src/DECODERS/themis/fgm2nc/CMakeLists.txt b/src/DECODERS/themis/fgm2nc/CMakeLists.txt new file mode 100644 index 0000000..97f0bc2 --- /dev/null +++ b/src/DECODERS/themis/fgm2nc/CMakeLists.txt @@ -0,0 +1,26 @@ + +PROJECT(fgm2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} + ${libcdf_INCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (fgm2nc ${source_files} ) + +target_link_libraries( + fgm2nc + DD_Client + ${NETCDFLIBRARY} + ${libcdf_LIBRARIES} +) + +install (TARGETS fgm2nc DESTINATION bin) diff --git a/src/DECODERS/themis/fgm2nc/themis_fgm2nc.c b/src/DECODERS/themis/fgm2nc/themis_fgm2nc.c new file mode 100644 index 0000000..ef853fb --- /dev/null +++ b/src/DECODERS/themis/fgm2nc/themis_fgm2nc.c @@ -0,0 +1,351 @@ + /************************************************************/ + /* THEMIS FGM CDF -> DD netCDF */ +/* NaN -> -1.e31 */ + /* 12.10.2007 */ + /* V 1.0 */ + /***********************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <cdf.h> +#include <DD.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#define TimeGap 1800000.0 +#define Source "themis@cdpp2" +#define MAX_FILE_NAME_LEN 250 // Max. file name length +#define MAX_VARS 250 // Max # of VARS in CDF + + +/************************************* + Global variables and structures +**************************************/ +long CDFDims, // Number of dimensions in a CDF file + CDFVars, // Number of variables in a CDF file + CDFDimSizes[CDF_MAX_DIMS], // Dimension Sizes in a CDF file + CDFencoding, // Data encoding + CDFmajority, // Variable majority + CDFmaxRec, // max Record number + CDFAttrs; // number of CDF Attributes + + +struct cdfvar { // CDF variable structure + char name[CDF_VAR_NAME_LEN+1]; + long num; //variable number + long datatype; + long numElem; // variable dimensionality + long recVariance; // variable rec Variance + long dimVariances[CDF_MAX_DIMS]; // # of data values in dimSizes +} cdfVar[MAX_VARS]; + + +int ncID; +char ncFile[] = "fgmh000000000.nc"; +int TimeDimID, TimeLengthID, DataID; // ID of netCDF dimensions +int TimeDimVector[2], DataDimVector[2]; // netCDF Dim vectors +size_t Start[2] = {0L,0L}; +size_t TimeCount[2] = {1L,TIMELENGTH}; +size_t DataCount[2] = {1L,3L}; + +char Version[]="v01"; +char ThemisID[]="tha\0"; +char ThemisTime[]="tha_fgh_time"; +char PAR0[]="tha_fgh_gse"; +float FillValue[3] = {-1.e31,-1.e31,-1.e31}; + +int StartTimeID, StopTimeID; +int FGMID; // Data netCDF Variables +int TimeID; // Time netCDF variable + +char StartT[TIMELENGTH]; // Start time from data +char StopT[TIMELENGTH]; // Stop time from data +/************************** + Function prototypes +**************************/ +void usage(); +void cdf_handle_error (CDFstatus); +void nc_handle_error (int); +void removeFilepath(); +void removeCDFext(); +void removeVers(); + +/*--------------------------------------------------------------------------*/ +void usage() +{ + printf ("\nDescription:\n"); + printf (" This program converts a themis CDF file into a netCDF file.\n"); + printf ("\n"); + printf ("Usage: fgm2nc <CDF file name> <ThemisID> <Resolution>\n"); + printf ("\n"); + printf ("Example: fgm2nc testfile tha h\n"); + printf ("\n"); + exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a CDF error. + *--------------------------------------------------------------------------*/ +void cdf_handle_error(CDFstatus status) +{ + + char message[CDF_STATUSTEXT_LEN+1]; + + CDFerror (status, message); /* Get the appropriate message */ + fprintf (stderr, "%s\n", message); + exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void nc_handle_error(int status) +{ + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(1); +} +/*-------------------------------------------------------------------------- + * Remove the filepath from a file name. * + * Example: + * /home/data/mydata.txt => mydata.txt + *--------------------------------------------------------------------------*/ +void removeFilepath (char *fileName) +{ + char *ptr; + + ptr = strrchr(fileName, '/'); // Unix file path separator + if (ptr != NULL) + { + ptr++; + strcpy(fileName, ptr); + } +} +/*-------------------------------------------------------------------------- + * Decode CDF File Name * + *--------------------------------------------------------------------------*/ +void removeVers (char *fileName) +{ + char *ptr; + char zero = '\0'; + int i; + + for (i = 0; i < 9; i++) + { + ptr = strchr(fileName, '_'); + if (ptr != NULL) + { + ptr++; + strcpy(fileName, ptr); + } + } + ptr = strchr(fileName, '_'); // + + if (ptr != NULL) + { + ptr++; + strncpy(Version, ptr, 2); + } + } + + /*-------------------------------------------------------------------------- + * Remove the CDF extention * + *--------------------------------------------------------------------------*/ +void removeCDFext (char *fileName) +{ + char *ptr; + char zero = '\0'; + + ptr = strchr(fileName, '.'); + if (ptr != NULL) + strcpy(ptr, &zero); +} +/*-------------------------------------------------------------------------- + * NetCDF File Definition * + *--------------------------------------------------------------------------*/ + void ncdefine(double Time, char *Sampling) + { + char *s; + time_t p; + int status; + char *STime; + +/*********************** Create netCDF file *****************************/ + STime = Double2DD_Time(Time); + + memcpy(&(ncFile[3]),&(Sampling[0]), 1); + memcpy(&(ncFile[4]),&(STime[2]), 9); + if ((status = nc_create(ncFile, NC_CLOBBER, &ncID)) != NC_NOERR) + nc_handle_error(status); +/******************netCDF Dimensions *******************************/ + nc_def_dim (ncID, "Time", NC_UNLIMITED, &TimeDimID); + nc_def_dim (ncID, "TimeLength", TIMELENGTH, &TimeLengthID); + nc_def_dim (ncID, "Data",3L, &DataID); + +/********************netCDF Variables ******************/ + TimeDimVector[0] = TimeDimID; + DataDimVector[0] = TimeDimID; + TimeDimVector[1] = TimeLengthID; + DataDimVector[1] = DataID; + +//ModeID, DensID, VelID, TempID; + nc_def_var (ncID, "Time", NC_CHAR, 2, TimeDimVector, &TimeID); + nc_def_var (ncID, "B", NC_FLOAT, 2, DataDimVector, &FGMID); + nc_def_var (ncID, "StartTime",NC_CHAR, 1, &TimeLengthID, &StartTimeID); + nc_def_var (ncID, "StopTime",NC_CHAR, 1, &TimeLengthID , &StopTimeID); + + nc_put_att_text(ncID, NC_GLOBAL, "Themis", 3, ThemisID); + nc_put_att_text(ncID, NC_GLOBAL, "Source", 12, Source); + nc_put_att_text(ncID, NC_GLOBAL, "Resolution", 1, Sampling); + // nc_put_att_text(ncID, NC_GLOBAL, "Version", 2, Version); + nc_put_att_text(ncID, FGMID, "Units", 2, "nT"); + nc_put_att_text(ncID, FGMID, "Frame", 3, "GSE"); + + time(&p); + s = ctime(&p); + nc_put_att_text(ncID, NC_GLOBAL, "Created", 24, s); + nc_enddef(ncID); + nc_put_vara_text(ncID, StartTimeID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time)); + + } +/*--------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ + long RecStart = 0, RecCount, RecCountF = 1, RecInt = 1, MaxRec; + long indices[1] = {0}, counts[1] = {3}, intervals[1] = {1}; + long countsE[1] = {1}, indicesF[2]={0,3}; + double *value; + size_t numElem; + long dimN, varN, par0, par1; + CDFstatus cstatus; // CDF status code + CDFid id; + int i, j, status; + char fileName[MAX_FILE_NAME_LEN]; + char Sampling[1]; + dd_tmstr_t *dtm; + int First = 1; + float par[3]; + long DayOld; + + char *UT; +/*-------------------------------- Arguments Decoding ----------------------------------------*/ + if (argc <= 3) usage(); // CDF input file name and HEMIS Number not specified + else + { + strcpy(fileName, argv[1]); + strncpy(ThemisID, argv[2], 3); + strncpy(Sampling, argv[3], 1); + } + + +/*------------------------------------------ CDF Variables Names Updated according to THEMIS Number -------------*/ + + memcpy(&(ThemisTime[2]),&(ThemisID[2]),1); + memcpy(&(PAR0[2]),&(ThemisID[2]),1); + memcpy(&(ThemisTime[6]),&(Sampling[0]),1); + memcpy(&(PAR0[6]),&(Sampling[0]),1); + +/*********************** Open CDF file *****************************/ + if ((cstatus = CDFopen(fileName, &id)) != CDF_OK) + cdf_handle_error(cstatus); + printf(" %s %s\n", argv[2],argv[3]); + +/*********** treat all vars as zVars with eliminated false dimensionality **********/ + + if ((cstatus = CDFlib(SELECT_, CDF_zMODE_, zMODEon2, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + + // Remove the file path (/home/data/mydata => mydata) + removeFilepath(fileName); + // Remove Version Number + removeVers(fileName); + + // Remove .cdf extension + removeCDFext(fileName); + +/************************ Get CDF Data ************************************/ + + if ((cstatus = CDFlib(GET_, zVAR_NUMBER_, ThemisTime, &varN, NULL_)) != CDF_OK) + cdf_handle_error(cstatus) ; + if ((cstatus = CDFlib( SELECT_, zVAR_, varN, + GET_, zVAR_MAXREC_, &MaxRec, NULL_)) != CDF_OK) + cdf_handle_error(cstatus) ; + + + if ((cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR0, &par0, NULL_)) != CDF_OK) + cdf_handle_error(cstatus) ; + + if ((cstatus = CDFlib( SELECT_, zVAR_, par0, + GET_, zVAR_DIMSIZES_, CDFDimSizes, NULL_)) != CDF_OK) + cdf_handle_error (cstatus) ; + + + RecCount = (long)(MaxRec+1); + printf(" Max Rec %d\n", MaxRec); + if (MaxRec > 1) { + value = (double *)malloc(sizeof(double)* RecCount); + if ((cstatus = CDFlib (SELECT_, + zVAR_, varN, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_) ) + != CDF_OK) cdf_handle_error (cstatus); + + for (i = 0; i < RecCount; i++) + { + + UT = Double2DD_Time(value[i]); + dtm = ReadTime(UT); + + if (i > 0 && (value[i]-value[i-1]) > TimeGap) + { + printf(" !!! Time GAP -> %f min\n", (value[i]-value[i-1])/60.0); + nc_put_vara_text(ncID,StopTimeID,&Start[1],&TimeCount[1], Double2DD_Time(dtm->times)); + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + } + + if (First == 1) + { + ncdefine(dtm->times, Sampling); + First = 0; + DayOld = dtm->day; + } + if (i > 0 && (value[i]-value[i-1]) > TimeGap) + { + ncdefine(dtm->times, Sampling); + Start[0] = 0L; + } + nc_put_vara_text(ncID, TimeID, Start, TimeCount, Double2DD_Time(dtm->times)); + + + RecStart = (long)i; + + if ((cstatus = CDFlib (SELECT_, zVAR_, par0, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCountF, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indicesF, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, par, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + if (!isnan(par[0])) + nc_put_vara_float(ncID, FGMID, Start, DataCount, par); + else nc_put_vara_float(ncID, FGMID, Start, DataCount, FillValue); + + + Start[0]++; + DayOld = dtm->day; + } + nc_put_vara_text(ncID,StopTimeID,&Start[1],&TimeCount[1], Double2DD_Time(dtm->times)); + free(value); + + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + } +/********************Close Files******************/ + if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + +} diff --git a/src/DECODERS/themis/sst2nc/CMakeLists.txt b/src/DECODERS/themis/sst2nc/CMakeLists.txt new file mode 100644 index 0000000..de83b44 --- /dev/null +++ b/src/DECODERS/themis/sst2nc/CMakeLists.txt @@ -0,0 +1,26 @@ + +PROJECT(sst2nc) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} + ${libcdf_INCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (sst2nc ${source_files} ) + +target_link_libraries( + sst2nc + DD_Client + ${NETCDFLIBRARY} + ${libcdf_LIBRARIES} +) + +install (TARGETS sst2nc DESTINATION bin) diff --git a/src/DECODERS/themis/sst2nc/themis_sst2nc.c b/src/DECODERS/themis/sst2nc/themis_sst2nc.c new file mode 100644 index 0000000..8555b3b --- /dev/null +++ b/src/DECODERS/themis/sst2nc/themis_sst2nc.c @@ -0,0 +1,363 @@ + /**************************************************************/ + /* THEMIS ESA ION AND ELECTRON MOMENTS CDF -> DD netCDF */ + /* 04.01.2008 */ + /* V 1.1 */ + /* Energy in info file */ + /* New CDF with ALL modes and new params */ + /* 04.01.2008 - 2 files for peir & peer modes */ + /**************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <netcdf.h> +#include <cdf.h> +#include <DD.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#define TimeGap 3600.0 +#define Source "themis@cdpp2" +#define MAX_FILE_NAME_LEN 250 // Max. file name length +#define MAX_VARS 250 // Max # of VARS in CDF + + +/************************************* + Global variables and structures +**************************************/ +long CDFDims, // Number of dimensions in a CDF file + CDFVars, // Number of variables in a CDF file + CDFDimSizes[CDF_MAX_DIMS], // Dimension Sizes in a CDF file + CDFencoding, // Data encoding + CDFmajority, // Variable majority + CDFmaxRec, // max Record number + CDFAttrs; // number of CDF Attributes + + +struct cdfvar { // CDF variable structure + char name[CDF_VAR_NAME_LEN+1]; + long num; //variable number + long datatype; + long numElem; // variable dimensionality + long recVariance; // variable rec Variance + long dimVariances[CDF_MAX_DIMS]; // # of data values in dimSizes +} cdfVar[MAX_VARS]; + +char mode[4]; +int ncID; +char ncFile[] = "psif000000000.nc"; +int TimeDimID, TimeLengthID, FluxDimID; +int TimeDimVector[2], FluxDimVector[2]; // netCDF Dim vectors + +size_t Start[2] = {0L,0L}; +size_t TimeCount[2] = {1L,TIMELENGTH}; +size_t FluxCount[2] = {1L,16L}; + +CDFstatus cstatus; // CDF status code + +char Version[]="v01"; +char ThemisID[]="tha\0"; +char ThemisTime[]="tha_psif_en_eflux_time"; +char PAR0[]="tha_psif_en_eflux_delta_time"; +char PAR1[]="tha_psif_en_eflux_mode"; +char PAR2[]="tha_psif_en_eflux"; + +int StartTimeID, StopTimeID; +int StartTimeSpID, StopTimeSpID; +int DeltaTID, DensID, AvTempID, ThVelID, PotID, CurrID, SymAngID; // 1D +int MfTempID, TempID, ModeID, ModeSpID, VelID, Flux2ID, SymmID; // 2D -> 3 +int prTenID, mfTenID; // 2D -> 6 +int FluxID; // 2D -> 32 +int TimeID; // Time netCDF variable +int TimeSpID; + +char StartT[TIMELENGTH]; // Start time from data +char StopT[TIMELENGTH]; // Stop time from data +/************************** + Function prototypes +**************************/ +void usage(); +void cdf_handle_error (CDFstatus); +void nc_handle_error (int); +void removeFilepath(); +void removeCDFext(); +void removeVers(); +void ncdefine(); +/*--------------------------------------------------------------------------*/ +void usage() +{ + printf ("\nDescription:\n"); + printf (" This program converts a themis CDF file into a netCDF file.\n"); + printf ("\n"); + printf ("Usage: esa2nc <CDF file name> <ThemisID> <mode>\n"); + printf ("\n"); + printf ("Example: esa2nc testfile tha peif\n"); + printf ("\n"); + exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a CDF error. + *--------------------------------------------------------------------------*/ +void cdf_handle_error(CDFstatus status) +{ + + char message[CDF_STATUSTEXT_LEN+1]; + + CDFerror (status, message); /* Get the appropriate message */ + fprintf (stderr, "CDF: %s\n", message); +// exit(1); +} +/*-------------------------------------------------------------------------- + * Handles a netCDF error. + *--------------------------------------------------------------------------*/ +void nc_handle_error(int status) +{ + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(1); +} + +/*-------------------------------------------------------------------------- + * NetCDF File Definition * + *--------------------------------------------------------------------------*/ + void ncdefine(double Time) + { + char *s; + time_t p; + int status; + char *STime; + +/*********************** Create netCDF file *****************************/ + memcpy(&(ncFile[0]),&(mode[0]), 4); + STime = Double2DD_Time(Time); + memcpy(&(ncFile[4]),&(STime[2]), 9); + if ((status = nc_create(ncFile, NC_CLOBBER, &ncID)) != NC_NOERR) + nc_handle_error(status); +/******************netCDF Dimensions *******************************/ + nc_def_dim (ncID, "Time", NC_UNLIMITED, &TimeDimID); + nc_def_dim (ncID, "TimeLength", TIMELENGTH, &TimeLengthID); + nc_def_dim (ncID, "Flux", 16L, &FluxDimID); + +/********************netCDF Variables ******************/ + TimeDimVector[0] = TimeDimID; + TimeDimVector[1] = TimeLengthID; + FluxDimVector[0] = TimeDimID; + FluxDimVector[1] = FluxDimID; +// + nc_def_var (ncID, "Time", NC_CHAR, 2, TimeDimVector, &TimeID); + + nc_def_var (ncID, "DeltaT", NC_DOUBLE, 1, &TimeDimID, &DeltaTID); + nc_def_var (ncID, "Mode", NC_FLOAT, 2, &TimeDimID, &ModeID); + nc_def_var (ncID, "Flux", NC_DOUBLE, 2, FluxDimVector, &FluxID); + + nc_def_var (ncID, "StartTime",NC_CHAR, 1, &TimeLengthID, &StartTimeID); + nc_def_var (ncID, "StopTime",NC_CHAR, 1, &TimeLengthID , &StopTimeID); + + + + + nc_put_att_text(ncID, NC_GLOBAL, "Themis", 3, ThemisID); + nc_put_att_text(ncID, NC_GLOBAL, "Source", 12, Source); + nc_put_att_text(ncID, FluxID, "Units", 17, "eV/(cm^2-s-sr-eV)"); + + + time(&p); + s = ctime(&p); + nc_put_att_text(ncID, NC_GLOBAL, "Created", 24, s); + + status = nc_enddef(ncID); + + + nc_put_vara_text(ncID, StartTimeID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time)); + + + } + + void put_double(RecStart, RecCount, ParCDF, ParNC) { + + + long RecInt = 1; + long indices[1] = {0}, intervals[1] = {1}, counts[1] = {1}; + + double *value; + + value = (double *)malloc(sizeof(double)*RecCount); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, ParNC, value); + + free(value); + } + + + void put_mode(RecStart, RecCount, ParCDF, ParNC) { + + float *value; + long indices[2] = {0,3}, intervals[1] = {1}, counts[1] = {3}; + long RecInt = 1; + + value = (float *)malloc(sizeof(float) * RecCount *3); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_float(ncID, ParNC, value); + + free(value); + } + +void put_spectra(RecStart, RecCount, ParCDF, ParNC) { + + double *value; + long indices[2] = {0,16}, intervals[1] = {1}, counts[1] = {16}; + long RecInt = 1; + + value = (double *)malloc(sizeof(double)*RecCount*16); + if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, counts, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_)) + != CDF_OK) cdf_handle_error(cstatus); + nc_put_var_double(ncID, ParNC, value); + free(value); + } +/*--------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ + long RecStart = 0, RecCount, RecCountF = 1, RecInt = 1, MaxRec; + long indices[1] = {0}, counts[1] = {3}, counts2[1] = {6}, countsFlux[1] = {32}, intervals[1] = {1}; + long countsE[1] = {1}, indicesF[2]={0,3}, indicesF2[2]={0,6}, indicesFlux[2] = {0, 32}; + double *value; + float *value_f; + size_t numElem; + long dimN, varN, par0, par1, par2; + + CDFid id; + int i, j, status; + char fileName[MAX_FILE_NAME_LEN]; + dd_tmstr_t *dtm; + int First = 1; + double DayOld; + + + char *UT; + char data_set[8]="thx_psxf"; +/*-------------------------------- Arguments Decoding ----------------------------------------*/ + if (argc <= 3) usage(); // CDF input file name and THEMIS Number not specified + else + { + strcpy(fileName, argv[1]); + strncpy(ThemisID,argv[2],3); + strncpy(mode,argv[3],4); + } + +/*------------------------------------------ CDF Variables Names Updated according to THEMIS Number -------------*/ + + memcpy(&(data_set[2]),&(ThemisID[2]),1); + memcpy(&(data_set[6]),&(mode[2]),2); + + memcpy(&(ThemisTime[0]),&(data_set[0]),8); + memcpy(&(PAR0[0]),&(data_set[0]),8); + memcpy(&(PAR1[0]),&(data_set[0]),8); + memcpy(&(PAR2[0]),&(data_set[0]),8); + + +/*********************** Open CDF file *****************************/ + if ((cstatus = CDFopen(fileName, &id)) != CDF_OK) + cdf_handle_error(cstatus); + printf(" THEMIS %s %s\n", ThemisID, mode); + +/*********** treat all vars as zVars with eliminated false dimensionality **********/ + + if ((cstatus = CDFlib(SELECT_, CDF_zMODE_, zMODEon2, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + +/************************ Get CDF Data ************************************/ + + cstatus = CDFlib(GET_, zVAR_NUMBER_, ThemisTime, &varN, NULL_); + cstatus = CDFlib( SELECT_, zVAR_, varN, GET_, zVAR_MAXREC_, &MaxRec, NULL_); + + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR0, &par0, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR1, &par1, NULL_); + cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR2, &par2, NULL_); + + + RecCount = (long)(MaxRec+1); + printf(" Max Rec %d\n", MaxRec); + + value = (double *)malloc(sizeof(double)* RecCount); + if ((cstatus = CDFlib (SELECT_, + zVAR_, varN, + zVAR_RECNUMBER_, RecStart , + zVAR_RECCOUNT_, RecCount, + zVAR_RECINTERVAL_, RecInt, + zVAR_DIMINDICES_, indices, + zVAR_DIMCOUNTS_, countsE, + zVAR_DIMINTERVALS_, intervals, + GET_, zVAR_HYPERDATA_, value, NULL_) ) + != CDF_OK) cdf_handle_error(cstatus); + + for (i = 0; i < RecCount; i++) { + + + UT = Double2DD_Time(value[i]); + + if ((First == 0) && (value[i] - DayOld) > TimeGap) { + + printf("GAP %f\n",(value[i] - DayOld)/60.0); + // put_double(RecStart, (long)i - RecStart, par0, DeltaTID); + // put_mode(RecStart, (long)i - RecStart, par1, ModeID, ModeSpID); + put_spectra(RecStart, (long)i - RecStart, par2, FluxID); + + nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], Double2DD_Time(DayOld)); + + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + + First = 1; + RecStart = (long)i; + UT = Double2DD_Time(value[i]); + } + + dtm = ReadTime(UT); + if (First == 1) { + ncdefine(dtm->times); + + First = 0; + Start[0] = 0; + + } + nc_put_vara_text(ncID, TimeID, Start, TimeCount, UT); + + Start[0]++; + DayOld = value[i]; + + } + free(value); + nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], UT); + + + // put_double(RecStart, RecCount - RecStart, par0, DeltaTID); + // put_mode(RecStart, RecCount - RecStart, par1, ModeID, ModeSpID); + put_spectra(RecStart, RecCount - RecStart, par2, FluxID); + +/********************Close Files******************/ + if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) + cdf_handle_error (cstatus); + if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); + +} diff --git a/src/INCLUDE/DD_comm.h b/src/INCLUDE/DD_comm.h index 440de1c..033f95b 100755 --- a/src/INCLUDE/DD_comm.h +++ b/src/INCLUDE/DD_comm.h @@ -115,8 +115,8 @@ // String length is counted as 4B + N + r (to completed to 4 bytes) /*------------ List of External Call of DD_Server and ERRORS -------------------*/ -#define ADDDATASETCALL "php %s/createVI.php %s %s %s" /* Format to call to create new VI */ -#define GETNEWDATACALL "php %s/getData%s.php %s %s %s %s &" /* Format to call to get new data */ +#define ADDDATASETCALL "php %s/CALLEXT/createVI.php %s %s %s" /* Format to call to create new VI */ +#define GETNEWDATACALL "php %s/CALLEXT/getData%s.php %s %s %s %s &" /* Format to call to get new data */ #define NOPHP 32512 #define NOSCRIPT 256 #define PHPOK 0 -- libgit2 0.21.2