Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
V
Vent Display
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Marcos Mendez Quintero
Vent Display
Commits
13b1167e
Commit
13b1167e
authored
4 years ago
by
Robert L. Read
Browse files
Options
Downloads
Patches
Plain Diff
adding work-of-breathing
parent
559a1fda
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
breath_plot.html
+171
-110
171 additions, 110 deletions
breath_plot.html
with
171 additions
and
110 deletions
breath_plot.html
+
171
−
110
View file @
13b1167e
...
...
@@ -325,7 +325,7 @@ an interactive or static analysis of a respiration. It's primary purpose is
</div>
</div>
<div>
<label
for=
"taip"
>
TAIP
(ms):
</label>
<label
for=
"taip"
>
Rise Time
(ms):
</label>
<div
class=
"value_and_fences"
>
<div
class=
"calcnum"
>
<label
id=
"taip"
>
</label>
...
...
@@ -343,7 +343,7 @@ an interactive or static analysis of a respiration. It's primary purpose is
</div>
</div>
<div>
<label
for=
"taip"
>
TRIP
(ms):
</label>
<label
for=
"taip"
>
Fall Time
(ms):
</label>
<div
class=
"value_and_fences"
>
<div
class=
"calcnum"
>
<label
id=
"trip"
>
</label>
...
...
@@ -359,6 +359,23 @@ an interactive or static analysis of a respiration. It's primary purpose is
</div>
</div>
</div>
<div>
<label
for=
"wob"
>
W. of B. (J/L):
</label>
<div
class=
"value_and_fences"
>
<div
class=
"calcnum"
>
<label
id=
"wob"
>
</label>
</div>
<div
class=
"vertical_alarms"
>
<div
class=
"limit max"
>
<label
for=
"wob_h"
>
H:
</label>
<input
class=
"fence"
id=
"wob_h"
type=
'text'
>
</input>
</div>
<div
class=
"limit min"
>
<label
for=
"wob_l"
>
L:
</label>
<input
class=
"fence"
id=
"wob_l"
type=
'text'
>
</input>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
@@ -370,11 +387,11 @@ an interactive or static analysis of a respiration. It's primary purpose is
<div>
Parameters:
<div>
<label
for=
"tarip_h"
>
TAIP/TRIP
High Pressure (cm H2O):
</label>
<label
for=
"tarip_h"
>
Rise/Fall
High Pressure (cm H2O):
</label>
<input
class=
"fence"
id=
"tarip_h"
type=
'text'
>
</input>
</div>
<div>
<label
for=
"tarip_l"
>
TAIP/TRIP
Low Pressure (cm H2O):
</label>
<label
for=
"tarip_l"
>
Rise/Fall
Low Pressure (cm H2O):
</label>
<input
class=
"fence"
id=
"tarip_l"
type=
'text'
>
</input>
</div>
</div>
...
...
@@ -667,10 +684,30 @@ function plot(samples, trans, breaths) {
,
0
);
var
max_v
=
Math
.
max
(
max_inh
,
max_exh
);
// not sure why I have null work, have to understand.
var
max_work_per_liter
=
0
;
var
work_per_liter
=
[];
for
(
var
i
=
0
;
i
<
breaths
.
length
;
i
++
)
{
var
b
=
breaths
[
i
];
if
(
b
.
work
!=
null
)
{
var
wpl
=
b
.
work
/
b
.
vol_i
;
if
(
wpl
>
max_work_per_liter
)
max_work_per_liter
=
wpl
;
var
center
=
((
trans
[
b
.
trans_begin_inhale
].
ms
+
trans
[
b
.
trans_cross_zero
].
ms
)
-
2
*
min
)
/
(
2.0
*
1000.0
);
work_per_liter
.
push
({
wpl
:
wpl
,
center
:
center
});
}
}
var
exh_v
=
unpack
(
breaths
,
'
vol_e
'
).
map
(
e
=>
100
*
e
/
max_v
);
var
t_exh_v
=
unpack
(
breaths
,
'
vol_e
'
).
map
(
e
=>
Math
.
round
(
e
*
1000.0
)
+
"
ml exh
"
);
var
inh_v
=
unpack
(
breaths
,
'
vol_i
'
).
map
(
i
=>
100
*
i
/
max_v
);
var
t_inh_v
=
unpack
(
breaths
,
'
vol_i
'
).
map
(
e
=>
Math
.
round
(
e
*
1000.0
)
+
"
ml inh
"
);
var
work_v
=
work_per_liter
.
map
(
w
=>
(
1
/
3
)
*
(
100
*
w
.
wpl
/
max_work_per_liter
));
var
t_work
=
work_per_liter
.
map
(
w
=>
w
.
wpl
.
toFixed
(
2
)
+
"
J/L
"
);
var
work_centers
=
unpack
(
work_per_liter
,
'
center
'
);
// now to graph properly, I must find the center of an inhalation.
// I have packed these into the breaths...
var
inhale_centers
=
breaths
.
map
(
b
=>
((
trans
[
b
.
trans_begin_inhale
].
ms
+
trans
[
b
.
trans_cross_zero
].
ms
)
-
2
*
min
)
/
(
2.0
*
1000.0
));
...
...
@@ -698,6 +735,17 @@ function plot(samples, trans, breaths) {
text
:
t_exh_v
,
};
var
workPlot
=
{
type
:
"
scatter
"
,
mode
:
"
markers+text
"
,
name
:
"
WoB J
"
,
textposition
:
'
bottom center
'
,
x
:
work_centers
,
y
:
work_v
,
text
:
t_work
,
marker
:
{
size
:
8
,
color
:
'
blue
'
,
symbol
:
'
triangle-right
'
}
};
event_graph
.
push
(
workPlot
);
event_graph
.
push
(
inhPlot
);
event_graph
.
push
(
exhPlot
);
}
...
...
@@ -733,7 +781,7 @@ function plot(samples, trans, breaths) {
// Basically, we will show only the first of these in a "run"
// This is rather difficult; we will instead just use 200 ms
// as a window.
const
time_windwow_ms
=
2
00
;
const
TIME_WINDOW_MS
=
4
00
;
var
lows
=
[];
var
highs
=
[];
...
...
@@ -741,10 +789,10 @@ function plot(samples, trans, breaths) {
for
(
var
i
=
0
;
i
<
messages
.
length
;
i
++
)
{
var
m
=
messages
[
i
];
if
(
m
.
buff
==
FLOW_TOO_LOW
)
{
if
((
lows
.
length
==
0
)
||
((
lows
.
length
>
0
)
&&
(
lows
[
lows
.
length
-
1
].
ms
<
(
m
.
ms
-
200
))))
if
((
lows
.
length
==
0
)
||
((
lows
.
length
>
0
)
&&
(
lows
[
lows
.
length
-
1
].
ms
<
(
m
.
ms
-
TIME_WINDOW_MS
))))
lows
.
push
(
m
);
}
else
if
(
m
.
buff
==
FLOW_TOO_HIGH
)
{
if
((
highs
.
length
==
0
)
||
((
highs
.
length
>
0
)
&&
(
highs
[
highs
.
length
-
1
].
ms
<
(
m
.
ms
-
200
))))
if
((
highs
.
length
==
0
)
||
((
highs
.
length
>
0
)
&&
(
highs
[
highs
.
length
-
1
].
ms
<
(
m
.
ms
-
TIME_WINDOW_MS
))))
highs
.
push
(
m
);
}
else
{
others
.
push
(
m
);
...
...
@@ -933,7 +981,13 @@ function compute_fio2_mean(secs,samples) {
}
}
// returns:
// [ respiration rate,
// tidal volume (avg),
// minute_volume
// EIRatio,
// Work-of-Breathing (avg)
// ]
function
compute_respiration_rate
(
secs
,
samples
,
transitions
,
breaths
)
{
// In order to compute the number of breaths
// in the last s seconds, I compute those breaths
...
...
@@ -944,7 +998,7 @@ function compute_respiration_rate(secs,samples,transitions,breaths) {
var
first_inhale_ms
=
-
1
;
var
last_inhale_ms
=
-
1
;
if
(
breaths
.
length
==
0
)
{
return
[
0
,
0
,
0
,
"
NA
"
];
return
[
0
,
0
,
0
,
"
NA
"
,
"
NA
"
];
}
else
{
const
recent_ms
=
samples
[
samples
.
length
-
1
].
ms
;
var
cur_ms
=
recent_ms
;
...
...
@@ -959,6 +1013,9 @@ function compute_respiration_rate(secs,samples,transitions,breaths) {
// divide by the inhlation_duration.
var
vol_ci
=
0.0
;
var
wob
=
0.0
;
var
wob_cnt
=
0
;
while
((
i
>=
0
)
&&
(
breaths
[
i
].
ms
>
(
cur_ms
-
secs
*
1000
)))
{
cnt
++
;
vol_i
+=
breaths
[
i
].
vol_i
;
...
...
@@ -975,6 +1032,11 @@ function compute_respiration_rate(secs,samples,transitions,breaths) {
const
zero_ms
=
transitions
[
breaths
[
i
].
trans_cross_zero
].
ms
;
time_inh
+=
(
zero_ms
-
inh_ms
);
time_exh
+=
(
exh_ms
-
zero_ms
);
if
(
breaths
[
i
].
work
!=
null
)
{
wob
+=
breaths
[
i
].
work
/
breaths
[
i
].
vol_i
;
wob_cnt
++
;
}
i
--
;
}
if
((
cnt
>
1
)
&&
(
first_inhale_ms
!=
last_inhale_ms
))
{
...
...
@@ -990,16 +1052,18 @@ function compute_respiration_rate(secs,samples,transitions,breaths) {
var
tidal_volume
=
1000.0
*
vol_i
/
cnt
;
var
EIratio
=
(
time_inh
==
0
)
?
null
:
time_exh
/
time_inh
;
var
WorkOfBreathing_J_per_L
=
wob
/
wob_cnt
;
return
[
rr
,
tidal_volume
,
minute_volume
,
EIratio
];
EIratio
,
WorkOfBreathing_J_per_L
];
}
else
{
return
[
0
,
0
,
0
,
"
NA
"
];
return
[
0
,
0
,
0
,
"
NA
"
,
"
NA
"
];
}
}
}
}
var
LIMITS
=
{
max
:
{
h
:
40
,
...
...
@@ -1021,7 +1085,9 @@ var LIMITS = {
taip
:
{
h
:
100
,
// These are in ms
l
:
0
},
trip
:
{
h
:
100
,
// These are in ms
l
:
0
},
l
:
0
},
wob
:
{
h
:
3
,
l
:
0.2
},
}
function
load_ui_with_defaults
(
limits
)
{
...
...
@@ -1067,13 +1133,19 @@ function process(samples) {
var
[
transitions
,
breaths
]
=
computeMovingWindowTrace
(
samples
,
t
,
v
);
plot
(
samples
,
transitions
,
breaths
);
// How many seconds backwards should we look? Perhaps 20?
var
[
bpm
,
tv
,
mv
,
EIratio
,
fio2
]
=
compute_respiration_rate
(
RESPIRATION_RATE_WINDOW_SECONDS
,
samples
,
transitions
,
breaths
);
var
[
bpm
,
tv
,
mv
,
EIratio
,
wob
]
=
compute_respiration_rate
(
RESPIRATION_RATE_WINDOW_SECONDS
,
samples
,
transitions
,
breaths
);
var
alarms
=
[];
$
(
"
#bpm
"
).
text
(
bpm
.
toFixed
(
1
));
$
(
"
#tv
"
).
text
(
tv
.
toFixed
(
0
));
$
(
"
#mv
"
).
text
((
mv
).
toFixed
(
2
));
$
(
"
#mv
"
).
text
(
mv
.
toFixed
(
2
));
if
(
wob
==
"
NA
"
)
{
$
(
"
#wob
"
).
text
(
"
NA
"
);
}
else
{
$
(
"
#wob
"
).
text
(
wob
.
toFixed
(
2
));
}
if
(
EIratio
==
"
NA
"
)
{
$
(
"
#ier
"
).
text
(
"
NA
"
);
}
else
{
...
...
@@ -1096,8 +1168,10 @@ function process(samples) {
alarms
=
alarms
.
concat
(
check_high_and_low
(
LIMITS
,
"
bpm
"
,
bpm
.
toFixed
(
1
),
b_ms
));
alarms
=
alarms
.
concat
(
check_high_and_low
(
LIMITS
,
"
tv
"
,
tv
.
toFixed
(
0
),
b_ms
));
alarms
=
alarms
.
concat
(
check_high_and_low
(
LIMITS
,
"
mv
"
,
(
mv
)
.
toFixed
(
2
),
b_ms
));
alarms
=
alarms
.
concat
(
check_high_and_low
(
LIMITS
,
"
mv
"
,
mv
.
toFixed
(
2
),
b_ms
));
alarms
=
alarms
.
concat
(
check_high_and_low
(
LIMITS
,
"
ier
"
,(
1.0
/
EIratio
).
toFixed
(
1
),
b_ms
));
if
(
wob
!=
"
NA
"
)
alarms
=
alarms
.
concat
(
check_high_and_low
(
LIMITS
,
"
wob
"
,
wob
.
toFixed
(
2
),
b_ms
));
// These must be moved out; in fact,
// they must be made configurable!
...
...
@@ -1182,26 +1256,34 @@ function retrieveAndPlot(){
// WARNING: This is a hack...if the timestamp is negative,
// we treat it as a limited (beyond range of sensor) measurement.
// Our goal is to warn about this, but for now we will just
// ignore and correct.
// ignore and correct.
if
(
cur_sam
==
null
)
{
console
.
log
(
"
No return
"
);
return
;
}
if
(
cur_sam
&&
cur_sam
.
length
==
0
)
{
console
.
log
(
"
no samples; potential misconfiguration!
"
);
}
else
{
cur_sam
=
sanitize_samples
(
cur_sam
);
if
(
INITS_ONLY
)
{
samples
=
cur_sam
;
INITS_ONLY
=
false
;
}
else
{
var
discard
=
Math
.
max
(
0
,
samples
.
length
+
cur_sam
.
length
-
MAX_SAMPLES_TO_STORE_S
);
samples
=
samples
.
slice
(
discard
);
}
samples
=
samples
.
concat
(
cur_sam
);
// We are not guaranteeed to get samples in order
// we sort them....
samples
=
samples
.
sort
((
a
,
b
)
=>
a
.
ms
-
b
.
ms
);
process
(
samples
);
if
(
typeof
(
cur_sam
)
==
"
string
"
)
{
console
.
log
(
cur_sam
);
}
else
{
cur_sam
=
sanitize_samples
(
cur_sam
);
if
(
INITS_ONLY
)
{
samples
=
cur_sam
;
INITS_ONLY
=
false
;
}
else
{
var
discard
=
Math
.
max
(
0
,
samples
.
length
+
cur_sam
.
length
-
MAX_SAMPLES_TO_STORE_S
);
samples
=
samples
.
slice
(
discard
);
}
samples
=
samples
.
concat
(
cur_sam
);
// We are not guaranteeed to get samples in order
// we sort them....
samples
=
samples
.
sort
((
a
,
b
)
=>
a
.
ms
-
b
.
ms
);
process
(
samples
);
}
}
},
error
:
function
(
xhr
,
ajaxOptions
,
thrownError
)
{
...
...
@@ -1416,11 +1498,10 @@ function PressureVolumeWork(breath, transitions, samples) {
var
beginTime_ms
=
beginTransition
.
ms
;
var
endTransition
=
transitions
[
breath
.
trans_cross_zero
];
var
endTime_ms
=
endTransition
.
ms
;
var
flows
=
samples
.
filter
(
s
=>
s
.
event
==
'
M
'
&&
s
.
type
==
'
F
'
&&
s
.
ms
>=
beginTime_ms
&&
s
.
ms
<=
endTime_ms
);
var
pressures
=
samples
.
filter
(
s
=>
s
.
event
==
'
M
'
&&
s
.
type
==
'
D
'
&&
s
.
loc
==
'
A
'
&&
s
.
ms
>=
beginTime_ms
&&
s
.
ms
<=
endTime_ms
);
console
.
log
(
flows
);
console
.
log
(
pressures
);
var
flows
=
samples
.
filter
(
s
=>
s
.
event
==
'
M
'
&&
s
.
type
==
'
F
'
&&
s
.
ms
>=
beginTime_ms
&&
s
.
ms
<=
endTime_ms
);
var
pressures
=
samples
.
filter
(
s
=>
s
.
event
==
'
M
'
&&
s
.
type
==
'
D
'
&&
s
.
loc
==
'
A
'
&&
s
.
ms
>=
beginTime_ms
&&
s
.
ms
<=
endTime_ms
);
// Note: The algorithm below relies on the fact that there is
// only one flow or pressure with a single ms value; and that
...
...
@@ -1433,8 +1514,8 @@ function PressureVolumeWork(breath, transitions, samples) {
var
ct
=
Math
.
min
(
flows
[
0
].
ms
,
pressures
[
0
].
ms
);
var
lfp
=
{
val
:
flows
[
0
].
val
,
ms
:
flows
[
0
].
ms
}
;
// last flow point
var
lpp
=
{
val
:
pressures
[
0
].
val
,
ms
:
pressures
[
0
].
ms
};
// last pressure_point
var
fi
=
increment_past
(
flows
,
ct
,
0
);
// Index of next flow sample
var
pi
=
increment_past
(
pressures
,
ct
,
0
);
// Index of next pressure sample
var
fi
=
increment_past
(
flows
,
flows
[
0
].
ms
,
0
);
// Index of next flow sample
var
pi
=
increment_past
(
pressures
,
pressures
[
0
].
ms
,
0
);
// Index of next pressure sample
var
w
=
0
;
// current work
// compute flow at time ms give index and last point
...
...
@@ -1445,17 +1526,24 @@ function PressureVolumeWork(breath, transitions, samples) {
return
last
.
val
+
(
cur
.
val
-
last
.
val
)
*
(
ms
-
ms0
)
/
(
ms1
-
ms0
);
}
function
increment_past
(
array
,
ms
,
index
)
{
var
begin
=
index
;
while
(
index
<
array
.
length
&&
array
[
index
].
ms
<=
ms
)
index
++
;
if
(
index
==
begin
)
debugger
;
if
(
index
>=
array
.
length
)
return
null
;
else
return
index
;
}
// A fundamental invariant:
// pressures[pi].ms > lpp.ms
// flows[pi].ms > lfp.ms
while
((
fi
+
pi
)
<
(
flows
.
length
+
pressures
.
length
))
{
// Invariant always increment fi or pi
// fi and pi point to unprocessed value
console
.
assert
(
pressures
[
pi
].
ms
>
lpp
.
ms
);
console
.
assert
(
flows
[
fi
].
ms
>
lfp
.
ms
);
var
ms
;
if
(
pressures
[
pi
].
ms
<=
flows
[
fi
].
ms
)
{
// process pressure
ms
=
pressures
[
pi
].
ms
;
...
...
@@ -1473,7 +1561,8 @@ function PressureVolumeWork(breath, transitions, samples) {
if
((
fi
===
null
)
||
(
pi
===
null
))
break
;
var
dur_s
=
(
ms
-
ct
)
/
1000
;
console
.
log
(
"
dur_s
"
,
dur_s
);
console
.
assert
(
pressures
[
pi
].
ms
>
lpp
.
ms
);
console
.
assert
(
flows
[
fi
].
ms
>
lfp
.
ms
);
var
nf
=
f
(
ms
,
flows
[
fi
],
lfp
);
var
np
=
f
(
ms
,
pressures
[
pi
],
lpp
);
var
f1
=
(
lfp
.
val
+
nf
)
/
2
;
...
...
@@ -1490,48 +1579,6 @@ function PressureVolumeWork(breath, transitions, samples) {
lpp
=
{
val
:
p1
,
ms
:
ms
};
ct
=
ms
;
}
console
.
log
(
"
begin transition time, end transition time:
"
,
beginTime_ms
,
endTime_ms
);
console
.
log
(
"
ms,w
"
,
ms
,
w
);
//var pressureVolume_prod= 0;
//for(var j = a; j
<
z
-
1
;
j
++
)
{
// // I'll use qadrilateral approximation.
// // We'll form each quadrilateral between two samples.
// var ms = flows[j+1].ms - flows[j].ms;
// var ht = (((flows[j+1].val*pressures[j+1].val) + (flows[j].val*pressures[j+1].val ))/2) * CONVERT_PIRDS_TO_SLM;
// // Flow in standard liters per minute,
// // divide by 60000 to get liters/s
// pressureVolume_prod += ms * ht/60000;
// if (isNaN(pressureVolume_prod)) {
// debugger;
// }
// }
// pressure cm H2O --> atm (divide by 1033)
// return pressureVolume_prod/1033
// average pressure * average flow ~ approximation of work
var
pAv_cm
=
0
;
for
(
var
i
=
0
;
i
<
pressures
.
length
;
i
++
)
{
pAv_cm
+=
pressures
[
i
].
val
/
10
;
}
pAv_cm
/=
pressures
.
length
;
var
pressures_pascales
=
pAv_cm
*
98.0665
;
//cm to pasc.
var
fAv_lpm
=
0
;
for
(
var
i
=
0
;
i
<
flows
.
length
;
i
++
)
{
fAv_lpm
+=
flows
[
i
].
val
/
1000
;
}
fAv_lpm
/=
flows
.
length
;
console
.
log
(
"
flows:
"
,
flows
,
"
\n
pressures:
"
,
pressures
)
console
.
log
(
"
pAv, vAv =
"
,
pAv_cm
,
fAv_lpm
);
var
flow_cubicMetersPerSecond
=
fAv_lpm
/
1000
/
60
;
//lpm to cmps
var
avPower
=
pressures_pascales
*
flow_cubicMetersPerSecond
;
// Watts
var
avWork
=
avPower
*
(
endTime_ms
-
beginTime_ms
)
/
1000
;
// Joules
console
.
log
(
"
Power (Watts):
"
,
avPower
);
console
.
log
(
"
Work (Joules):
"
,
avWork
);
console
.
log
(
"
ms, Work main (Joules)
"
,
ms
,
w
);
return
w
;
}
}
...
...
@@ -1542,42 +1589,52 @@ function generate_synthetic_trace() {
const
SAMPLES_MS_PER_SAMPLE
=
1
;
var
trace
=
[];
var
cur
=
0
;
function
push_samples
(
start
,
num
,
d
,
f
)
{
// p is a probability of occuring.
function
push_samples
(
start
,
num
,
d
,
f
,
pd
,
pf
)
{
for
(
var
i
=
start
;
i
<
start
+
num
;
i
++
)
{
trace
.
push
(
{
event
:
"
M
"
,
loc
:
"
A
"
,
ms
:
i
,
num
:
0
,
type
:
"
D
"
,
val
:
d
});
trace
.
push
(
{
event
:
"
M
"
,
loc
:
"
A
"
,
ms
:
i
,
num
:
0
,
type
:
"
F
"
,
val
:
f
});
if
(
Math
.
random
()
<
pd
)
{
trace
.
push
(
{
event
:
"
M
"
,
loc
:
"
A
"
,
ms
:
i
,
num
:
0
,
type
:
"
D
"
,
val
:
d
});
}
if
(
Math
.
random
()
<
pf
)
{
trace
.
push
(
{
event
:
"
M
"
,
loc
:
"
A
"
,
ms
:
i
,
num
:
0
,
type
:
"
F
"
,
val
:
f
});
}
}
}
push_samples
(
0
,
SAMPLES_PER_PHASE
,
-
200
,
-
50000
);
push_samples
(
SAMPLES_PER_PHASE
,
SAMPLES_PER_PHASE
,
200
,
50000
);
push_samples
(
SAMPLES_PER_PHASE
*
2
,
SAMPLES_PER_PHASE
,
-
200
,
-
50000
);
push_samples
(
SAMPLES_PER_PHASE
*
3
,
SAMPLES_PER_PHASE
,
200
,
50000
);
const
P1
=
1
/
2
;
const
P2
=
1
/
2
;
push_samples
(
SAMPLES_PER_PHASE
,
SAMPLES_PER_PHASE
,
200
,
50000
,
P1
,
P2
);
push_samples
(
0
,
SAMPLES_PER_PHASE
,
-
200
,
-
50000
,
P1
,
P2
);
push_samples
(
SAMPLES_PER_PHASE
,
SAMPLES_PER_PHASE
,
200
,
50000
,
P1
,
P2
);
push_samples
(
SAMPLES_PER_PHASE
*
2
,
SAMPLES_PER_PHASE
,
-
200
,
-
50000
,
P1
,
P2
);
push_samples
(
SAMPLES_PER_PHASE
*
3
,
SAMPLES_PER_PHASE
,
200
,
50000
,
P1
,
P2
);
return
trace
;
}
function
nearp
(
x
,
y
,
d
)
{
return
Math
.
abs
(
x
-
y
)
<=
d
;
}
function
testWorkSynthetic
(){
// breaths give us inspiration transition points
var
samples
=
generate_synthetic_trace
();
const
JOULES_IN_BREATH
=
1
*
1961.33
*
50000
/
(
60
e
+
6
);
var
flows
=
samples
.
filter
(
s
=>
s
.
event
==
'
M
'
&&
s
.
type
==
'
F
'
);
var
first_time
=
flows
[
0
].
ms
;
var
last_time
=
flows
[
flows
.
length
-
1
].
ms
;
...
...
@@ -1592,10 +1649,10 @@ function testWorkSynthetic(){ // breaths give us inspiration transition points
console
.
log
(
breaths
);
for
(
i
=
0
;
i
<
breaths
.
length
;
i
++
)
{
var
w
=
PressureVolumeWork
(
breaths
[
i
],
transitions
,
samples
);
console
.
assert
((
w
==
null
)
||
(
w
==
JOULES_IN_BREATH
));
console
.
log
(
"
final =
"
,
w
);
console
.
assert
((
w
==
null
)
||
(
nearp
(
w
,
JOULES_IN_BREATH
)
,
0.1
)
);
console
.
log
(
"
final
(Joules)
=
"
,
w
);
}
return
true
;
}
...
...
@@ -1680,6 +1737,8 @@ function testWorkSynthetic(){ // breaths give us inspiration transition points
trans_end_exhale
:
i
,
}
);
var
w
=
PressureVolumeWork
(
breaths
[
breaths
.
length
-
1
],
transitions
,
samples
);
breaths
[
breaths
.
length
-
1
].
work
=
w
;
beg
=
i
;
expiring
=
false
;
vole
=
integrateSamples
(
last
,
transitions
[
i
].
sample
,
flows
);
...
...
@@ -1758,6 +1817,8 @@ function computeMovingWindowTrace(samples,t,v) {
trans_end_exhale
:
i
,
}
);
var
w
=
PressureVolumeWork
(
breaths
[
0
],
transitions
,
samples
);
breaths
[
0
].
work
=
w
;
beg
=
i
;
expiring
=
false
;
vole
=
integrateSamples
(
last
,
transitions
[
i
].
sample
,
flows
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment