new version of tecs_dlog (now in fortran)

This commit is contained in:
cvs
2000-05-10 09:22:35 +00:00
parent 1f3d41a83e
commit 1329c3beb4
7 changed files with 486 additions and 437 deletions

View File

@ -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

View File

@ -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*1000<period) period=logPeriod*1000;
str_copy(buf, logDir);
str_append(buf, serverId);
str_copy(status, "starting up");
logfileStatusBuf(status);
logfileInit(buf, logIt, use_stdout, logIt);
logfileInit(buf, logIt, use_stdout, logIt && use_stdout);
logfileOut(LOG_INFO ,"\n");
logfileWrite(logMask);
@ -966,6 +1026,7 @@ int main(int argc, char *argv[])
CocDefStr(chan, CocRD);
CocDefStr(intype, CocRD);
CocDefStr(status, CocRD);
CocDefStr(dlogfile, CocRD);
CocDefInt(cod1, CocRD);
CocDefInt(cod2, CocRD);
@ -978,7 +1039,7 @@ int main(int argc, char *argv[])
CocDefInt(resist, CocRD);
CocDefInt(iAmp, CocRD);
CocDefInt(iRange, CocRD);
CocDefInt(mode, CocRD);
CocDefInt(remoteMode, CocRD);
CocDefInt(readTemp, CocWR);
CocDefInt(controlMode, CocWR);
@ -991,21 +1052,17 @@ int main(int argc, char *argv[])
ERR_I(iret=CocHandleRequests(100, 0));
ftime(&tim0);
tim=tim0.time;
/*
str_copy(buf, logDir);
str_append(buf, serverId);
str_append(buf, ".dlog");
logfileOut(LOG_INFO, "open data log file: %s\n", buf);
ERR_I(iret=DlogOpenWrt(&dset, buf, tim0.time, 2, 7*24*60*60/logPeriod, logPeriod, 0.0));
if (iret==0) {
logfileOut(LOG_INFO, "created\n");
} else {
logfileOut(LOG_INFO, "opened\n");
}
str_copy(dlogfile, logDir);
str_append(dlogfile, serverId);
str_append(dlogfile, ".dlog");
logfileOut(LOG_INFO, "open data log file: %s\n", dlogfile);
dlog_open_write_(dlogfile, 2000); /* max size of 2 MB */
logfileWrite(logMask);
*/
LscCmd(ser, "MODE:[mode]");
per=period;
LscCmd(ser, "MODE?>remoteMode");
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);

View File

@ -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);

View File

@ -1,299 +0,0 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#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;i<FILL_BUF_SIZE;i++) fill[i]=dset->undef;
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 (q<p) {
e = q;
q = dset->headsize + dset->nlen * dset->fsize;
}
}
ERR_SI(lseek(dset->fd, p, SEEK_SET));
size=sizeof(fill);
for (i=p; i<q-size; i+=size) {
ERR_SI(write(dset->fd, 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; i<e-size; i+=size) {
ERR_SI(write(dset->fd, 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; i<nset; i++) {
f[i]=dset->undef;
}
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; j<nset; j++) {
if (DEFINED(f0[j]) && /* when last point defined */
(i%2 && f0[j]>f[j] || /* take maximum (for odd i) */
!i%2 && f0[j]<f[j] ) /* or minimum (for even i) */
) f[j]=f0[j]; /* of f0 and f0 */
}
} else if (i0<i-1) {
DlogFill(dset, i0+1, i);
}
ERR_I(DlogWrite(dset, i, f));
dset->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<nread; j++) {
if (n>=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; k<nset; k++) {
index[k]=ntot;
nmx=(nmax-ntot)/(nset-k);
ERR_I(n=DlogGet(dset, k, nmx, starttime, &x[ntot], &y[ntot]));
ntot+=n;
}
return(ntot);
OnError:
return(-1);
}
int dlog_get_(char *name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[], int namlen) {
DlogSet dset;
char buf[64];
int ntot;
/* for compaq unix */
str_trim(buf, name, namlen);
ERR_I(DlogOpen(&dset, buf));
ERR_I(ntot=DlogGetMany(&dset, *nset, *nmax, starttime, x, y, index));
DlogClose(&dset);
return(ntot);
OnError:
ErrWrite("error in dlog_get_");
return(-1);
}
int Dlog_Get(char **name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[]) {
/* for VMS */
return(dlog_get_(name[1], nset, nmax, starttime, x, y, index, *(short *)name));
}
int DlogUpd(DlogSet *dset) {
ERR_SI(lseek(dset->fd, 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);
}

321
tecs/tecs_dlog.f Normal file
View File

@ -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

View File

@ -3,52 +3,15 @@
#include <time.h>
#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_ */

9
tecs/tecs_dlog.inc Normal file
View File

@ -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