Commit 847ab99616dc9e2fccb7ab63bbe74f9db6eb9997

Authored by Benjamin Renard
2 parents bfe6ede1 dc1a467d

Merge branch 'time-in-double'

scripts/ConvertVIDDTimeToDouble.sh 0 → 100755
... ... @@ -0,0 +1,14 @@
  1 +#!/bin/sh
  2 +
  3 +if [ $# -eq 0 ]
  4 + then
  5 + echo "ViId should be defined"
  6 + exit
  7 + fi
  8 +
  9 +BASEDIR=$(dirname "$0")
  10 +
  11 +. ${BASEDIR}/DDServer.env
  12 +
  13 +php ${DATAMANAGER}/ConvertVIDDTimeToDouble.php $1
  14 +
... ...
src/DATA/MANAGER/ConvertVIDDTimeToDouble.php 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +<?php
  2 +
  3 +if ($argc < 2) {
  4 + echo "[ERROR] Usage : php ".$argv[0]." ViId".PHP_EOL;
  5 + exit(1);
  6 +}
  7 +$ViId = $argv[1];
  8 +
  9 +if (!function_exists('__autoload'))
  10 +{
  11 + function __autoload($class_name) {
  12 + require_once $class_name . '.php';
  13 + }
  14 +}
  15 +
  16 +putenv("LD_LIBRARY_PATH=".getenv("LD_LIBRARY_PATH"));
  17 +putenv("PATH=./:".getenv("DDBASEBIN").":/bin:/usr/bin");
  18 +set_include_path("./:".getenv("DATAMANAGER"));
  19 +
  20 +
  21 +
  22 +$baseMgr = new DDBaseMgr();
  23 +
  24 +$baseMgr->convertVIDDTimeToDouble($ViId);
  25 +
  26 +?>
... ...
src/DATA/MANAGER/DDBaseMgr.php
... ... @@ -381,6 +381,48 @@ class DDBaseMgr
381 381 $this->DDsysDoc->save($this->DDsys);
382 382 system("makeDDsys");
383 383 }
  384 +
  385 + function convertVIDDTimeToDouble($ViId) {
  386 + $XPath = new DOMXpath($this->DDsysDoc);
  387 +
  388 + $dataSet = $XPath->query("//NAME[.='$ViId']");
  389 +
  390 + if ($dataSet->length == 0) {
  391 + echo "[ERROR] NO $ViId in DDsys.xml".PHP_EOL;
  392 + return FALSE;
  393 + }
  394 +
  395 + $dataSet = $dataSet->item(0);
  396 +
  397 + $locationNodes = $dataSet->parentNode->getElementsByTagName('LOCATION');
  398 +
  399 + if ($locationNodes->length == 0) {
  400 + echo "[ERROR] Cannot retrieve LOCATION for $ViId in DDsys.xml".PHP_EOL;
  401 + return FALSE;
  402 + }
  403 +
  404 + $location = $locationNodes->item(0)->nodeValue;
  405 +
  406 +
  407 + if (file_exists($location."/LOCK")) {
  408 + echo "[ERROR] VI $ViId already locked by another process".PHP_EOL;
  409 + return FALSE;
  410 + }
  411 +
  412 + echo "[INFO] Lock VI $ViId".PHP_EOL;
  413 + touch($location."/LOCK");
  414 +
  415 + $WORKING_DIR = getcwd();
  416 + chdir($location);
  417 +
  418 + echo "[INFO] Cleanup VI $ViId".PHP_EOL;
  419 + system("./clean");
  420 + echo "[INFO] Convert data files".PHP_EOL;
  421 + system("ConvertDDTimeToDouble *.nc.gz");
  422 +
  423 + unlink($location."/LOCK");
  424 +
  425 + }
384 426 }
385 427 ?>
386 428  
... ...
src/DATA/TOOLS/ConvertDDTimeToDouble.c 0 → 100755
... ... @@ -0,0 +1,480 @@
  1 +/* $Id: ConvertDDTimeToDouble.c,v 1.0 2019/10/03 13:39:00 benjamin Exp $*/
  2 +/*=====================================================================
  3 + * DD SYSTEM base package
  4 + * DD_Server library
  5 + * ConvertDDTimeToDouble.c
  6 + *
  7 + * usage ConvertDDTimeToDouble
  8 + *
  9 + * Versions:
  10 + *=====================================================================*/
  11 + /*=====================================================================
  12 + * Description:
  13 + * Program to convert DDTime of a list of nc_data_files to timestamp (double). Data file can be gzipped
  14 + *======================================================================*/
  15 +
  16 +#include <stdio.h>
  17 +#include <stdlib.h>
  18 +#include <string.h>
  19 +#include <ctype.h>
  20 +#include <dirent.h>
  21 +#include <netcdf.h>
  22 +#include <math.h>
  23 +#include <DD.h>
  24 +
  25 +/*==================================================================================
  26 + * READ NC FILE INFO
  27 + *==================================================================================*/
  28 +
  29 +typedef struct
  30 +{
  31 + int id;
  32 + char name[NC_MAX_NAME+1];
  33 + size_t length;
  34 + int isUnlimited;
  35 +} NCDimInfo;
  36 +
  37 +typedef struct
  38 +{
  39 + int id;
  40 + char name[NC_MAX_NAME+1];
  41 + size_t length;
  42 + nc_type type;
  43 + void* value;
  44 +} NCAttInfo;
  45 +
  46 +typedef struct
  47 +{
  48 + int id;
  49 + char name[NC_MAX_NAME+1];
  50 + int ndims;
  51 + int dimids[NC_MAX_VAR_DIMS];
  52 + int natts;
  53 + NCAttInfo *atts;
  54 + nc_type type;
  55 +} NCVarInfo;
  56 +
  57 +typedef struct
  58 +{
  59 + int id;
  60 + int ndims;
  61 + NCDimInfo *dims;
  62 + int natts;
  63 + NCAttInfo *atts;
  64 + int nvars;
  65 + NCVarInfo *vars;
  66 +} NCFileInfo;
  67 +
  68 +/*==================================================================================
  69 + * READ NC FILE INFO
  70 + *==================================================================================*/
  71 +
  72 +int readNCFileInfo(char* filePath, NCFileInfo* info)
  73 +{
  74 + memset(info, 0, sizeof(NCFileInfo));
  75 +
  76 + int status = nc_open(filePath, 0, &info->id);
  77 +
  78 + if (status != NC_NOERR) {
  79 + fprintf(stderr,"Cannot open NC file %s\n",filePath);
  80 + return 0;
  81 + }
  82 +
  83 + // General info
  84 + int unlimdimid;
  85 + status = nc_inq(info->id, &info->ndims, &info->nvars, &info->natts, &unlimdimid);
  86 +
  87 + if (status != NC_NOERR) {
  88 + fprintf(stderr,"Cannot retrieve general info of NC file %s\n",filePath);
  89 + return 0;
  90 + }
  91 +
  92 + //Load dims
  93 + int i, j;
  94 + if (info->ndims > 0) {
  95 + info->dims = malloc(info->ndims * sizeof(NCDimInfo));
  96 + }
  97 + for (i = 0; i < info->ndims; ++i) {
  98 + status = nc_inq_dim(info->id, i, info->dims[i].name, &info->dims[i].length);
  99 + if (status != NC_NOERR) {
  100 + fprintf(stderr,"Cannot retrieve dim info %d of NC file %s\n",i,filePath);
  101 + return 0;
  102 + }
  103 + status = nc_inq_dimid(info->id, info->dims[i].name, &info->dims[i].id);
  104 + if (status != NC_NOERR) {
  105 + fprintf(stderr,"Cannot retrieve dim id %d of NC file %s\n",i,filePath);
  106 + return 0;
  107 + }
  108 + info->dims[i].isUnlimited = (unlimdimid == info->dims[i].id);
  109 + }
  110 +
  111 + //Load global attributes
  112 + if (info->natts > 0) {
  113 + info->atts = malloc(info->natts * sizeof(NCAttInfo));
  114 + }
  115 + for (i = 0; i < info->natts; ++i) {
  116 + status = nc_inq_attname(info->id, NC_GLOBAL, i, info->atts[i].name);
  117 + if (status != NC_NOERR) {
  118 + fprintf(stderr,"Cannot retrieve global att name %d of NC file %s\n",i,filePath);
  119 + return 0;
  120 + }
  121 + status = nc_inq_att(info->id, NC_GLOBAL, info->atts[i].name, &info->atts[i].type, &info->atts[i].length);
  122 + if (status != NC_NOERR) {
  123 + fprintf(stderr,"Cannot retrieve global att info %d of NC file %s\n",i,filePath);
  124 + return 0;
  125 + }
  126 + info->atts[i].value = malloc(info->atts[i].length * nctypelen(info->atts[i].type));
  127 + status = nc_get_att(info->id, NC_GLOBAL, info->atts[i].name, info->atts[i].value);
  128 + if (status != NC_NOERR) {
  129 + fprintf(stderr,"Cannot retrieve global att value %d of NC file %s\n",i,filePath);
  130 + }
  131 + }
  132 +
  133 + //Load variables
  134 + if (info->nvars > 0) {
  135 + info->vars = malloc(info->nvars * sizeof(NCVarInfo));
  136 + }
  137 + for (i = 0; i < info->nvars; ++i) {
  138 + status = nc_inq_var(info->id, i, info->vars[i].name, &info->vars[i].type, &info->vars[i].ndims, info->vars[i].dimids, &info->vars[i].natts);
  139 + if (status != NC_NOERR) {
  140 + fprintf(stderr,"Cannot retrieve variable info %d of NC file %s\n",i,filePath);
  141 + return 0;
  142 + }
  143 + //Load variable attributes
  144 + if (info->vars[i].natts > 0) {
  145 + info->vars[i].atts = malloc(info->vars[i].natts * sizeof(NCAttInfo));
  146 + }
  147 + for (j = 0; j < info->vars[i].natts; ++j) {
  148 + status = nc_inq_attname(info->id, i, j, info->vars[i].atts[j].name);
  149 + if (status != NC_NOERR) {
  150 + fprintf(stderr,"Cannot retrieve variable %d att name %d of NC file %s\n",i,j,filePath);
  151 + return 0;
  152 + }
  153 + status = nc_inq_att(info->id, i, info->vars[i].atts[j].name, &info->vars[i].atts[j].type, &info->vars[i].atts[j].length);
  154 + if (status != NC_NOERR) {
  155 + fprintf(stderr,"Cannot retrieve variable %d att info %d of NC file %s\n",i,j,filePath);
  156 + return 0;
  157 + }
  158 + info->vars[i].atts[j].value = malloc(info->vars[i].atts[j].length * nctypelen(info->vars[i].atts[j].type));
  159 + status = nc_get_att(info->id, i, info->vars[i].atts[j].name, info->vars[i].atts[j].value);
  160 + if (status != NC_NOERR) {
  161 + fprintf(stderr,"Cannot retrieve variable %d att value %d of NC file %s\n",i,j,filePath);
  162 + }
  163 + }
  164 + }
  165 +
  166 + return 1;
  167 +}
  168 +
  169 +/*==================================================================================
  170 + * CLOSE NC FILE and free memory
  171 + *==================================================================================*/
  172 +
  173 +void closeNCFile(NCFileInfo* info) {
  174 + int i,j;
  175 +
  176 + if (info->ndims > 0) {
  177 + free(info->dims);
  178 + }
  179 +
  180 + if (info->natts > 0) {
  181 + for (i = 0; i < info->natts; ++i) {
  182 + if (info->atts[i].value != NULL) {
  183 + free(info->atts[i].value);
  184 + }
  185 + }
  186 + free(info->atts);
  187 + }
  188 +
  189 + if (info->nvars > 0) {
  190 + for (i = 0; i < info->nvars; ++i) {
  191 + if (info->vars[i].natts > 0) {
  192 + for (j = 0; j < info->vars[i].natts; ++j) {
  193 + if (info->vars[i].atts[j].value != NULL) {
  194 + free(info->vars[i].atts[j].value);
  195 + }
  196 + }
  197 + free(info->vars[i].atts);
  198 + }
  199 + }
  200 + free(info->vars);
  201 + }
  202 +
  203 + int status = nc_close(info->id);
  204 +
  205 + if (status != NC_NOERR) {
  206 + fprintf(stderr,"Cannot close NC file\n");
  207 + }
  208 +
  209 + memset(info, 0, sizeof(NCFileInfo));
  210 +}
  211 +
  212 +/*==================================================================================
  213 + * convertDDTimeToDouble
  214 + *==================================================================================*/
  215 +
  216 +void convertDDTimeToDouble(void* values, void* values_converted, int nbRecs) {
  217 + int i;
  218 + double TimeStampValue;
  219 + char DDTimeValue[TIMELENGTH+1];
  220 + memset(DDTimeValue,0,(TIMELENGTH+1)*sizeof(char));
  221 + for (i = 0; i < nbRecs; ++i) {
  222 + memcpy(DDTimeValue, values + i * (TIMELENGTH*sizeof(char)), TIMELENGTH*sizeof(char));
  223 + TimeStampValue = DD_Time2Double(DDTimeValue);
  224 + memcpy(values_converted + i * sizeof(double), &TimeStampValue, sizeof(double));
  225 + }
  226 +}
  227 +
  228 +/*==================================================================================
  229 + * CONVERT NC FILE
  230 + *==================================================================================*/
  231 +
  232 +#define CONV_OK 1
  233 +#define CONV_NOTNEED 2
  234 +#define CONV_ERROR 0
  235 +
  236 +int convertNCFile(char* oldFilePath, char* newFilePath) {
  237 + char TimeName[] = "Time";
  238 +
  239 + //Read info of old NC file
  240 + NCFileInfo info;
  241 + int status = readNCFileInfo(oldFilePath,&info);
  242 + if (status == 0) {
  243 + closeNCFile(&info);
  244 + return CONV_ERROR;
  245 + }
  246 +
  247 + //Retrieve time in old file
  248 + int oldFileTimeVarIndex = -1;
  249 + int i;
  250 + for (i = 0; i < info.nvars; ++i) {
  251 + if (strcmp(info.vars[i].name, TimeName) == 0) {
  252 + oldFileTimeVarIndex = i;
  253 + break;
  254 + }
  255 + }
  256 + if (oldFileTimeVarIndex < 0) {
  257 + fprintf(stderr,"Cannot retrieve %s variable in old NC file\n", TimeName);
  258 + closeNCFile(&info);
  259 + return CONV_ERROR;
  260 + }
  261 +
  262 + if (info.vars[oldFileTimeVarIndex].type == NC_DOUBLE) {
  263 + //Time is already in double format => Nothing to do
  264 + closeNCFile(&info);
  265 + return CONV_NOTNEED;
  266 + }
  267 +
  268 + //Retrieve time dim in old file
  269 + int oldFileTimeDimIndex = -1;
  270 + int isTimeUnlimitedDim = 0;
  271 + for (i = 0; i < info.ndims; ++i) {
  272 + if (info.dims[i].id == info.vars[oldFileTimeVarIndex].dimids[0]) {
  273 + oldFileTimeDimIndex = i;
  274 + isTimeUnlimitedDim = info.dims[i].isUnlimited;
  275 + break;
  276 + }
  277 + }
  278 +
  279 + //Create new file
  280 + int newFileId;
  281 + status = nc_create(newFilePath, NC_CLOBBER, &newFileId);
  282 +
  283 + if (status != NC_NOERR) {
  284 + fprintf(stderr,"Cannot create NC file %s %s\n",newFilePath,nc_strerror(status));
  285 + closeNCFile(&info);
  286 + return CONV_ERROR;
  287 + }
  288 +
  289 + //Create dimensions in new file
  290 + int tmpId;
  291 + for (i = 0; i < info.ndims; ++i) {
  292 + status = nc_def_dim(newFileId, info.dims[i].name, (info.dims[i].isUnlimited == 1) ? NC_UNLIMITED : info.dims[i].length, &tmpId);
  293 + if (status != NC_NOERR) {
  294 + fprintf(stderr,"Cannot create dim %d in new file %s\n",i,newFilePath);
  295 + closeNCFile(&info);
  296 + return CONV_ERROR;
  297 + }
  298 + }
  299 +
  300 + //Create global attributes in new file
  301 + for (i = 0; i < info.natts; ++i) {
  302 + status = nc_put_att(newFileId, NC_GLOBAL, info.atts[i].name, info.atts[i].type, info.atts[i].length, info.atts[i].value);
  303 + if (status != NC_NOERR) {
  304 + fprintf(stderr,"Cannot create global att %d in new file %s\n",i,newFilePath);
  305 + closeNCFile(&info);
  306 + return CONV_ERROR;
  307 + }
  308 + }
  309 +
  310 + //Create variables in new file
  311 + int j;
  312 + for (i = 0; i < info.nvars; ++i) {
  313 + if (oldFileTimeVarIndex == i) {
  314 + status = nc_def_var(newFileId, info.vars[i].name, NC_DOUBLE, 1, info.vars[i].dimids, &tmpId);
  315 + }
  316 + else {
  317 + status = nc_def_var(newFileId, info.vars[i].name, info.vars[i].type, info.vars[i].ndims, info.vars[i].dimids, &tmpId);
  318 + }
  319 + if (status != NC_NOERR) {
  320 + fprintf(stderr,"Cannot create var %d in new file %s\n",i,newFilePath);
  321 + closeNCFile(&info);
  322 + return CONV_ERROR;
  323 + }
  324 + //Create variable attributes
  325 + for (j = 0; j < info.vars[i].natts; ++j) {
  326 + status = nc_put_att(newFileId, i, info.vars[i].atts[j].name, info.vars[i].atts[j].type, info.vars[i].atts[j].length, info.vars[i].atts[j].value);
  327 + if (status != NC_NOERR) {
  328 + fprintf(stderr,"Cannot create local att %d for var %d in new file %s\n",j,i,newFilePath);
  329 + closeNCFile(&info);
  330 + return CONV_ERROR;
  331 + }
  332 + }
  333 + }
  334 +
  335 + status = nc_enddef(newFileId);
  336 +
  337 + void* values;
  338 + void* values_converted;
  339 + int k;
  340 + int size;
  341 + size_t* start;
  342 + size_t* count;
  343 + for (i = 0; i < info.nvars; ++i) {
  344 + start = malloc(info.vars[i].ndims * sizeof(size_t));
  345 + count = malloc(info.vars[i].ndims * sizeof(size_t));
  346 + //Load old values
  347 + size = 1;
  348 + for (j = 0; j < info.vars[i].ndims; ++j) {
  349 + start[j] = 0;
  350 + for (k = 0; k < info.ndims; ++k) {
  351 + if (info.vars[i].dimids[j] == info.dims[k].id) {
  352 + count[j] = info.dims[k].length;
  353 + size *= info.dims[k].length;
  354 + break;
  355 + }
  356 + }
  357 + }
  358 + values = malloc(size * nctypelen(info.vars[i].type));
  359 + status = nc_get_vara(info.id, i, start, count, values);
  360 + if (status != NC_NOERR) {
  361 + fprintf(stderr,"Cannot load var values %d from old file %s\n",i,oldFilePath);
  362 + free(values);
  363 + free(start);
  364 + free(count);
  365 + closeNCFile(&info);
  366 + return CONV_ERROR;
  367 + }
  368 + //Copy or convert values
  369 + if (oldFileTimeVarIndex == i) {
  370 + values_converted = malloc(size * nctypelen(NC_DOUBLE));
  371 + convertDDTimeToDouble(values, values_converted, count[0]);
  372 + status = nc_put_vara(newFileId, i, start, count, values_converted);
  373 + free(values_converted);
  374 + }
  375 + else {
  376 + status = nc_put_vara(newFileId, i, start, count, values);
  377 + }
  378 + free(values);
  379 + free(start);
  380 + free(count);
  381 + if (status != NC_NOERR) {
  382 + fprintf(stderr,"Cannot copy var values %d in new file %s\n",i,newFilePath);
  383 + closeNCFile(&info);
  384 + return CONV_ERROR;
  385 + }
  386 + }
  387 +
  388 + nc_close(newFileId);
  389 +
  390 + closeNCFile(&info);
  391 + return CONV_OK;
  392 +}
  393 +
  394 +/*==================================================================================
  395 + * MAIN
  396 + *==================================================================================*/
  397 +
  398 +#define COMMAND_MAX_LEN 1000
  399 +#define MAX_FILENAME_LEN 100
  400 +
  401 +main(int argc, char **argv)
  402 +{
  403 + static char usage[] = "usage: ConvertDDTimeToDouble nc_data_file[*.gz]";
  404 +
  405 + if (argc < 2) {fprintf(stderr,"%s\n",usage); exit(1); }
  406 +
  407 + char inputFileName[MAX_FILENAME_LEN+1];
  408 + char unzippedFileName[MAX_FILENAME_LEN+1];
  409 + char workingFileName[] = "ConvertDDTimeToDouble.nc";
  410 + char command[COMMAND_MAX_LEN+1];
  411 + int i;
  412 + int zippedFile = 0;
  413 + int status;
  414 +
  415 + for (i = 1; i < argc; ++i) {
  416 + if (strlen(argv[i]) > MAX_FILENAME_LEN)
  417 + {
  418 + fprintf(stderr,"File name size exceed the max size : %s\n",argv[i]);
  419 + continue;
  420 + }
  421 +
  422 + memset(inputFileName, 0, (MAX_FILENAME_LEN+1) * sizeof(char));
  423 + strcpy(inputFileName,argv[i]);
  424 +
  425 + memset(command, 0, (COMMAND_MAX_LEN+1) * sizeof(char));
  426 + if((strlen(inputFileName) > 3) && (strcmp(inputFileName+strlen(inputFileName)-3,".gz") == 0)) // Zipped file
  427 + {
  428 + strcpy(unzippedFileName, inputFileName);
  429 + unzippedFileName[strlen(inputFileName)-3] = '\0';
  430 + sprintf(command,"gunzip -c %s > %s",inputFileName,unzippedFileName);
  431 + zippedFile = 1;
  432 + }
  433 + else {
  434 + zippedFile = 0;
  435 + strcpy(unzippedFileName, inputFileName);
  436 + }
  437 +
  438 + status = system(command);
  439 + if (status != 0) {
  440 + fprintf(stderr,"Cannot create working input file for %s\n",argv[i]);
  441 + continue;
  442 + }
  443 +
  444 + status = convertNCFile(unzippedFileName, workingFileName);
  445 + if (status == CONV_NOTNEED) {
  446 + fprintf(stderr,"[WARNING] File %s already converted\n", inputFileName);
  447 + continue;
  448 + }
  449 + else if (status == CONV_ERROR) {
  450 + fprintf(stderr,"[ERROR] Error detected during %s file conversion\n", inputFileName);
  451 + continue;
  452 + }
  453 +
  454 + memset(command, 0, (COMMAND_MAX_LEN+1) * sizeof(char));
  455 + sprintf(command,"cp -p %s %s",workingFileName,unzippedFileName);
  456 + status = system(command);
  457 + if (status != 0) {
  458 + fprintf(stderr,"[ERROR] Cannot copy result file in %s\n",inputFileName);
  459 + continue;
  460 + }
  461 +
  462 + if (zippedFile == 1) {
  463 + memset(command, 0, (COMMAND_MAX_LEN+1) * sizeof(char));
  464 + sprintf(command,"gzip -f %s",unzippedFileName);
  465 + status = system(command);
  466 + if (status != 0) {
  467 + fprintf(stderr,"[ERROR] Cannot compress result file\n");
  468 + }
  469 + }
  470 +
  471 + fprintf(stderr,"[INFO] File %s converted\n", inputFileName);
  472 + }
  473 +
  474 + memset(command, 0, (COMMAND_MAX_LEN+1) * sizeof(char));
  475 + sprintf(command,"rm -f %s",workingFileName);
  476 + status = system(command);
  477 +
  478 + return(0);
  479 +}
  480 +/*=========================================================================================================*/
... ...
src/SERVER/DD_GetData.c
... ... @@ -508,20 +508,16 @@ int GetAttribute(int ID, char *VarName)
508 508 */
509 509 {
510 510 static int *VarID = NULL; /* IDs of requested Parameters of this VI */
511   - static char TimeStr[TIMELENGTH];
512   - static char TimeName[] = "Time";
513 511 static int TimeID;
  512 + static int TimeIsDouble = 0;
514 513 //static size_t DimArray[NC_MAX_DIMS];
515 514 static size_t **DimArrayS = NULL; /* Several Dimensions arrays */
516 515 size_t *DimArray; /* Local Dimension Array (for the specific parameter */
517 516 static int DimIDArray[NC_MAX_DIMS];
518 517 static nc_type type;
519 518 static size_t start[NC_MAX_DIMS];
520   - static size_t TimeCount[2] = {1,TIMELENGTH};
521   - static size_t TimeStart[2] = {0,0};
522 519 static int Scalar = 0; /* indicator of scalar value */
523 520 static int String = 0; /* indicator of single (not timed) string March 9 1997 */
524   - static int TimeTypeValue = 0; /* indicator of time type value */
525 521 static size_t RecordSize; /* Size of one record in terms of variables of specified type */
526 522 static size_t *PacketSize=NULL; /* Packets sizes of one record (of specified variable) */
527 523 static size_t RecordNumber; /* Variable maximal number of records in one packet */
... ... @@ -691,16 +687,24 @@ int GetAttribute(int ID, char *VarName)
691 687 /*---------------------------------------------
692 688 * Define time ID
693 689 *--------------------------------------------*/
694   - status = nc_inq_varid(CurrncID,TimeName,&TimeID);
  690 + TimeID = Time_GetVarID(CurrncID);
  691 + if (TimeID < 0)
  692 + {
  693 + if(Verbose) fprintf(stderr,"GetMultiData(%d): Error in time var detection\n",ID);
  694 + return(DATAFILEERR);
  695 + }
  696 +
  697 + TimeIsDouble = Time_IsDoubleVar(CurrncID, TimeID);
  698 +
  699 + if(Verbose) fprintf(stderr,"GetMultiData(%d): TimeID = %d - TimeIsDouble = %d\n",ID,TimeID,TimeIsDouble);
  700 +
695 701 /*------------------------------------------------------------------------------------------
696 702 * Reseting VarNumber and create a new local data structure
697 703 * Also we need to set Time limit constants
698 704 *------------------------------------------------------------------------------------------*/
699 705 if(DD_Var[ID]->LastPacketFlag == OK) /* Very new request, after SetTime() */
700 706 {
701   - TimeStart[0] = DD_Var[ID]->nc_rec;
702   - status = nc_get_vara_text(DD_Var[ID]->ncID,TimeID,TimeStart,TimeCount,TimeStr);
703   - DD_Var[ID]->CDTime = DD_Time2Double(TimeStr); /* Current time of record */
  707 + DD_Var[ID]->CDTime = Time_GetValueFromVar(DD_Var[ID]->ncID,TimeID,TimeIsDouble,DD_Var[ID]->nc_rec); /* Current time of record */
704 708 DD_Var[ID]->SDTime = DD_Var[ID]->CDTime; /* Start time of record */
705 709 DD_Var[ID]->FDTime = DD_Var[ID]->SDTime + DD_Time2Double(TimeInt);
706 710 }
... ... @@ -860,9 +864,7 @@ int GetAttribute(int ID, char *VarName)
860 864  
861 865 /*---------- Define START from LOCAL struct and read current Time ----------*/
862 866 start[0] = Local.nc_rec;
863   - TimeStart[0] = Local.nc_rec;
864   - status = nc_get_vara_text(Local.ncID,TimeID,TimeStart,TimeCount,TimeStr);
865   - Local.CDTime = DD_Time2Double(TimeStr); /* Current time of record */
  867 + Local.CDTime = Time_GetValueFromVar(Local.ncID, TimeID, TimeIsDouble, Local.nc_rec);
866 868 //fprintf(stderr,"GetData(%d): Start %f Current %f Stop %f\n",ID,Local.SDTime,Local.CDTime,Local.FDTime);
867 869  
868 870 //-------------- Check if we have to return by time --------------
... ... @@ -1239,6 +1241,7 @@ int SetTime(DD_Var_t *DD_VarL, double VCTime)
1239 1241 More = 1;
1240 1242 Rmin = 0; Rmax = DD_VarL->Maxnc_rec - 1;
1241 1243  
  1244 + int TimeIsDouble = Time_IsDoubleVar(DD_VarL->ncID, TimeID);
1242 1245 do
1243 1246 {
1244 1247 start[0] = (Rmin + Rmax)/2;
... ... @@ -1246,8 +1249,7 @@ int SetTime(DD_Var_t *DD_VarL, double VCTime)
1246 1249 if(start[0] > Rmax) { DD_VarL->nc_rec = Rmax; More = 0;}
1247 1250 if(More > 0)
1248 1251 {
1249   - status = nc_get_vara_text(DD_VarL->ncID, TimeID,start,TimeCount,StartTime);
1250   - TestTime = DD_Time2Double(StartTime);
  1252 + TestTime = Time_GetValueFromVar(DD_VarL->ncID, TimeID, TimeIsDouble, start[0]);
1251 1253  
1252 1254 if(CTime >= TestTime)
1253 1255 {
... ... @@ -1263,8 +1265,7 @@ int SetTime(DD_Var_t *DD_VarL, double VCTime)
1263 1265 return 1;
1264 1266 }
1265 1267 start[0]++;
1266   - status = nc_get_vara_text(DD_VarL->ncID, TimeID,start,TimeCount,StartTime);
1267   - TestTime = DD_Time2Double(StartTime);
  1268 + TestTime = Time_GetValueFromVar(DD_VarL->ncID, TimeID, TimeIsDouble, start[0]);
1268 1269 if(CTime <= TestTime)
1269 1270 {
1270 1271 DD_VarL->nc_rec = start[0];
... ... @@ -1287,8 +1288,7 @@ int SetTime(DD_Var_t *DD_VarL, double VCTime)
1287 1288 else
1288 1289 {
1289 1290 start[0]--;
1290   - status = nc_get_vara_text(DD_VarL->ncID, TimeID,start,TimeCount,StartTime);
1291   - TestTime = DD_Time2Double(StartTime);
  1291 + TestTime = Time_GetValueFromVar(DD_VarL->ncID, TimeID, TimeIsDouble, start[0]);
1292 1292 if(CTime >= TestTime)
1293 1293 {
1294 1294 DD_VarL->nc_rec = start[0] +1;
... ...
src/SERVER/DD_TimeVar.c 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +/*=====================================================================
  2 + * DD SYSTEM base package
  3 + * DD_Server library
  4 + * DD_TimeVar.c
  5 + * V.1.0
  6 + * Last revision:
  7 + * June 03 2019: Version 1.0. Common methods used for time variable
  8 + */
  9 +
  10 +#include <netcdf.h>
  11 +#include "DD.h"
  12 +#include "DD_comm.h"
  13 +
  14 +int Time_GetVarID(int ncID) {
  15 + static char TimeName[] = "Time";
  16 + int status = NC_NOERR;
  17 + int TimeID = -1;
  18 + status = nc_inq_varid(ncID, TimeName, &TimeID);
  19 + if (status != NC_NOERR) {
  20 + return -1;
  21 + }
  22 + return TimeID;
  23 +}
  24 +
  25 +int Time_IsDoubleVar(int ncID, int timeVarID) {
  26 + nc_type TimeType;
  27 + int status = NC_NOERR;
  28 + status = nc_inq_var (ncID, timeVarID, NULL, &TimeType, NULL, NULL, NULL);
  29 + if (status != NC_NOERR) {
  30 + return 0;
  31 + }
  32 + return (TimeType == NC_DOUBLE) ? 1 : 0;
  33 +}
  34 +
  35 +double Time_GetValueFromTextVar(int ncID, int timeVarID, int recNum) {
  36 + static char TimeStr[TIMELENGTH];
  37 + static size_t TimeCountText[2] = {1,TIMELENGTH};
  38 + size_t TimeStartText[2] = {recNum,0};
  39 + int status = NC_NOERR;
  40 + status = nc_get_vara_text(ncID,timeVarID,TimeStartText,TimeCountText,TimeStr);
  41 + if (status != NC_NOERR) {
  42 + return 0.;
  43 + }
  44 + return DD_Time2Double(TimeStr);
  45 +}
  46 +
  47 +double Time_GetValueFromDoubleVar(int ncID, int timeVarID, int recNum) {
  48 + static size_t TimeCountDouble[1] = {1};
  49 + size_t TimeStartDouble[1] = {recNum};
  50 + double val;
  51 + int status = NC_NOERR;
  52 + status = nc_get_vara_double (ncID,timeVarID,TimeStartDouble,TimeCountDouble,&val);
  53 + if (status != NC_NOERR) {
  54 + return 0.;
  55 + }
  56 + return val;
  57 +}
  58 +
  59 +double Time_GetValueFromVar(int ncID, int timeVarID, int isDoubleTime, int recNum) {
  60 + if (isDoubleTime) {
  61 + return Time_GetValueFromDoubleVar(ncID, timeVarID, recNum);
  62 + }
  63 + return Time_GetValueFromTextVar(ncID, timeVarID, recNum);
  64 +}
  65 +
... ...
tests/CMakeLists.txt
... ... @@ -12,12 +12,18 @@ file(
12 12 ./*
13 13 )
14 14  
15   -ADD_EXECUTABLE (testParallel ${source_files} )
16   -
  15 +ADD_EXECUTABLE (testParallel testParallel.c )
17 16 target_link_libraries(
18 17 testParallel
19 18 ${CMAKE_THREAD_LIBS_INIT}
20 19 ${DDCLIENTLIBRARY}
21 20 )
22 21  
23   -install (TARGETS testParallel DESTINATION tests)
  22 +ADD_EXECUTABLE (testGetData testGetData.c )
  23 +target_link_libraries(
  24 + testGetData
  25 + ${CMAKE_THREAD_LIBS_INIT}
  26 + ${DDCLIENTLIBRARY}
  27 +)
  28 +
  29 +install (TARGETS testParallel testGetData DESTINATION tests)
... ...
tests/testGetData.c 0 → 100644
... ... @@ -0,0 +1,82 @@
  1 +/*=============================================================
  2 + * testGetData.c
  3 + * Test data collection for a a given parameter (hard coded)
  4 + * Oct 2019, V.1.0, Renard
  5 + *=============================================================*/
  6 +#include <stdio.h>
  7 +#include <stdlib.h>
  8 +#include <unistd.h>
  9 +#include <DD.h>
  10 +#include <time.h>
  11 +#include <string.h>
  12 +#include <sys/time.h>
  13 +
  14 +#define DATA_VI "mes:mag:orb\0"
  15 +#define DATA_STARTTIME "2012000000000000\0"
  16 +#define DATA_TIMEINT "0000010000000000\0"
  17 +#define DATA_TIMENAME "Time\0"
  18 +#define DATA_PARAMNAME "B_MSO\0"
  19 +
  20 +
  21 +/*
  22 + * Main
  23 + */
  24 +int main()
  25 +{
  26 + char ViName[100];
  27 + char StartTime[17];
  28 + char TimeInt[17];
  29 + char ParamName[100];
  30 + char TimeName[100];
  31 +
  32 + strcpy(ViName,DATA_VI);
  33 + strcpy(StartTime, DATA_STARTTIME);
  34 + strcpy(TimeInt, DATA_TIMEINT);
  35 + strcpy(ParamName, DATA_PARAMNAME);
  36 + strcpy(TimeName, DATA_TIMENAME);
  37 +
  38 + char* ParNames[2] = {TimeName, ParamName};
  39 +
  40 + int ID, error;
  41 +
  42 + double RealTime;
  43 + DD_data_t *data;
  44 +
  45 + ID = DD_SetVariable(ViName);
  46 + if(ID < 0)
  47 + {
  48 + error = DD_Close(99);
  49 + printf("[ERROR]\n");
  50 + return 0;
  51 + }
  52 +
  53 + error = DD_SetTimeInfo(ID, StartTime, &RealTime);
  54 + if(error < 0)
  55 + {
  56 + error = DD_Close(ID);
  57 + printf("[ERROR]\n");
  58 + return 0;
  59 + }
  60 +
  61 + do
  62 + {
  63 + error = DD_GetMultiData(ID, 2, ParNames, TimeInt, &data, 1);
  64 + if(error < 0)
  65 + {
  66 + error = DD_Close(ID);
  67 + printf("[ERROR]\n");
  68 + return 0;
  69 + }
  70 + if(error == MOREDELAY)
  71 + {
  72 + error = MOREDATA;
  73 + }
  74 + }
  75 + while(error == MOREDATA);
  76 +
  77 + error = DD_Close(ID);
  78 +
  79 + printf("[SUCESS]\n");
  80 +
  81 + return 1;
  82 +}
... ...