Update to filesource

Move tprev out of the loop to enable storing the previous time value.
Add some general warning message that an error might have occurred during
reading the time or data values from the data input file.
Allow empty lines in the data input file.
Guard early data values (TIME < time offset) against false reading.
Add some simple examples.
This commit is contained in:
Holger Vogt 2025-08-11 18:45:21 +02:00
parent b44421749a
commit f45103b3ab
5 changed files with 111 additions and 8 deletions

View File

@ -0,0 +1,49 @@
simple filesource, time relative or absolute
a1 %vd([out1 0]) filesrc
.model filesrc filesource (file="rect_rel.m" amploffset=[0.1] amplscale=[1]
+ timeoffset=0 timescale=1
+ timerelative=true amplstep=false)
a2 %vd([out2 0]) filesrc2
.model filesrc2 filesource (file="rect_rel.m" amploffset=[0.15] amplscale=[1]
+ timeoffset=10e-6 timescale=1
+ timerelative=true amplstep=false)
a3 %vd([out3 0]) filesrc3
.model filesrc3 filesource (file="rect_rel.m" amploffset=[0.2] amplscale=[0.9]
+ timeoffset=5e-6 timescale=1.2
+ timerelative=true amplstep=false)
a4 %vd([out4 0]) filesrc4
.model filesrc4 filesource (file="rect_rel.m" amploffset=[0.05] amplscale=[1.2]
+ timeoffset=0 timescale=1.2
+ timerelative=true amplstep=true)
a5 %vd([out5 0]) filesrc5
.model filesrc5 filesource (file="rect_abs.m" amploffset=[0.05] amplscale=[1.1]
+ timeoffset=5u timescale=1.2
+ timerelative=false amplstep=false)
a6 %v([out6 out7]) filesrc6
.model filesrc6 filesource (file="rect_abs_dual.m" amploffset=[0.05 -0.05] amplscale=[0.9]
+ timeoffset=5u timescale=1.2
+ timerelative=false amplstep=false)
.control
tran 0.1u 100u
set xbrushwidth=3
plot V(out1) V(out2)+2 V(out3)+4 V(out4)+6 V(out5)+8 V(out6)+11 V(out7)+11
.endc
.end

View File

@ -0,0 +1,11 @@
# simple input, time absolute
0 0
10e-6 0
11e-6 1.8
21e-6 1.8
22e-6 0
32e-6 0
33e-6 1.8
43e-6 1.8
44e-6 0
1 0

View File

@ -0,0 +1,11 @@
# simple input, time absolut
0 0 0
10e-6 0 0
11e-6 1.8 -0.3
21e-6 1.8 -0.3
22e-6 0 -0.6
32e-6 0 -0.6
33e-6 1.8 -0.3
43e-6 1.8 -0.3
44e-6 0 0
1 0

View File

@ -0,0 +1,11 @@
# simple input, time relative
0 0
10e-6 0
1e-6 1.8
10e-6 1.8
1e-6 0
10e-6 0
1e-6 1.8
10e-6 1.8
1e-6 0
1 0

View File

@ -14,6 +14,7 @@ AUTHORS
03 Sep 2012 Holger Vogt
27 Feb 2017 Marcel Hendrix
23 JUL 2018 Holger Vogt
11 Aug 2025 Holger Vogt
MODIFICATIONS
@ -171,6 +172,17 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
if (INIT == 1) {
int count;
double tprev; /* store the previous time, used when time relative is set */
bool terr = MIF_FALSE; /* Cumulative warning message upon error during time reading */
bool derr = MIF_FALSE; /* Cumulative warning message upon error during data reading */
/* add time offset only once to tprev */
if (!PARAM_NULL(timeoffset)) {
tprev = PARAM(timeoffset);
}
else
tprev = 0.;
/*** allocate static storage for *loc ***/
if ((loc = (Local_Data_t *) (STATIC_VAR(locdata) = calloc(1,
@ -240,11 +252,12 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
count = 0;
while (!loc->state->atend) {
char line[512];
char *cp, *cpdel;
char *cp2;
double t, tprev = 0;
double t = 0, d = 0;
int i;
if (!fgets(line, sizeof(line), loc->state->fp)) {
loc->state->atend = 1;
@ -260,13 +273,14 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
/* read the time channel; update the time difference */
while (*cp && isspace_c(*cp))
++cp;
if (*cp == '*' || *cp == '#' || *cp == ';') {
if (*cp == '*' || *cp == '#' || *cp == ';' || *cp == '\0') {
free(cpdel);
continue;
}
t = strtod(cp, &cp2);
if (cp2 == cp) {
free(cpdel);
terr = MIF_TRUE;
continue;
}
cp = cp2;
@ -297,15 +311,17 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
for (i = 0; i < size; ++i) {
while (*cp && (isspace_c(*cp) || *cp == ','))
++cp;
t = strtod(cp, &cp2);
if (cp2 == cp)
d = strtod(cp, &cp2);
if (cp2 == cp) {
derr = MIF_TRUE;
break;
}
cp = cp2;
if (i < amplscalesize)
t *= PARAM(amplscale[i]);
d *= PARAM(amplscale[i]);
if (i < amploffssize)
t += PARAM(amploffset[i]);
loc->indata->datavec[count++] = t;
d += PARAM(amploffset[i]);
loc->indata->datavec[count++] = d;
}
free(cpdel);
}
@ -318,6 +334,11 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
/* set the start time data */
loc->timeinterval[0] = loc->indata->datavec[loc->indata->actpointer];
loc->timeinterval[1] = loc->indata->datavec[loc->indata->actpointer + stepsize];
if (terr)
cm_message_printf("WARNING: some error occured during reading the time values");
if (derr)
cm_message_printf("WARNING: some error occured during reading the data values");
}
loc = STATIC_VAR (locdata);
@ -326,7 +347,7 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
* If TIME steps backward, for example due to a second invocation of a 'tran' analysis
* step back in datavec[loc->indata->actpointer] .
*/
if (TIME < loc->timeinterval[0]) {
if (TIME < loc->timeinterval[0] && loc->indata->actpointer >= stepsize) {
while (TIME < loc->indata->datavec[loc->indata->actpointer] && loc->indata->actpointer >= 0)
loc->indata->actpointer -= stepsize;
loc->timeinterval[0] = loc->indata->datavec[loc->indata->actpointer];