From 1329c3beb44e722b1c3dfd08e32d476fd84ff82b Mon Sep 17 00:00:00 2001 From: cvs Date: Wed, 10 May 2000 09:22:35 +0000 Subject: [PATCH] new version of tecs_dlog (now in fortran) --- tecs/Makefile | 7 +- tecs/tecs.c | 236 ++++++++++++++++++++------------- tecs/tecs_cli.c | 2 +- tecs/tecs_dlog.c | 299 ----------------------------------------- tecs/tecs_dlog.f | 321 +++++++++++++++++++++++++++++++++++++++++++++ tecs/tecs_dlog.h | 49 +------ tecs/tecs_dlog.inc | 9 ++ 7 files changed, 486 insertions(+), 437 deletions(-) delete mode 100644 tecs/tecs_dlog.c create mode 100644 tecs/tecs_dlog.f create mode 100644 tecs/tecs_dlog.inc diff --git a/tecs/Makefile b/tecs/Makefile index 242d1ef6..28cb4809 100644 --- a/tecs/Makefile +++ b/tecs/Makefile @@ -11,6 +11,9 @@ OBJ= tecs_cli.o coc_client.o coc_util.o err_handling.o \ CC=cc CFLAGS= -std1 -g -warnprotos -I../ -I. -I../hardsup +.f.o: + f77 -c -g $*.f + .c.o: $(CC) $(CFLAGS) -c $*.c @@ -19,9 +22,7 @@ tecs: $(OBJ) ar cr libtecsl.a $(OBJ) ranlib libtecsl.a - rm TecsServer - $(CC) $(CFLAGS) -o TecsServer -g tecs.c fortify1.c -lm -L. -ltecsl -L../hardsup -lhlib - - rm tecs - f77 -o tecs -g test.for tecs_tas.for get_lun.for -L. -ltecsl + $(CC) $(CFLAGS) -o TecsServer -g tecs.c fortify1.c -lm -L. -ltecsl -L../hardsup -lhlib -lfor clean: rm *.o rm *.a diff --git a/tecs/tecs.c b/tecs/tecs.c index 055027a3..673efa43 100644 --- a/tecs/tecs.c +++ b/tecs/tecs.c @@ -21,7 +21,6 @@ static SerChannel *ser=NULL; static char *serverId=NULL; static char *binDir=NULL; static char *logDir=NULL; -static DlogSet dset; typedef struct { float temp, t1, t2; /* calc, high, low temperature */ @@ -54,7 +53,7 @@ static float tInt=0; /* integral time (sec.) for setpoint shift */ static int - logPeriod=10, /* data logging period (sec.) */ + logPeriod=0, /* data logging period (sec.) */ period=5000, /* default read interval (msec.) */ logTime, /* next logging time */ setFlag, /* temperature to be set */ @@ -62,7 +61,7 @@ static int noResp=1, /* no response */ quit, /* quit server */ controlMode=2, /* 0: control on heater, 1: control on sample, 3: 2nd loop for difference heater-sample */ - mode=2, /* 0: local, 2: remote */ + remoteMode, /* 1: local, 2: remote */ maxfld, /* last used display field */ busy, /* busy after CRVSAV */ deviceFlag, /* device given via net */ @@ -78,7 +77,6 @@ static int per; /* effective period */ static time_t - auto_remote_time, /* time for automatic reload */ tim, /* actual time */ tableTime; /* last time when table was read */ @@ -86,11 +84,12 @@ static int decod[8]={21,20,17,16,5,4,1,0}; /* for code conversion */ static char status[132], /* status buffer */ - device[32], /* concatenated device names */ + device[64], /* concatenated device names */ buf1[256], buf2[256], buf3[256], buf4[256], /* buffers for temporary use */ head[64], /* curve header */ intype[64], /* input configuration */ - chan[2]; /* actual channel */ + chan[2], /* actual channel */ + dlogfile[128]; static char *table=NULL, /* environment devices table */ @@ -112,6 +111,38 @@ void concatDevice(void) { str_append(device, "/"); str_append(device, samp.device); } + if (cryo.manual) { + str_append(device, " (manual"); + } else { + str_append(device, " (auto"); + } + if (samp.manual==cryo.manual) { + str_append(device, ")"); + } else if (samp.manual) { + str_append(device, "/manual)"); + } else { + str_append(device, "/auto)"); + } +} + +int putPermanentData(FILE *fil) { + char buf[256]; + char *d1, *d2; + + if (cryo.manual) { + d1="*"; + } else { + d1=""; + } + if (samp.manual) { + d2="*"; + } else { + d2=""; + } + sprintf(buf, "%s%s/%s%s/%d/%d\n", d1, cryo.device, d2, samp.device, cryo.code, samp.code); + ERR_SI(fputs(buf, fil)); + return(0); + OnError: return(-1); } int instCurve(char *nam, char *channel) { @@ -123,7 +154,7 @@ int instCurve(char *nam, char *channel) { *s, /* start of found entry */ *e, /* cache part after found entry */ *res, *t; - int i, n; + int i, n, c1, c2; char used[60]; FILE *fil; int retstat; @@ -208,7 +239,8 @@ int instCurve(char *nam, char *channel) { if (head[0]!='\0' && LscEqPar(head, chead)) { /* header matches: select sensor type and curve */ retstat=-1; /* an error could be fixed */ - ERR_P(LscCmd(ser, "INTYPE [chan]:[intype];INCRV [chan]:[num];DISPFLD [fld],[chan],1;DISPLAY:[maxfld]")); + ERR_P(LscCmd(ser, "RANGE:0;INTYPE [chan]:[intype];INCRV [chan]:[num]")); + ERR_P(LscCmd(ser, "DISPFLD [fld],[chan],1;DISPLAY:[maxfld]")); logfileOut(LOG_MAIN, "curve %d on channel %s selected\n", num, chan); Progress(100); @@ -220,7 +252,8 @@ int instCurve(char *nam, char *channel) { if (busy) ERR_MSG("busy"); logfileOut(LOG_MAIN, "download curve %d\n", num); /* select sensor type first to display sensor units */ - ERR_P(LscCmd(ser, "INTYPE [chan]:[intype];DISPFLD [fld],[chan],3;DISPLAY:[maxfld]")); + ERR_P(LscCmd(ser, "RANGE:0;INTYPE [chan]:[intype]")); + ERR_P(LscCmd(ser, "DISPFLD [fld],[chan],3;DISPLAY:[maxfld]")); Progress(1); n=3; @@ -264,10 +297,7 @@ int instCurve(char *nam, char *channel) { str_append(nbuf, lbuf); fil=fopen(nbuf, "r+"); if (fil==NULL) ERR_SP(fil=fopen(nbuf, "w")); - if (cryo.manual) ERR_SI(fputs(cryo.device, fil)); - ERR_SI(fputs("/", fil)); - if (samp.manual) ERR_SI(fputs(samp.device, fil)); - ERR_SI(fputs("\n", fil)); + ERR_I(putPermanentData(fil)); sprintf(buf, "%d:%s", num, head); ERR_SI(fputs(buf, fil)); /* write actual entry */ if (start!=s) { /* write content before replaced entry */ @@ -365,10 +395,7 @@ int loadCache(void) { str_copy(nbuf, logDir); str_append(nbuf, lbuf); ERR_SP(fil=fopen(nbuf, "w")); - if (cryo.manual) ERR_SI(fputs(cryo.device, fil)); - ERR_SI(fputs("/", fil)); - if (samp.manual) ERR_SI(fputs(samp.device, fil)); - ERR_SI(fputs("\n", fil)); + ERR_I(putPermanentData(fil)); bufi[0]=buf1; bufi[1]=buf2; bufi[2]=buf3; @@ -436,15 +463,15 @@ int SetTemp(int switchOn) { tShift=0; } str_copy(chan, ch); - if (scale!=1.0) { + if (scale!=1.0) { /* show set point on display (for rdrn) */ ERR_P(LscCmd(ser, "LINEAR C,1,0,1,1,[tempC]")); } - if (tempC==0) { - ERR_P(LscCmd(ser, "RANGE:0;SETP 1:0")); - return(0); - } tempH=(tempC+tShift)/scale; - if (switchOn) { + if (tempC==0) { + ERR_P(LscCmd(ser, "CSET 1:[chan],1,1,0;RANGE:0;SETP 1:0")); + } else if (remoteMode==1) { /* local mode: do not switch on heater */ + ERR_P(LscCmd(ser, "SETP 1:[tempH]")); + } else if (switchOn) { ERR_P(LscCmd(ser, "CSET 1:[chan],1,1,0;RANGE:[iRange];SETP 1:[tempH]")); } else { ERR_P(LscCmd(ser, "CSET 1:[chan],1;SETP 1:[tempH]")); @@ -496,7 +523,7 @@ int ReadTemp(void) { && !samp.dirty && samp.codDefined && !samp.codChanged && !cryo.dirty && cryo.codDefined && !cryo.codChanged) { configuring=0; - } else if (configuring==0) { + } else if (configuring==0 && remoteMode==2) { str_copy(status, "configuring"); configuring=1; } @@ -506,31 +533,26 @@ int ReadTemp(void) { int PeriodicTask(void) { char buf[256], lbuf[16]; - char *res; + char *next; int i, k; time_t putTim; - float t2[2], p, d, w; + float t3[3], p, d, w; ERR_P(LscCmd(ser, "DIOST?>cod1,out1;DOUT 3,29;HTR?>htr;BUSY?>busy")); - if (cryo.codDefined) { - per=period; - } else { - per=1; /* advance fast when initializing */ + if (cryo.codDefined && samp.codDefined) { + per=period; /* no timeout on above command and codes are defined: normal period */ } - if (noResp) { /* check serial number */ - k=serialNo; + if (noResp) { /* there was no response on an earlier command, or we are initializing */ + k=serialNo; /* check serial number */ ERR_P(LscCmd(ser, "*IDN?>buf1,buf2,serialNo,")); if (0!=strcmp(buf1, "LSCI") || 0!=strcmp(buf2, "MODEL340") || serialNo==0) return(0); - if (k!=serialNo) { + if (k!=serialNo) { /* controller exchanged or we are initializing */ if (!configuring) { str_copy(status, "controller connected"); } - configuring++; + if (remoteMode==2) configuring++; tempC=0; - if (cryo.manual || cryo.code!=0) { cryo.dirty=1; } - if (samp.manual || samp.code!=0) { samp.dirty=1; } - ERR_P(LscCmd(ser, "RANGE:0")); /* switch off heater */ /* reload curve cache: */ if (cache!=NULL) my_free(cache); sprintf(lbuf, "lsc.%d", serialNo); @@ -538,12 +560,40 @@ int PeriodicTask(void) { str_append(buf, lbuf); cache=str_read_file(buf); if (cache==NULL && 0==strcmp(ErrMessage, "file not found")) ERR_I(loadCache()); - cryo.device[0]='\0'; + /* get device names and last codes separated by '/' */ + str_split(buf, cache, '\n'); /* read 1 line */ samp.device[0]='\0'; - sscanf(cache, "%15[^/!]%*c%15[^\n!]", cryo.device, samp.device); /* read device names separated by '/' */ - if (cryo.device[0]!='\0') cryo.manual=1; - if (samp.device[0]!='\0') samp.manual=1; + cryo.code=0; + samp.code=0; + next=str_split(buf1, buf, '/'); + if (next!=NULL) { + next=str_split(buf2, next, '/'); + if (next!=NULL) { + next=str_split(buf3, next, '/'); + cryo.code=atoi(buf3); + cryo.codChanged=0; + if (next!=NULL) { + next=str_split(buf3, next, '\n'); + samp.code=atoi(buf3); + samp.codChanged=0; + } + } + } + if (buf1[0]=='*') { + str_copy(cryo.device, buf1+1); + cryo.manual=1; + } else { + str_copy(cryo.device, buf1); + } + if (buf2[0]=='*') { + str_copy(samp.device, buf2+1); + samp.manual=1; + } else { + str_copy(samp.device, buf2); + } concatDevice(); + if (cryo.manual || cryo.code!=0) { cryo.dirty=1; } + if (samp.manual || samp.code!=0) { samp.dirty=1; } } noResp=0; } @@ -551,15 +601,16 @@ int PeriodicTask(void) { ERR_I(ReadTemp()); if (cryo.dirty==0 && samp.dirty==0 && noResp==0 && tim>logTime) { - t2[0]=cryo.temp; - t2[1]=samp.temp; + t3[0]=cryo.temp; + t3[1]=samp.temp; + t3[2]=htr*htr*power*1e-4; + if (t3[2]==0.0) t3[2]=1e-20; + time(&putTim); -/* DlogPut(&dset, putTim, 2, t2); DlogUpd(&dset); */ + i=3; + dlog_put_(&putTim, &i, t3); + logTime=(putTim/logPeriod+1)*logPeriod; - time(&tim); - if (tim-putTim>1) { - logfileOut(LOG_MAIN, "needed %d sec. for filling in dlog\n", tim-putTim); - } } if (samp.nSens>0 && cryo.nSens>0 && controlMode==2 && tempC!=0) { d=(tempH-cryo.temp)/cryo.temp-1.0; /* relative difference */ @@ -593,11 +644,11 @@ int PeriodicTask(void) { samp.code1=-(3*decod[cod2 / 8] ^ 2*decod[cod1 / 8]); for (i=0; i<2; i++) { tpoint=tpoints[i]; - if (tpoint->code1!=tpoint->code) { + if (tpoint->code1!=tpoint->code) { /* code has changed -> wait for a confirmation */ tpoint->code=tpoint->code1; tpoint->codChanged=1; } else { - if (tpoint->codChanged) { + if (tpoint->codChanged) { /* code change confirmed */ tpoint->codChanged=0; Progress(1); if (tpoint->code1==0) { @@ -605,10 +656,10 @@ int PeriodicTask(void) { } else { logfileOut(LOG_MAIN, "plugged %d on %s\n", tpoint->code1, tpoint->tname); } - if (tpoint->codDefined) { - tpoint->manual=0; - } + tpoint->manual=0; tempC=0; + remoteMode=2; /* set to remote mode */ + LscCmd(ser, "MODE:[remoteMode]"); tpoint->dirty=1; if (!configuring) configuring=1; } @@ -619,15 +670,26 @@ int PeriodicTask(void) { } if (key!=0) { - auto_remote_time=tim+600; if (!(cryo.dirty || samp.dirty)) { logfileOut(LOG_MAIN ,"user touched keys\n"); } if (cryo.manual || cryo.code!=0) cryo.dirty=1; if (samp.manual || samp.code!=0) samp.dirty=1; - mode=0; - ERR_P(LscCmd(ser, "MODE?>mode")); - if (mode==2) auto_remote_time=tim; /* user switched to remote mode */ + remoteMode=1; + ERR_P(LscCmd(ser, "MODE?>remoteMode")); + if (remoteMode==2) { /* user switched to remote mode */ + ERR_P(LscCmd(ser, "RANGE?>iRange;SETP?1>tempC")); + setFlag=(iRange>0); + } + } + + if (saveTime!=0 && tim>saveTime) { + ERR_P(LscCmd(ser, "CRVSAV;BUSY?>busy")); + while (!busy) { + idleHdl(200, 0); /* wait 200 ms */ + ERR_P(LscCmd(ser, "BUSY?>busy")); + } + saveTime=0; } return(0); OnError: return(-1); @@ -716,12 +778,11 @@ int Settings(void) { maxfld=2*cryo.nSens-1; } if (maxfld>0) { - ERR_P(LscCmd(ser, "MODE:2;DISPLAY:[maxfld]")); + ERR_P(LscCmd(ser, "DISPLAY:[maxfld]")); } else { maxfld=1; - ERR_P(LscCmd(ser, "MODE:2;DISPLAY:1;DISPFLD 1,A,3")); + ERR_P(LscCmd(ser, "DISPLAY:1;DISPFLD 1,A,3")); } - mode=2; str_copy(nbuf, binDir); str_append(nbuf, cryo.device); @@ -738,14 +799,6 @@ int Settings(void) { my_free(cfg); } - if (saveTime!=0 && tim>saveTime) { - ERR_P(LscCmd(ser, "CRVSAV;BUSY?>busy")); - while (!busy) { - idleHdl(200, 0); /* wait 200 ms */ - ERR_P(LscCmd(ser, "BUSY?>busy")); - } - saveTime=0; - } ERR_I(ReadTemp()); } return(0); @@ -759,7 +812,7 @@ int ExecuteRequest(void) { struct CocClient *client; if (readTemp) ReadTemp(); - if (tim>auto_remote_time || setFlag) ERR_I(Settings()); + if (remoteMode==2) ERR_I(Settings()); if (setFlag) { if (cryo.nSens>0) { tInt=0; /* reset integral time */ @@ -780,13 +833,15 @@ int ExecuteRequest(void) { } if (deviceFlag) { tempC=0; + remoteMode=2; /* set to remote mode */ + LscCmd(ser, "MODE:[remoteMode]"); if (!configuring) { str_copy(status, "configuring"); configuring=1; } t=strchr(device, '/'); if (t==NULL) { - if (0==strcmp(device, "0")) { + if (0==strcmp(device, "0") || 0==strcasecmp(device, "auto")) { cryo.manual=0; cryo.dirty=1; samp.manual=0; samp.dirty=1; } else { @@ -821,7 +876,7 @@ int mainBody(void) struct timeb tim1; ERR_I(PeriodicTask()); - if (tim>=auto_remote_time) ERR_I(Settings()); + if (remoteMode==2) ERR_I(Settings()); logfileWrite(logMask); while (!quit) { @@ -913,6 +968,9 @@ int main(int argc, char *argv[]) } else if ('p'==opt) { i++; port=atoi(argv[i]); + } else if ('f'==opt) { + i++; + logPeriod=atoi(argv[i]); } else { logfileOut(LOG_INFO ,"?"); } @@ -922,13 +980,15 @@ int main(int argc, char *argv[]) } if (port==0) port=9753; if (msecTmo==0) msecTmo=1000; + if (logPeriod==0) logPeriod=10; + if (logPeriod*1000remoteMode"); + if (remoteMode!=2) configuring=0; + per=1; /* advance fast when initializing */ cntError=0; while (!quit) { iret=mainBody(); @@ -1017,14 +1074,11 @@ int main(int argc, char *argv[]) if (cntError>0) cntError--; } } - ERR_P(LscCmd(ser, "MODE:1")); logfileWrite(logMask); ERR_MSG("got quit command"); OnError: logfileShowErr("exit TecsServer"); -/* - DlogClose(&dset); -*/ + dlog_close_w_(); SerClose(ser); CocCloseServer(); return(0); diff --git a/tecs/tecs_cli.c b/tecs/tecs_cli.c index 121b66d3..d4ee137d 100644 --- a/tecs/tecs_cli.c +++ b/tecs/tecs_cli.c @@ -11,7 +11,7 @@ static float tempX, tempP, tempC; pTecsClient TeccInit(char *startcmd, int port) { CocConn *conn; - ERR_SP(conn=(CocConn *)my_malloc(sizeof(*conn),"conn")); + NEW(conn); ERR_I(CocInitClient(conn, "", port, "#rwacs", 0, startcmd)); CocDefFlt(tempC, CocRD); CocDefFlt(tempP, CocRD); diff --git a/tecs/tecs_dlog.c b/tecs/tecs_dlog.c deleted file mode 100644 index 8af3e2a7..00000000 --- a/tecs/tecs_dlog.c +++ /dev/null @@ -1,299 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "err_handling.h" -#include "str_util.h" -#include "tecs_dlog.h" - -#define VERSION 1.1 - -#define DEFINED(F) (abs((F)-dset->undef)>1.0e-5*(F)) - -static time_t gmtoff; - -int DlogWrite(DlogSet *dset, int idx, void *data) { - int p; - - p = dset->headsize + (idx % dset->nlen) * dset->fsize; - if (p!=dset->pos) { - ERR_SI(lseek(dset->fd, p, SEEK_SET)); - } - ERR_SI(write(dset->fd, data, dset->fsize)); - dset->pos = p + dset->fsize; - return(0); - OnError: - return(-1); -} - -#define FILL_BUF_SIZE 1024 - -int DlogFill(DlogSet *dset, int from, int to) { - int p, q, e, i, size; - float fill[FILL_BUF_SIZE]; - - for (i=0;iundef; - e = 0; - if (to-from>=dset->nlen) { /* fill all */ - p = dset->headsize; - q = dset->headsize + dset->nlen * dset->fsize; - } else { - p = dset->headsize + (from % dset->nlen) * dset->fsize; - q = dset->headsize + (to % dset->nlen) * dset->fsize; - if (qheadsize + dset->nlen * dset->fsize; - } - } - ERR_SI(lseek(dset->fd, p, SEEK_SET)); - size=sizeof(fill); - for (i=p; ifd, fill, size)); - } - if (q>i) ERR_SI(write(dset->fd, fill, q-i)); - - if (e>0) { - p = dset -> headsize; - ERR_SI(lseek(dset->fd, p, SEEK_SET)); - for (i=p; ifd, fill, size)); - } - if (e>i) ERR_SI(write(dset->fd, fill, q-i)); - } - dset->pos = -1; /* set position to undefined */ - return(0); - OnError: - return(-1); -} - -int DlogRead(DlogSet *dset, int idx, int max, void *data) { - int i, p, m; - - i = idx % dset->nlen; - p = dset->headsize + i * dset->fsize; - if (max > dset->nlen - i) { - max = dset->nlen - i; - } - if (p!=dset->pos) { - ERR_SI(lseek(dset->fd, p, SEEK_SET)); - } - ERR_SI(read(dset->fd, data, dset->fsize * max)); - dset->pos = p + dset->fsize * max; - return(max); - OnError: - return(-1); -} - -int DlogOpenOld(DlogSet *dset, char *name, int write) { - int i, p, np, fd, flags; - time_t tim; - struct tm *timp; - - fd=0; - str_copy(dset->name, name); - if (write) { - flags=O_RDWR | O_SYNC; - } else { - flags=O_RDONLY | O_SYNC; - } -#ifdef __VMS - ERR_SI(fd=open(name, flags, 0, "SHR=UPD")); - gmtoff=0; -#else - ERR_SI(fd=open(name, flags, 0)); - time(&tim); - timp=localtime(&tim); - gmtoff=timp->tm_gmtoff; -#endif - dset->fd=fd; - - p=(char *)&dset->fd - (char *)dset; - ERR_SI(read(dset->fd, dset, p)); - dset->pos=p; - if ((int)(dset->version*1000+0.5) != (int)(VERSION*1000+0.5)) ERR_MSG("version mismatch"); - if (dset->headsize != p) ERR_MSG("illegal dlog file"); - return(0); - OnError: - if (fd!=0) close(fd); - return(-1); -} - -int DlogOpen(DlogSet *dset, char *name) { - return(DlogOpenOld(dset, name, 0)); -} - -int DlogOpenWrt(DlogSet *dset, char *name, time_t start, int nset, int nlen, int period, float undef) { - int fd, i, j, p, iret; - va_list ap; - float f[DLOG_MAX_SET]; - - iret=DlogOpenOld(dset, name, 1); - if (iret>=0 && dset->nset==nset - && dset->nlen==nlen - && dset->last+nlen*period>start - && dset->undef == undef) { - return(1); /* take old file only if it matches */ - } - fd=0; - if (nset>DLOG_MAX_SET) ERR_MSG("nset too large"); - dset->nset=nset; - dset->nlen=nlen; - dset->start=start; - dset->last=start-period; - dset->period=period; - dset->undef=undef; - dset->version=VERSION; - str_copy(dset->name, name); - - for (i=0; iundef; - } - ERR_SI(fd=open(name, O_RDWR | O_CREAT | O_SYNC | O_TRUNC, 0666)); - dset->fd=fd; - p=(char *)&dset->fd - (char *)dset; - dset->headsize = p; - dset->fsize = nset * sizeof(float); - ERR_SI(write(dset->fd, dset, p)); - dset->pos=p; - return(0); - OnError: - if (fd!=0) close(fd); - return(-1); -} - -int DlogPut(DlogSet *dset, time_t tim, int nset, float val[]) { - int i, i0, j; - float f[DLOG_MAX_SET], f0[DLOG_MAX_SET]; - - if (nset > dset->nset) nset = dset->nset; - - for (j=0; j < nset; j++) { f[j]=val[j]; } - for (j=nset; j < dset->nset; j++) { f[j]=dset->undef; } - - i = ( tim - dset->start ) / dset->period; - i0 = ( dset->last - dset->start ) / dset->period; - - if (i0==i) { - ERR_I(DlogRead(dset, i, 1, f0)); - for (j=0; jf[j] || /* take maximum (for odd i) */ - !i%2 && f0[j]last=tim; - return(0); - OnError: - return(-1); -} - -#define RD_BUF_SIZE 1024 - -int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], float y[]) { - int j, i0, i1, i, n, nread, undef; - float f, fbuf[RD_BUF_SIZE+1]; - - if (iset<0) ERR_MSG("illegal iset"); - if (iset>=dset->nset) return(0); - - i = ( dset->last - dset->start ) / dset->period; - if (i - dset->nlen > 0) { - i1 = i - dset->nlen + 1; - } else { - i1 = 0; - } - i0=i1; - - *starttime = dset->start + i1 * dset->period + gmtoff; - n=0; - undef=2; - while (i0<=i) { - ERR_I(nread=DlogRead(dset, i0, RD_BUF_SIZE/dset->nset, fbuf)); - for (j=0; j=nmax) return(n); - f=fbuf[j * dset->nset + iset]; - i0++; - if (DEFINED(f)) { - x[n]=(float)(i0-i1)*dset->period; - y[n]=f; - n++; - undef=0; - } else if (undef==0) { - undef=1; - } else if (undef==1) { - undef=2; - x[n]=(float)(i0-i1)*dset->period; - y[n]=0; - n++; - } - } - } - return(n); - OnError: - return(-1); -} - -int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[], float y[], int index[]) { - int n, k, nmx, ntot; - - ntot=0; - for (k=0; kfd, 0, SEEK_SET)); - ERR_SI(write(dset->fd, &dset->last, sizeof(int))); - dset->pos=sizeof(int); -#ifdef __VMS - close(dset->fd); - ERR_I(DlogOpenOld(dset, dset->name, 1)); -#endif - return(0); - OnError: - return(-1); -} - -int DlogClose(DlogSet *dset) { - ERR_I(DlogUpd(dset)); - close(dset->fd); - return(0); - OnError: - return(-1); -} diff --git a/tecs/tecs_dlog.f b/tecs/tecs_dlog.f new file mode 100644 index 00000000..45615786 --- /dev/null +++ b/tecs/tecs_dlog.f @@ -0,0 +1,321 @@ + subroutine DLOG_OPEN_W(FILE, MAXSIZE) !! +!! ===================================== +!! +!! open dlog file for write +!! + character*(*) FILE !! (in) filename + integer MAXSIZE !! (in) max. size of file (in kBytes) + + include 'tecs_dlog.inc' + + integer j, k, iostat + data lunw/0/ + + if (lunw .ne. 0) then + print *,'DLOG_OPEN_W: file already open for write' + return + endif + lunw=38 + + vers=0 + + open(lunw, name=file, status='old', access='direct', shared + 1 , iostat=iostat) + if (iostat .eq. 0) then + read(lunw, rec=1) vers, wrec, rrec, rlim, lastx + if (vers .ne. version) then + close(lunw, status='delete') + else + read(lunw, rec=wrec) wn, wpos + 1 , (wtim(j), (wdat(j*wn+k), k=0,wn-1), j=0,wpos-1) + endif + else + vers=0 + endif + if (vers .ne. version) then + print *,'DLOG_OPEN_W: create new file' + vers=version + rlim=max(5,maxsize*256/recl) + rrec=2 + wrec=2 + wpos=0 + wn=0 + open(lunw, name=file, status='new', access='direct', shared + 1 , recl=recl, err=93) + write(lunw, rec=2) + endif + + call dlog_write_block(1) + + wlim=max(5,maxsize*256/recl) + return + +93 print *,'DLOG_OPEN_W: can not open file for write' + close(lunw) + lunw=0 + end + + + subroutine DLOG_PUT(TIME, N, DAT) !! +!! ================================= +!! +!! put data for N channels to logfile +!! + integer N, TIME !! (in) convention: time is in seconds since UNIX + real DAT(N) !! (in) data (0 is none) + + include 'tecs_dlog.inc' + + integer i,ival,j + + entry dlog_put_(time, n, dat) ! C interface for VMS + + if (lunw .le. 0) then + if (lunw .eq. 0) print *,'DLOG_PUT: file not open' + lunw=-1 + return + endif + + if (n .eq. 0) return + + if (wn .eq. 0) wn=n + + if ((wpos+1)*(n+1)+2 .gt. recl .or. n .ne. wn) then ! next record + wrec=wrec+1 + if (wrec .gt. wlim) then + rlim=wlim + wrec=2 + if (rrec .gt. rlim) rrec=2 + endif + if (wlim .gt. rlim) rlim=wlim + if (wrec .eq. rrec) then ! move read pointer + rrec=rrec+1 + if (rrec .gt. rlim) then + rrec=2 + endif + endif + call dlog_write_block(1) + wn=n + wpos=0 + endif + wtim(wpos)=time + j=wpos*wn + do i=1,wn + wdat(j)=dat(i) + j=j+1 + enddo + wpos=wpos+1 + call dlog_write_block(wrec) + lastx=time + call dlog_write_block(1) + end + + + + subroutine DLOG_CLOSE_W !! +!! ======================= +!! +!! close data file for write +!! + include 'tecs_dlog.inc' + + entry dlog_close_w_ + + if (lunw .gt. 0) close(lunw) + lunw=0 + end + + + subroutine DLOG_OPEN_R(FILE, FIRST, LAST, OFFSET) !! +!! ================================================= +!! +!! open dlog file for read +!! + character*(*) FILE !! (in) filename + integer FIRST !! first time + integer LAST !! last time + integer OFFSET !! recommended offset for DLOG_GET: + !! last Monday 0h00 before FIRST + + include 'tecs_dlog.inc' + + logical done + integer iostat,i,j + data lunr/0/ + + if (lunr .ne. 0) then + print *,'DLOG_OPEN_R: file already open for read' + return + endif + + lunr=39 + + open(lunr, name=file, status='old', access='direct', shared + 1 , recl=recl, err=99, readonly) + call dlog_read_block(1, done) + if (done) call dlog_read_block(rrec, done) + if (.not. done) then + close(lunr) + goto 99 + endif + if (nl .eq. 0) then + first=0 + else + first=rtim(0) + endif + last=lastx + offset=first-mod(first+3*24*3600,7*24*3600) + return + +99 print *,'DLOG_OPEN_R: can not open' + lunr=0 + end + + + subroutine DLOG_GET(NDIM, NDAT, OFFSET, XMIN, XMAX, X, Y, NRES) !! +!! =============================================================== +!! +!! Get data from logfile in the range XMIN..XMAX +!! not available data is represented by 0 +!! for precision reasons, and because time is internally stored +!! as integer seconds since UNIX (1 Jan 1970), a time offset is used. +!! X(i)+OFFSET, XMIN+OFFSET, XMAX+OFFSET is in seconds since UNIX +!! + integer NDIM, NDAT !! (in) dimensions + integer OFFSET !! (in) time zero point (use value from DLOG_OPEN) + real XMIN, XMAX !! (in) start and end time + real X(NDIM), Y(NDIM, NDAT) !! (out) data + integer NRES !! (out) returned size + + include 'tecs_dlog.inc' + + integer i, j, k, ix, imin, imax, rpos, iostat + logical done + + nres=0 + if (lunr .eq. 0) return ! file not open + + imin=nint(max(-2147480000.,xmin)) + imax=nint(min( 2147480000.,xmax)) + + call dlog_read_block(1, done) + if (.not. done) return ! record locked + +1 continue + call dlog_read_block(rrec, done) + if (.not. done) return ! record locked + do i=0,nl-1 + ix=rtim(i)-offset + if (ix .ge. imin .and. ix .le. imax .and. nres .lt. ndim) then + nres=nres+1 + x(nres)=ix + j=i*rn + do k=1,min(rn, ndat) + y(nres,k)=rdat(j) + j=j+1 + enddo + do k=min(rn, ndat)+1,ndat ! fill with zeros + y(nres,k)=0 + enddo + endif + enddo +8 if (rrec .eq. wrec) goto 9 + rrec=rrec+1 + if (rrec .gt. rlim) then + rrec=2 + endif + goto 1 +9 continue + + end + + + subroutine DLOG_CLOSE_R !! +!! ======================= +!! +!! close data file for read +!! + include 'tecs_dlog.inc' + + if (lunr .ne. 0) close(lunr) + lunr=0 + end + + + + subroutine dlog_write_block(recno) + + integer recno + + include 'tecs_dlog.inc' + + integer i,j,k,iostat + real s + + s=secnds(0.0) +1 if (recno .eq. 1) then + write(lunw, rec=1, iostat=iostat) vers, wrec, rrec, rlim, lastx + else + write(lunw, rec=recno, iostat=iostat) wn, wpos + 1 , (wtim(j), (wdat(j*wn+k), k=0,wn-1), j=0,wpos-1) + endif + if (iostat .eq. 52) then ! record locked + if (secnds(s) .lt. 2.0) goto 1 + print *,'DLOG_PUT: record locked' + endif + end + + + subroutine dlog_read_block(recno, done) + + integer recno + logical done + + include 'tecs_dlog.inc' + + integer i,j,k,iostat + real s + + s=secnds(0.0) +1 if (recno .eq. 1) then + read(lunr, rec=1, iostat=iostat) vers, wrec, rrec, rlim, lastx + else + read(lunr, rec=recno, iostat=iostat) rn, nl + 1 , (rtim(j), (rdat(j*rn+k), k=0,rn-1), j=0,nl-1) + endif + if (iostat .eq. 52) then ! record locked + if (secnds(s) .lt. 2.0) goto 1 + print *,'DLOG_GET: record locked' + done=.false. + elseif (iostat .ne. 0) then + print *,'DLOG_GET: can not read record' + done=.false. + else + done=.true. + endif + end + + +! +! C interface +! + subroutine dlog_open_write(cfile, maxsize) + + byte cfile(*) ! C char* + integer maxsize ! C int + + integer m, i, j + character file*128 + + entry dlog_open_write_(cfile, maxsize) ! C interface for VMS + + m=%loc(maxsize) + do i=2,128 + if (cfile(i) .eq. 0) then + write(file, '(128a1)') (cfile(j), j=1,i-1) + call dlog_open_w(file(1:i-1), m) + return + endif + enddo + print *,'DLOG_OPEN_WRITE: filename too long' + end diff --git a/tecs/tecs_dlog.h b/tecs/tecs_dlog.h index 2eaae7bf..83675599 100644 --- a/tecs/tecs_dlog.h +++ b/tecs/tecs_dlog.h @@ -3,52 +3,15 @@ #include -#define DLOG_MAX_SET 32 +/* implemented in fortran TECS_DLOG.FOR */ -typedef struct { - time_t last, start; - float version, undef; - int period, headsize, fsize, nset, nlen; - int fd, pos; - char name[128]; -} DlogSet; +int dlog_open_write_(char *file, int maxsize); +/* open dlog file */ +int dlog_put_(time_t *time, int *nset, float val[]); +/* put values to dlog file */ -int DlogOpen(DlogSet *dset, char *name); -/* open existing dlog set */ - -int DlogOpenWrt(DlogSet *dset, char *name, time_t start, int nset, int nlen, int period, float undef); -/* create or append to new dlog file */ - -int DlogPut(DlogSet *dset, time_t time, int nset, float val[]); -/* put values to dlog set */ - -int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float *x, float *y); -/* get one dataset from dlog set - - iset is the dataset to be returned - nmax is the maximal number of points to be returned - x, y: the data (arrays declared with at least nmax elements) - - on success, the return value is the effective length of returned data -*/ - -int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[], float y[], int index[]); -/* get many datasets from dlog set - - nset is the nember of datasets to be returned - nmax is the maximal number of points to be returned - x, y: the data, one dataset after an other (arrays declared with at least nmax elements) - index must be an array of at least nset elements. - it returns the start indices in x[] and y[] of the data sets. - - on success, the return value is the effective length of returned data -*/ - -int DlogUpd(DlogSet *dset); -/* update pointer */ - -int DlogClose(DlogSet *dset); +int dlog_close_w_(void); /* close dlog set */ #endif /* _DLOG_H_ */ diff --git a/tecs/tecs_dlog.inc b/tecs/tecs_dlog.inc new file mode 100644 index 00000000..e6bc897e --- /dev/null +++ b/tecs/tecs_dlog.inc @@ -0,0 +1,9 @@ + parameter version=104, recl=16 + + integer lunw, lunl, lunr + integer vers, wrec, wpos, rrec, rlim, wlim, wn, rn, nl, lastx + integer wtim(0:recl-1), rtim(0:recl-1) + real wdat(0:recl-1), rdat(0:recl-1) + common/tecs_dlog_inc/ lunw, lunl, lunr + 1, vers, wrec, wpos, rrec, rlim, wlim, wn, rn, nl, lastx + 1, wtim, wdat, rtim, rdat