% The function simulate.m implements various computational models of the % human cardiovascular system. The models include the following three % major components: % % 1) Lumped parameter, pulsatile heart and circulation % (various preparations) % 2) Short-term regulatory system % a) Arterial baroreflex system % b) Cardiopulmonary baroreflex system % c) Direct neural coupling mechanism between Qlu and F % 3) Resting physiologic perturbations % a) respiratory activity % b) eExogenous disturbances to % i) Ra % ii) F % iii) Qvo % iv) Pasp % % Function arguments: % flag - 8x1 vector indicating the status of the model % (overrides parameter values assigned in th) % - [preparation breathing dncm baro dra dpasp df dqvo] % % - preparation - status of pulsatile heart and circulation % - 0 - intact circulation (nominal) % - 1 - heart-lung unit designed for measuring cardiac function curves % - 2 - systemic circulation designed for measuring venous return curves % - 3 - left ventricle % (automated step changes in Ppv and Pa NOT implemented) % - 4 - intact circulation for measurement of single ventricular % contraction Pa response % - 5 - intact circulation with only linear elements % - 6 - intact circulation with third-order systemic arteries % - 7 - intact circulation with nonlinear systemic arterial compliance % - 8 - intact circulation with third-order systemic arteries % and nonlinear large, elastic arterial compliance % - 9 - intact circulation with an arterial pressure reservoir % - 10 - intact circulation with contracting atria % - breathing - status of breathing (Qlu) % - 0 - no breathing (Qlu constant) % - 1 - fixed-rate breathing (Qlu periodic) % - 2 - random-interval breathing (Qlu random; 5 s mean period) % instantaneous alveolar ventilation rate constant over time % - 3 - random-interval breathing (Qlu random; 5 s mean period) % tidal volume fixed; instantaneous alveolar ventilation rate % not constant % - 4 - step increase in breathing (Qlu step) % - 5 - impulse increase in breathing (Qlu impulse) % - dncm - status of direct neural coupling mechanism between Qlu and F % - 0 - dncm off % - 1 - dncm on (not applicable for step increase in Qlu) % - baro - status of baroreflexes % - 0 - arterial and cardiopulmonary baroreflexes off % - 1 - arterial baroreflex on only % - 2 - cardiopulmonary baroreflex on only % - 3 - arterial and cardiopulmonary baroreflexes on % - dra - status of bandlimited disturbance to Ra % - 0 - dra off % - 1-3 - dra on % - 1 - 1/f fluctuations % - 2 - bandlimited, white fluctuations % - 3 - sinusoidal fluctuations % - dpasp - status of sinusoidal disturbance to Pasp % - 0 - dpasp off % - 1 - dpasp on % - df - status of 1/f disturbance to F % - 0 - df off % - 1 - df on % - dqvo - status of bandlimited disturbance to Qvo % - 0 - dqvo off % - 1 - dqvo on % th - 113x1 vector containing the parameter values characterizing % the simulation % outputfile - prefix of the output files in MIT format generated by the model % parameterfile - name of a file which contains the parameter values % characterizing the model and its execution % signals - the signals to be viewed by WAVE as the data are generated % % NOTE: If this program is executed in the MATLAB environment, it will % not be possible to implement on-line viewing and parameter updating % Thus, the last three arguments should be omitted. % % Function outputs: % P - matrix representing simulated pressures [mmHg] % = [Pl Pe Pv Pr Ppa Ppv Pth Palv Pra Pm] for preparation == 6,8 % = [Pl Pa Pv Pr Ppa Ppv Pth Palv Pra Pla] for preparation == 10 % = [Pl Pa Pv Pr Ppa Ppv Pth Palv Pra] otherwise % Q - matrix representing simulated volumes [ml] % = [Ql Qe Qv Qr Qpa Qpv Qlu Qm] for preparation == 6,8 % = [Ql Qa Qv Qr Qpa Qpv Qlu Qra Qla] for preparation == 10 % = [Ql Qa Qv Qr Qpa Qpv Qlu] otherwise % q - matrix representing simulated flow rates [ml/s] % = [qpv ql qm qv qr qpa qe] for preparation == 6,8 % = [qla ql qa qra qr qpa qv qpv] for preparation == 10 % = [qpv ql qa qv qr qpa] otherwise % ap - matrix representing simulated adjustable parameters % = [Cls Crs Qvo Ra F Tsys] % ve - matrix representing the ventricular variable elastances % [mmHg/ml] % = [El Er Ela Era] for preparation == 10 % = [El Er] otherwise % qrs - vector representing times of ventricular contractions [s] % t - vector representing the associated time [s] % num - matrix representing either cardiac function or venous % return curve numerics % = [mra mpa mco] for preparation == 1 % = [mra mco] for preparation == 2 % = [0, 0] otherwise % % Function usage (in MATLAB): % % [P,Q,q,ap,ve,qrs,t,num] = simulate(flag,th); % function [P,Q,q,ap,ve,qrs,t,num] = simulate(flag,th,outputfile,parameterfile,signals) % Declaring C functions. %#function wave_remote read_key write_param % Checking number of arguments. If there are only two arguments, % this indicates MATLAB execution and thus on-line viewing is % turned off. (If it were left on, MATLAB would produce an error.) if (nargin == 2) signals = '-1'; end % Checking dimensionality of the argument flag -- status parameters. % If flag is of incorrect dimension, the program will exit in error. if (length(flag) ~= 8) error('flag is not of correct dimension'); end % Assigning status parameters to new variable names. preparation = flag(1); breathing = flag(2); dncm = flag(3); baro = flag(4); dra = flag(5); dpasp = flag(6); df = flag(7); dqvo = flag(8); % Assigning numerical integration variables. % Number of integration steps. tics = th(106); % Integration step size (s). deltaT = 1/th(113); % Assigning integrate and fire variables. % Fraction of current cardiac cycle that integration step is at. ipfm = 0; % Current number of ventricular contractions. qrs_index = 1; % Time in current cardiac cycle that integration is at. sumdeltaT = 0; % Short-term regulatory systems and resting physiologic % perturbation variables. % Note there are restrictions on altering Sgran and Sratio. % 1) Sgran*Sratio <= 1.0. % 2) (1.5/Sgran) must be an integer. % 3) ((2/Sgran)-((Sratio*Sgran/2)/Sgran)) must be an integer. % 4) (0.5-(Sratio*Sgran/2))/Sgran must be an integer. % Granularity (s). Sgran = 0.0625; % Ratio of length of averaging window to Sgran % (must be an integer). Sratio = 4; % Duration (samples). Slength = 40/Sgran; % Generation of a vector of arrival times for each respiratory cycle. % at(1) = 0 & length(at) ~= 1: Qlu periodic if (breathing == 1) at = zeros(ceil((deltaT*tics)+1)+1,1); i = 2; x = (at(i) <= deltaT*tics+1); mbintscalar(x); while (x) i = i+1; at(i) = at(i-1)+th(42); x = (at(i) <= deltaT*tics+1); mbintscalar(x); end at = at(1:i); % at(1) = 1: Qlu random with constant alveolar ventilation rate (2) % at(1) = 2: Qlu random with fixed tidal volume (3) elseif (breathing == 2 | breathing == 3) at = zeros(ceil((deltaT*tics)+1)+1,1); if (breathing == 2) at(1) = 1; else at(1) = 2; end i = 2; at(i) = rand_int_breath; x = (at(i) <= deltaT*tics+1); mbintscalar(x); while (x) i = i+1; at(i) = at(i-1) + rand_int_breath; x = (at(i) <= deltaT*tics+1); mbintscalar(x); end at = at(1:i); % at(1) = 0 & length(at) == 1: Qlu constant elseif (breathing == 0) at = 0; % at(1) = 3 (length(at) == 2): step Qlu (cannot implement dncm) elseif (breathing == 4) at = [3; th(36)]; % at(1) = 4 (length(at) == 3): impulse Qlu elseif (breathing == 5) at = [4; th(36); (((deltaT*tics)+1)+1)]; % Exiting program with error if breathing is not valid. else error('breathing is not a valid option'); end % Pre-calculating Qlu, Pth, dPth, and Ppac (Palv) over the entire % integration period from the generated arrival time vector. thbreathe = resp_act(th,at,deltaT/2,0,(tics-1)*deltaT); % Adding a step change to Qlu, Pth, dPth, and Ppac, if mandated via Qfrs. if ((breathing == 0 | breathing == 1 | breathing == 2) & th(36) ~= 0) th(103) = 0; thbreathes = resp_act(th,[3; th(36)],deltaT/2,0,(tics-1)*deltaT); dthbreathe = [-th(98)*ones(1,length(thbreathes)); -th(23)*ones(1,length(thbreathes)); zeros(2,length(thbreathes))]; thbreathe = thbreathe+thbreathes+dthbreathe; end % Creating the filter characterizing direct neural coupling mechanism % betweeen Qlu and F at a sampling period of Sgran. Decimating the % above Qlu to a sampling period of Sgran in order to implement this filter. % (not applicable to step input of Qlu) if (dncm == 1) hilvhr = dncm_filt(th,[Sgran; Slength; Sratio]); ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran); % Taking care of filtering edge effects. ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)]; rsastep = 1; % Exiting program with error if dncm is not valid. elseif (dncm ~= 0) error('dncm is not a valid option'); end % Autoregulation of local vascular beds -- exogenous disturbance to Ra. % Generating sinusoidal Ra disturbance at a sampling period of Sgran % for entire integration period. if (dra == 3) amp = th(61); freq = th(62); n = floor(((deltaT*tics)+1)/Sgran)+(Sratio-1); i = 1:n; tr = (i-1)*Sgran; Ralvrp = (amp/(Sgran*2*pi*freq))*(cos(2*pi*freq*tr)-cos(2*pi*freq*(tr+Sgran))); Ralvr = zeros(1,length(Ralvrp)-Sratio+1); for kt = Sratio:length(Ralvrp) Ralvr(kt-(Sratio-1)) = sum(Ralvrp(kt-(Sratio-1):kt))/Sratio; end Ralvr = Ralvr+((0.01*amp)/sqrt(Sgran))*randn(1,length(Ralvr)); lvrstep = 2; % Generating bandlimited 1/f Ra disturbance at a sampling period of Sgran % for entire integration period. elseif (dra == 1) hra = bl_filt(th(44),Sgran); n = floor(((deltaT*tics)+1)/Sgran)+length(hra); whitenoise = sqrt(1/Sgran)*th(47)*randn(1,n); dmin = -4; dmax = 0; honeoverfra = oneoverf_filt(th,Sgran,dmin,dmax); Ralvrw = conv(honeoverfra,whitenoise); Ralvrw = Ralvrw(length(Ralvrw)-length(n)+1:length(Ralvrw)); % Filtering 1/f disturbance to Ra. Ralvr = conv(hra,Ralvrw); Ralvr = Ralvr(length(hra)+1:length(Ralvrw)); lvrstep = 2; % Generating white noise at a sampling period of Sgran for bandlimited % disturbance to Ra. elseif (dra == 2) wra = sqrt(1/Sgran)*th(47)*randn(length(-60:Sgran:60),1); % Exiting program with error if dra is not valid. elseif (dra ~= 0) error('dra is not a valid option'); end % Generating sinusoidal Pasp disturbance at a sampling period of Sgran % for entire integration period. if (dpasp == 1); amp = th(63); freq = th(64); n = floor(((deltaT*tics)+1)/Sgran)+(Sratio-1)+Slength; i = 1:n; tr = (i-1)*Sgran; tempPsp = (amp/(Sgran*2*pi*freq))*(cos(2*pi*freq*tr)-cos(2*pi*freq*(tr+Sgran))); deltaPsp = zeros(length(tempPsp)-Sratio+1,1); for kt = Sratio:length(tempPsp) deltaPsp(kt-(Sratio-1)) = sum(tempPsp(kt-(Sratio-1):kt))/Sratio; end deltaPsp = deltaPsp+((0.1*amp)/sqrt(Sgran))*randn(length(deltaPsp),1); ceostep = 2; elseif (dpasp == 0) deltaPsp = 0; % Exiting program with error if dpasp is not valid. else error('dpasp is not valid'); end % Creating 1/f filter and white noise at a sampling period of Sgran % for the exogenous disturbance to F. if (df == 1) dmin = -4; % Desired minimum frequency decade with 1/f character dmax = 0; % Desired maximum frequency decade with 1/f character hans = ans_filt(th,[Sgran; Slength; Sratio]); honeoverf = oneoverf_filt(th,Sgran,dmin,dmax); hf = conv(honeoverf,hans); wf = sqrt(1/Sgran)*th(48)*randn(length(hf),1); % Exiting program with error if df is not valid. elseif (df ~= 0) error('df is not a valid option'); end % Generating bandlimited, white disturbance to Qvo at a sampling period of Sgran % for entire integration period. if (dqvo == 1) hvvo = bl_filt(th(65),Sgran); n = floor(((deltaT*tics)+1)/Sgran)+length(hvvo); Vvow = sqrt(1/Sgran)*th(66)*randn(1,n); Vvo = conv(hvvo,Vvow); Vvo = Vvo(length(hvvo)+1:length(Vvow)); nvvostep = 2; % Exiting program with error if dqvo is not valid. elseif (dqvo ~= 0) error('dqvo is not a valid option'); end % Pre-allocating memory for function output waveforms which is % necessary for dramatic improvement in execution speed. P = zeros(11,tics); Q = zeros(9,tics); q = zeros(8,tics); t = zeros(1,tics); ap = zeros(9,tics); ve = zeros(4,tics); % Pre-allocating memory and initializing variables for % cardiac function/venous return curve generation. if (preparation == 1) % Pre-allocating memory. Crd = ((th(27)-th(12))/th(32))*th(6); final = round((th(27)-th(12)-20)/Crd)+3; rarange = [final:-th(88):0, th(23)+1]; lengthra = length(rarange); if (lengthra == 2); lengthra = 1; rarange = final; end lengthsa = length(30:th(90):th(31)-10); lengtht = lengthra*lengthsa; num = zeros(3,lengtht); % Initializing variables for family of cardiac function curves. if (lengthra > 1 & lengthsa > 1) countn = 0; countj = 0; th(30) = final; th(29) = 30; tmp = 0; % Initializing variables for a single cardiac function curve. elseif (lengthra > 1 & lengthsa == 1) countn = 0; countj = 0; th(30) = final; tmp = 0; % Initializing variables for curve of average ql versus Pa. elseif (lengthra == 1 & lengthsa > 1) final = th(30); rarange = final; th(29) = 30; tmp = 0; end % Initializing variables for averaging Pra and ql over each cardiac cycle. summrap = 0; summco = 0; % Initializing variable representing number of beats until voltage % source(s) is varied. fb_int = 10; elseif (preparation == 2) % Pre-allocating memory. Crs = ((th(27)-th(12))/th(32))*th(5); lengthra = length([Crs:th(89):60]); num = zeros(2,lengthra); if (length(num(1,:)) > 1) countn = 0; Crd = Crs; th(6) = (th(32)/(th(27)-th(12)))*Crd; end % Initializing variables for integrating Pra and qv over each cardiac cycle. summrap = 0; summco = 0; % Initializing variable representing number of beats until Crd % is varied. fb_int = 10; else num = zeros(2,1); end % Resetting ventricular compliance values for the intact circulatory % preparation with only linear elements. if (preparation == 5) th(1) = th(1)*((th(26)-th(9))/th(31)); th(2) = th(2)*((th(26)-th(9))/th(31)); th(5) = th(5)*((th(27)-th(12))/th(32)); th(6) = th(6)*((th(27)-th(12))/th(32)); th(31) = th(26)-th(9); th(32) = th(27)-th(12); end % Initializing the function output waveforms. % Adjustable parameters. ap(1:6,1) = [th(1)*((th(26)-th(9))/th(31)) th(5)*((th(27)-th(12))/th(32)) th(11) th(16) th(22) .3*sqrt(th(24))]'; % Pulsatile heart and circulation preparation. if (preparation == 0 | preparation == 4 | preparation == 5 | preparation == 7) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = intact_init_cond(th); elseif (preparation == 1) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = hlu_init_cond(th); elseif (preparation == 2) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = sc_init_cond(th); elseif (preparation == 3) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = lv_init_cond(th); elseif (preparation == 5) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = init_cond(th); elseif (preparation == 6) [Ptemp,Q(1:7,1),q(1:7,1),ve(1:2,1)] = third_init_cond(th); P(1:6,1) = Ptemp(1:6); P(10:11,1) = Ptemp(7:8); Q(8,1) = Q(7,1); elseif (preparation == 7) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = nac_init_cond(th); elseif (preparation == 8) [Ptemp,Q(1:7,1),q(1:7,1),ve(1:2,1)] = third_nac_init_cond(th); P(1:6,1) = Ptemp(1:6); P(10:11,1) = Ptemp(7:8); Q(8,1) = Q(7,1); elseif (preparation == 9) [P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = apr_init_cond(th); elseif (preparation == 10) [tempp,tempv,q(1:8,1),ve(:,1)] = a_init_cond(th); P(1:6,1) = tempp(1:6); P(9,1) = tempp(7); P(10:11,1) = tempp(7:8); Q(1:6,1) = tempv(1:6); Q(8:9,1) = tempv(7:8); % Exiting program with error if preparation is not valid, else error('preparation is not a valid option'); end if (preparation ~= 10) P(9,1) = P(4,1); end % Respiratory-related waveforms. P(7,1) = thbreathe(2,1); P(8,1) = thbreathe(4,1); Q(7,1) = thbreathe(1,1); % Assigning setpoint variables % Setpoint pressure for arterial baroreflex (mmHg). Pasp = th(40); % Setpoint pressure for cardiopulmonary baroreflex (mmHg). Pratrsp = th(41); % F setpoint value (Hz). Fsp = th(22); % Ra setpoint value (mmHg-s/ml). Rasp = th(16); % Cls, Crs setpoint value (ml/mmHg). Clssp = th(1); Crssp = th(5); % Qvo setpoint value (ml). Qvosp = th(11); % 7x1 vector of setpoint values. thsp = [Pasp; Fsp; Rasp; Clssp; Crssp; Qvosp; Pratrsp]; % Initializing baroreflex-related variables. if (baro > 0 & baro < 4) % Initializing input pressures. (The lowest % index indicates the most recent pressure.) bP = zeros(Slength,1); bPratr = zeros(Slength,1); for i = 1:Slength; bP(i) = P(2,1); bPratr(i) = P(9,1)-P(7,1); end bPtemp = zeros(Sratio,1); bPratrtemp = zeros(Sratio,1); for i = 1:Sratio bPtemp(i) = P(2,1); bPratrtemp(i) = P(9,1)-P(7,1); end % Initializing variables for integrating Pa, Pratr, % and t over each Sgran interval. sumP = 0; sumPratr = 0; sumt = 0; % Exiting program with error if baro is not valid, elseif (baro ~= 0) error('baro is not a valid option'); end % Initializing parameter vector and other variables in order to % implement linear interpolation of the controllable parameters. thn = th; thp = th; tn = 0; tp = 0; % Initializing parameters for writing data and annotations to file % in MIT format. Calling the WAVE window. if (strcmp(signals,'-1') == 0) % Initializing waveform file variables. kstart = 1; qrs_index_start = 1; fid = fopen([outputfile '.dat'],'wa'); % Initializing annotation file. fid2 = fopen([outputfile '.qrs'],'wa'); fwrite(fid2,1,'bit10'); fwrite(fid2,1,'ubit6'); fwrite(fid2,-1,'bit10'); fwrite(fid2,62,'ubit6'); Nbytes = length(parameterfile)+2; fwrite(fid2,Nbytes,'bit10'); fwrite(fid2,63,'ubit6'); fwrite(fid2,[parameterfile '.' num2str(0)],[num2str(Nbytes) '*uchar']); % Assigning annotation flag. if (th(105) == 0) annotator = '-1'; else annotator = 'qrs'; end % Initializing parameter update counter. count_pc = 0; % Calling the WAVE window. wave_remote( outputfile, annotator, 0, signals ); % Initializing variables which permit annotation flag to be % updated on-line. wrflag = 1; outputfile2 = ['./' outputfile]; end % Generating the function output waveforms for each integration step. for k = 2:tics % Generating the pressure waveforms and associated time for % the current integration step -- fourth-order Runge-Kutta % integration. Ptempn = rk4([P(1:6,k-1); P(10:11,k-1)],[Q(1,k-1);Q(4,k-1)],thbreathe(:,2*(k-1)+1:2*(k-1)+3),th,ipfm,sumdeltaT,deltaT,preparation); P(1:6,k) = Ptempn(1:6); if (preparation == 10) P(9,k) = Ptempn(7); end P(10,k) = Ptempn(7); P(11,k) = Ptempn(8); % Updating time. t(k) = t(k-1)+deltaT; % Computing fraction of cardiac cycle that was surpassed % during the integration step. frac = deltaT*th(22); % Obtaining Pth, Ppac (Palv), and Qlu at the current integration step P(7,k) = thbreathe(2,2*(k-1)+1); P(8,k) = thbreathe(4,2*(k-1)+1); Q(7,k) = thbreathe(1,2*(k-1)+1); % Integrating Pa data using the Backward Euler method and % denoting the time into the integration. sumt = sumt+deltaT; sumP = sumP+P(2,k)*deltaT; % Computing Pra and integrating Pratr using the Backward % Euler method. if (preparation ~= 10) x = (P(4,k) >= P(3,k)); mbintscalar(x); if (x) P(9,k) = P(3,k); else P(9,k) = P(4,k); end end sumPratr = sumPratr+(P(9,k)-P(7,k))*deltaT; % Implementing the short-term regulatory system and/or resting % physiologic perturbations each Sgran s. x = (sumt > Sgran); mbintscalar(x); if (x) % Setting final th values of previous Sgran to initial th % value of current Sgran. thp = thn; tp = tn; % Initializing thc -- a vector which contains the mandated % adjustments to controllable parameters of sampling period % Sgran. thc = zeros(5,1); % Implementing the arterial baroreflex. if (baro == 1 | baro == 3) % Calculating the integral of Pa precisely % over the Sgran interval. sumP = sumP-P(2,k)*deltaT; sumP = sumP+P(2,k)*(deltaT-(sumt-Sgran)); % Placing the averaged Pa over the Sgran*Sratio % interval in the most recent slot of the arterial % baroreflex input. bPtemp = [(sumP/Sgran); bPtemp(1:Sratio-1)]; avebP = sum(bPtemp)/Sratio; bP = [avebP; bP(1:Slength-1)]; % Calculating the new baroreflex adjusted parameters % for the next Sgran interval. % For constant Pasp. if (length(deltaPsp) == 1) thc = thc+abreflex([Sgran; Slength; Sratio],bP,th,thsp,deltaPsp); % For sinusoidally varying Pasp. else thc = thc+abreflex([Sgran; Slength; Sratio],bP,th,thsp,deltaPsp(dpasp:dpasp+length(bP)-1)); dpasp=dpasp+1; end end % Implementing the cardiopulmonary baroreflex. if (baro == 2 | baro == 3) % Calculating the integral of Pratr precisely % over the Sgran interval. sumPratr = sumPratr-(P(9,k)-P(7,k))*deltaT; sumPratr = sumPratr+(P(9,k)-P(7,k))*(deltaT-(sumt-Sgran)); % Placing the averaged Pratr over the Sgran*Sratio interval % in the most recent slot of the cardiopulmonary baroreflex % input. bPratrtemp = [(sumPratr/Sgran); bPratrtemp(1:Sratio-1)]; avebPratr = sum(bPratrtemp)/Sratio; bPratr = [avebPratr; bPratr(1:Slength-1)]; % Calculating the new baroreflex adusted parameters % for the next Sgran interval. thc = thc+cpreflex([Sgran; Slength; Sratio],bPratr,th,thsp); end % Implementing the direct neural coupling mechanism between % Qlu and F. if (dncm == 1) % Creating the dncm filter. hilvhr = dncm_filt(th,[Sgran; Slength; Sratio]); % Creating the input Qlu vector to be convolved with the filter. tempilv = ilv(rsastep:rsastep+length(hilvhr)-1); tempilv = tempilv-th(98); % Compute the mandated change in F from the convolution. thc(1) = thc(1)+sum(tempilv.*hilvhr(length(hilvhr):-1:1)); rsastep = rsastep+1; end % Implementing the exogenous disturbance to Ra. if (dra ~= 0) % Bandlimited, white disturbance if (dra == 2) % Creating the bandlimited filter. hra = bl_filt(th(44),Sgran); % Creating white noise input to be convolved with the filter. wra = [sqrt(1/Sgran)*th(47)*randn(1); wra(1:length(wra)-1)]; % Computing the mandated change to Ra. thc(2) = thc(2)+sum(wra.*hra'); % Other Ra disturbance. else % Assigning mandated change to Ra which was pre-computed. thc(2) = thc(2)+Ralvr(lvrstep); lvrstep = lvrstep+1; end end % Implementing the 1/f disturbance to F. if (df == 1) % Creating a filter which is a cascade combination of % an autonomic filter and 1/f filter. hans = ans_filt(th,[Sgran; Slength; Sratio]); hf = conv(honeoverf,hans); % Creating white noise input to be convolved with the filter. wf = [sqrt(1/Sgran)*th(48)*randn(1); wf(1:length(wf)-1)]; % Computing mandated change to F. thc(1) = thc(1)+sum(wf.*hf); end % Implementing disturbance to Qvo. if (dqvo == 1) % Assigning mandated change to Qvo which was pre-computed. thc(5) = thc(5)+Vvo(nvvostep); nvvostep = nvvostep+1; end % Calculating the values of the adjustable parameters at the % end of the next Sgran interval and assigning these values % to the thn vector. thn = th; thn(1) = thsp(4)+thc(3); thn(5) = thsp(5)+thc(4); thn(11) = thsp(6)+thc(5); thn(16) = thsp(3)+thc(2); thn(22) = thsp(2)+thc(1); % Denoting the time at the start of the next Sgran interval. tn = t(k)-(sumt-Sgran); % Resetting the initial values for the integration % of Pa, Pratr, and t over the next Sgran interval. sumP = P(2,k)*(sumt-Sgran); sumPratr = (P(9,k)-P(7,k))*(sumt-Sgran); sumt = sumt-Sgran; end % Calculating the new values of the adjustable parameters % at the current time step via linear interpolation and assigning % the values to the vector tha. (Note that the mandated changes % to Cls and Crs are implemented at the start of each beat.) tha = th; tha(11) = ((thn(11)-thp(11))/Sgran)*(t(k)-(tp+Sgran))+thp(11); tha(16) = ((thn(16)-thp(16))/Sgran)*(t(k)-(tp+Sgran))+thp(16); tha(22) = ((thn(22)-thp(22))/Sgran)*(t(k)-(tp+Sgran))+thp(22); % Adjusting Pv in response to any mandated change in Qvo -- for % constant volume considerations. P(3,k) = P(3,k)+(th(11)-tha(11))/th(4); % Setting the th vector to its current values. th = tha; % Computing Pra and qpv or qv over each cardiac cycle in order % to establish cardiac function/venous return curves. % (Note that ql is not computed, because it is relatively % inaccurate for large integration steps.) if (preparation == 1) summrap = summrap+0.5*deltaT*(P(9,k-1)+P(9,k)); x = (P(6,k) > P(1,k)); mbintscalar(x); if (x) qpv = (P(6,k)-P(1,k))/th(20); else qpv = 0; end summco = summco+0.5*deltaT*(q(1,k-1)+qpv); elseif (preparation == 2) summrap = summrap+0.5*deltaT*(P(9,k-1)+P(9,k)); x = (P(3,k) > P(4,k) & P(4,k) >= th(91)); y = (P(3,k) > th(91) & th(91) > P(4,k)); mbintscalar(x); mbintscalar(y); if (x) qv = (P(3,k)-P(4,k))/th(17); elseif (y) qv = (P(3,k)-th(91))/th(17); else qv = 0; end summco = summco+0.5*deltaT*(q(4,k-1)+qv); end % Recalculating the fraction advance in the cardiac cycle to account % for the mandated change to F. frac = ((deltaT-(sumt-Sgran))*th(22)) + ((sumt-Sgran)*tha(22)); % Updating time in and fraction of current cardiac cycle. % These values are associated with the newly calculated pressure % and time data. The integration of the ipfm parameter is achieved % with the Backward Euler method. sumdeltaT = sumdeltaT + deltaT; % Stopping the initiation of ventricular contractions after a % desired number of beats. if (preparation == 4 & qrs_index > th(43)) sumdelta = 0; frac = 0; end ipfm = ipfm + frac; % Completing a cardiac cycle when ipfm is greater than or equal to one. ipfmcond = (ipfm >= 1); mbintscalar(ipfmcond) if (ipfmcond) % Resetting the ipfm model once the current cardiac contraction % is complete. sumdeltaT = (ipfm - 1)/th(22); ipfm = ipfm - 1; qrs_index = qrs_index+1; % Number of beats. ap(7,qrs_index) = t(k)-sumdeltaT; % Time of each beat. ap(8,qrs_index) = k; % Sample number of each beat. % Setting next systolic interval based on previous % cardiac cycle length. th(24) = t(k)-sumdeltaT-ap(7,qrs_index-1); % Implementing mandated changes to Cls and Crs. th(1) = thn(1); th(5) = thn(5); % Varying parameters and computing averages for generation % of cardiac function/venous return curves if (preparation == 1) % Calculating the integral of Pra and qpv % precisely over the previous cardiac cycle. summrap = summrap-0.5*deltaT*(P(9,k-1)+P(9,k)); summrap = summrap+0.5*(deltaT-sumdeltaT)*(P(9,k-1)+P(9,k)); summco = summco-0.5*deltaT*(q(1,k-1)+qpv); summco = summco+0.5*(deltaT-sumdeltaT)*(q(1,k-1)+qpv); % Computing the average Pra and qpv over the % previous cardiac cycle. . mrap = summrap/(t(k)-sumdeltaT-ap(7,qrs_index-1)); mco = summco/(t(k)-sumdeltaT-ap(7,qrs_index-1)); % Recording mean Pra, Pa, and qpv to the num matrix % and varying Pv and/or Pa every fb_int beats until % all of the pre-determined variations have been % implemented. if (qrs_index == fb_int & countn < lengtht) countn = countn+1; countj = countj+1; num(1,countn) = mrap; num(2,countn) = P(2,k); num(3,countn) = mco; if (countj ~= lengthra) th(30) = rarange(countj+1); end if (countj == lengthra & countn ~= lengtht) th(29) = th(29)+th(90); P(2,k) = th(29); % Adjusting range of Pv for large Pa values. if (th(29) > 180) tmp = tmp+1; final = final-0.5*tmp; rarangei = final:-th(88):0; while (length(rarangei) < lengthra-1) rarangei = [rarangei, rarangei(length(rarangei))-th(88)]; end rarange = [rarangei, th(23)+1]; if (lengthra == 2); lengthra = 1; rarange = final; end th(30) = final; end fb_int = fb_int+5; countj = 0; P(3,k) = rarange(countj+1); elseif (countn ~= lengtht) P(3,k) = th(30); fb_int = fb_int+5; end end % Resetting the initial values for the integration % of Pra and qpv over the next cardiac cycle. summrap = 0.5*sumdeltaT*(P(9,k-1)+P(9,k)); summco = 0.5*sumdeltaT*(q(1,k-1)+qpv); end if (preparation == 2) % Calculating the integral of Pra and qv % precisely over the previous cardiac cycle. summrap = summrap-0.5*deltaT*(P(9,k-1)+P(9,k)); summrap = summrap+0.5*(deltaT-sumdeltaT)*(P(9,k-1)+P(9,k)); summco = summco-0.5*deltaT*(q(4,k-1)+qv); summco = summco+0.5*(deltaT-sumdeltaT)*(q(4,k-1)+qv); % Computing mean Pra and ql over the previous cardiac cycle. mrap = summrap/(t(k)-sumdeltaT-ap(7,qrs_index-1)); mco = summco/(t(k)-sumdeltaT-ap(7,qrs_index-1)); % Recording mean Pra and ql to the num matrix % and varying Crd after every fb_int beats % until all the pre-determined variations have % been implemented. if (qrs_index == fb_int & Crd <= 60 & lengthra ~= 1) countn = countn+1; num(1,countn)=mrap; num(2,countn)=mco; Crdo = Crd; Crd = Crd+th(89); % Adjustment of Pr in response to variation in Crd -- for % constant volume considerations. th(6) = (th(32)/(th(27)-th(12)))*Crd; ypres = (P(4,k)-P(7,k))/th(32); xvol = vent_vol(Q(4,k-1),ypres,1/Crdo); alpha = 1/th(6); x0 = 1/(alpha+1); kscale = 50; c1 = 1+exp(-kscale*(1-x0)); d1 = 1+exp(kscale*x0); denb1 = (1+(1/kscale)*log(c1/d1)); beta = (1-alpha)/denb1; c = 1+exp(-kscale*(xvol-x0)); d = 1+exp(kscale*x0); denb = (xvol+(1/kscale)*log(c/d)); P(4,k) = th(32)*(alpha*xvol+beta*denb)+P(7,k); % Incrementing fb_int. fb_int = fb_int+5; end % Resetting the initial values for the integration % of Pra and qv over the next cardiac cycle. summrap = 0.5*sumdeltaT*(P(9,k-1)+P(9,k)); summco = 0.5*sumdeltaT*(q(4,k-1)+qv); end end % Recording the adjustable parameter values at the current integration step. ap(1:6,k) = [th(1)*((th(26)-th(9))/th(31)) th(5)*((th(27)-th(12))/th(32)) th(11) th(16) th(22) .3*sqrt(th(24))]'; % Recording the variable elastance values at the current integration step. if (preparation ~= 10) [El,dEl] = var_cap(th(1),th(2),th(24),sumdeltaT); [Er,dEr] = var_cap(th(5),th(6),th(24),sumdeltaT); ve(1:2,k) = [El*(th(31)/(th(26)-th(9))); Er*(th(32)/(th(27)-th(12)))]; else [El,dEl] = var_vcap(th(1),th(2),th(24),sumdeltaT); [Er,dEr] = var_vcap(th(5),th(6),th(24),sumdeltaT); [Ela,dEla] = var_acap(th(80),th(81),th(24),sumdeltaT); [Era,dEra] = var_acap(th(84),th(85),th(24),sumdeltaT); ve(:,k) = [El*(th(31)/(th(26)-th(9))); Er*(th(32)/(th(27)-th(12))); Ela; Era]; end % Obtaining the volume values at the current integration step. Equations depend % on the preparation being implemented. if (preparation ~= 10) Q(1:6,k) = [(1/El) th(3) th(4) (1/Er) th(7) th(8)]'.*(P(1:6,k)-P(7,k)*[1 0 0 1 1 1]') + [th(9:14)]; else Q(1:6,k) = [(1/El) th(3) th(4) (1/Er) th(7) th(8)]'.*([P(1:6,k)]-P(7,k)*[1 0 0 1 1 1]')+[th(9:14)]; Q(8:9,k) = [(1/Era) (1/Ela)]'.*([P(10:11,k)]-P(7,k)*[1 1]')+[th(86); th(82)]; end if (preparation == 6) Q(2,k) = th(72)*P(2,k)+th(74); Q(8,k) = th(73)*P(10,k)+th(75); elseif (preparation == 1) Q(2,k) = 0; Q(3,k) = 0; elseif (preparation == 3) Q(2,k) = 0; Q(6,k) = 0; elseif (preparation == 7) alphatau = -th(70)/th(3); Qamax = th(71)-th(3)^2/th(70); Qao = th(71)+(th(3)^2/th(70))*exp(-th(70)*th(40)/th(3))*(1-exp(th(70)*th(40)/th(3))); Q(2,k) = (Qamax-Qao)*(1-exp(-alphatau*P(2,k)))+Qao; elseif (preparation == 8) alphatau = -th(70)/th(72); Qamax = th(76)-th(72)^2/th(70); Qao = th(76)+(th(72)^2/th(70))*exp(-th(70)*th(40)/th(72))*(1-exp(th(70)*th(40)/th(72))); Q(2,k) = (Qamax-Qao)*(1-exp(-alphatau*P(2,k)))+Qao; Q(8,k) = th(73)*P(10,k)+th(75); end if (preparation ~= 5) x = (P(1,k) < P(7,k)); mbintscalar(x); if (x) Q(1,k) = th(9)*(2/pi)*atan(((P(1,k)-P(7,k))/((2/pi)*th(9)*El))) + th(9); else yl = (P(1,k)-P(7,k))/th(31); xl = vent_vol(Q(1,k-1),yl,El); Q(1,k) = (th(26)-th(9))*xl+th(9); end x = (P(4,k) < P(7,k)); mbintscalar(x); if (x) Q(4,k) = th(12)*(2/pi)*atan(((P(4,k)-P(7,k))/((2/pi)*th(12)*Er))) + th(12); else yr = (P(4,k)-P(7,k))/th(32); xr = vent_vol(Q(4,k-1),yr,Er); Q(4,k) = (th(27)-th(12))*xr+th(12); end end % Correcting Qv and Pv in order to keep total blood volume in the % intact circulatory preparations, which may vary due to integration % error, constant. if (preparation == 0 | preparation == 4 | preparation == 5 | preparation == 6 | preparation == 7 | preparation == 8 | preparation == 9 | preparation == 10) if (preparation == 6 | preparation == 8) Qtot = sum(Q([1:6 8],k)); elseif (preparation == 10) Qtot = sum(Q([1:6 8 9],k)); else Qtot = sum(Q(1:6,k)); end Q(3,k) = Q(3,k) - (Qtot-th(21)); P(3,k) = (Q(3,k)-th(11))/th(4); end % Checking for a request to pause simulation after the completion % of every beat provided that waveforms are being viewed on-line. if (strcmp(signals,'-1') == 0 & ipfmcond) flagnew = read_key; if (flagnew == 1) % Re-reading parameter file, in the event of a possible update. thspold = thsp; thold = th; fidp = fopen(parameterfile,'r'); [th,signals] = read_param(fidp); fclose(fidp); % Precluding adjustment of unchangeable parameters. th(98) = thold(98); % Qfr th(33) = thold(33); % Pms th(88) = thold(88); % Pvs th(89) = thold(89); % Crds th(90) = thold(90); % Pas % Precluding adjustment of Pv, Pa, and Crd if they are being % automatically varied. if (preparation == 1 & lengthra > 1) th(30) = thold(30); end if (preparation == 1 & lengthsa > 1) th(29) = thold(29); end if (preparation == 2 & lengthra > 1) th(6) = thold(6); end % Setting annotator flag. if (th(105) == 0) annotator = 'wqrs'; else annotator = 'qrs'; end % Determining if parameter update is relevant to % status of current simulation. parameter_change = param_change(th,thold,flag); mbintscalar(parameter_change == 1); if (parameter_change == 1) % Annotating and documenting the relevant parameter update. count_pc = count_pc+1; ap(9,qrs_index) = count_pc; write_param(parameterfile,num2str(count_pc)); % Adjusting setpoint pressures. thsp(1) = th(40); thsp(7) = th(41); % Conserving Qfr by altering Pth at the functional reserve % volume of the lungs. th(23) = th(25)-((th(98)-th(102))/th(101)); % Updating respiratory-related pressures and volumes % over the remainder of the integration period, if necessary. % No breathing. if (breathing == 0 & th(23) ~= thold(23)) thbreathe = resp_act(th,at,deltaT/2,0,(tics-1)*deltaT); % Fixed-rate breathing. elseif (breathing == 1 & (th(42) ~= thold(42) | th(77) ~= thold(77) | th(23) ~= thold(23) | th(100) ~= thold(100))) atcount = 2; x = (at(atcount) < t(k)+1.5); mbintscalar(x); while (x) atcount=atcount+1; x = (at(atcount) < t(k)+1.5); mbintscalar(x); end start_index = k+ceil((at(atcount)-t(k))/deltaT); start_time = t(k)+deltaT*ceil((at(atcount)-t(k))/deltaT)-at(atcount); end_time = (length(thbreathe)-(2*(start_index-1)+1))*(deltaT/2)+start_time; if (start_index < tics) at = [at(1:atcount); zeros(length(start_index:tics)+1,1)]; x = (at(atcount) <= deltaT*tics+1); mbintscalar(x); while (x) atcount=atcount+1; at(atcount) = at(atcount-1)+th(42); x = (at(atcount) <= deltaT*tics+1); mbintscalar(x); end at = at(1:atcount); thbreathe(:,2*(start_index-1)+1:end) = resp_act(th,zeros(4,1),deltaT/2,start_time,end_time); ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran); ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)]; end % Random-interval breathing. elseif (breathing == 2 & (th(42) ~= thold(42) | th(77) ~= thold(77) | th(99) ~= thold(99) | th(23) ~= thold(23) | th(100) ~= thold(100))) atcount = 2; x = (at(atcount) < t(k)+1.5); mbintscalar(x); while (x) atcount=atcount+1; x = (at(atcount) < t(k)+1.5); mbintscalar(x); end start_index = k+ceil((at(atcount)-t(k))/deltaT); start_time = t(k)+deltaT*ceil((at(atcount)-t(k))/deltaT)-at(atcount); end_time = (length(thbreathe)-(2*(start_index-1)+1))*(deltaT/2)+start_time; if (start_index < tics) thbreathe(:,2*(start_index-1)+1:end) = resp_act(th,[1; (at(atcount+1:end)-at(atcount))],deltaT/2,start_time,end_time); ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran); ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)]; end end % Implementing a step change to Qlu, if mandated. if (th(36) ~= 0) if (breathing == 1 | breathing == 2) atcount = 2; x = (at(atcount) < t(k)+1.5); mbintscalar(x); while (x) atcount=atcount+1; x = (at(atcount) < t(k)+1.5); mbintscalar(x); end start_index = k+ceil((at(atcount)-t(k))/deltaT); start_time = (start_index-1)*deltaT; th(103) = start_time+1.5; elseif (breathing == 0) th(103) = t(k)+1.5; end if (th(103) < (tics-1)*deltaT) thbreathes = resp_act(th,[3; th(36)],deltaT/2,0,(tics-1)*deltaT); dthbreathe = [-th(98)*ones(1,length(thbreathes)); -th(23)*ones(1,length(thbreathes)); zeros(2,length(thbreathes))]; thbreathe = thbreathe+thbreathes+dthbreathe; ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran); ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)]; end end % Assigning values to Pth, Ppac (Palv), and Qlu P(7,k) = thbreathe(2,2*(k-1)+1); P(8,k) = thbreathe(4,2*(k-1)+1); Q(7,k) = thbreathe(1,2*(k-1)+1); % Conserving volume in each compartment of the pulsatile % heart and circulation through pressure adjustments. P(1:6,k) = conserve_vol(th,sumdeltaT,Q(1:6,k),P(7,k)); if (preparation == 1) P(2,k) = th(29); P(3,k) = th(30); end % Updating adjustable parameters via instantaneous values % and setpoint values. if (thspold(3) ~= th(16)) thn(16) = th(16); thp(16) = th(16); thsp(3) = th(16); ap(4,k) = th(16); else th(16) = thold(16); end if (thspold(2) ~= th(22)) thn(22) = th(22); thp(22) = th(22); thsp(2) = th(22); ap(5,k) = th(22); else th(22) = thold(22); end if (thspold(6) ~= th(11)) thn(11) = th(11); thp(11) = th(11); thsp(6) = th(11); ap(3,k) = th(11); else th(11) = thold(11); if (preparation == 0) P(3,k) = (Q(3,k)-th(11))/th(4); end end thn([1:10 12:15 17:21 23:end]) = th([1:10 12:15 17:21 23:end]); thp([1:10 12:15 17:21 23:end]) = th([1:10 12:15 17:21 23:end]); if (thspold(4) ~= th(1)) thsp(4) = th(1); else th(1) = thold(1); end if (thspold(5) ~= th(5)) thsp(5) = th(5); else th(5) = thold(5); end end end end % Obtaining the flow rate values at the current integration step. Equations % are dependent on the preparation being implemented. if (preparation == 0 | preparation == 1 | preparation == 2 | preparation == 4 | preparation == 5 | preparation == 6 | preparation == 7 | preparation == 8) x = (P(6,k) > P(1,k)); mbintscalar(x); if (x) q(1,k) = (P(6,k)-P(1,k))/th(20); else q(1,k) = 0; end elseif (preparation == 3) x = (th(34) > P(1,k)); mbintscalar(x); if (x) q(1,k) = (th(34)-P(1,k))/th(20); else q(1,k) = 0; end elseif (preparation == 10) x = (P(11,k) > P(1,k)); mbintscalar(x); if (x) q(1,k) = (P(11,k)-P(1,k))/th(83); else q(1,k) = 0; end end if (preparation == 0 | preparation == 1 | preparation == 4 | preparation == 5 | preparation == 6 | preparation == 7 | preparation == 8 | preparation == 9 | preparation == 10) x = (P(1,k) > P(2,k)); mbintscalar(x); if (x) q(2,k) = (P(1,k)-P(2,k))/th(15); else q(2,k) = 0; end elseif (preparation == 2) x = (P(1,k) > th(33)); mbintscalar(x); if (x) q(2,k) = (P(1,k)-th(33))/th(15); else q(2,k) = 0; end elseif (preparation == 3) x = (P(1,k) > th(29)); mbintscalar(x); if (x) q(2,k) = (P(1,k)-th(29))/th(15); else q(2,k) = 0; end end if (preparation == 0 | preparation == 2 | preparation == 4 | preparation == 5 | preparation == 7 | preparation == 9 | preparation == 10) q(3,k) = (P(2,k)-P(3,k))/th(16); elseif (preparation == 1 | preparation == 3) q(3,k) = 0; elseif (preparation == 6 | preparation == 8) q(3,k) = (P(10,k)-P(3,k))/th(16); end if (preparation ~= 10 & preparation ~= 5) x = (P(3,k) > P(4,k) & P(4,k) >= th(91)); y = (P(3,k) > th(91) & th(91) > P(4,k)); mbintscalar(x); mbintscalar(y); if (x) q(4,k) = (P(3,k)-P(4,k))/th(17); elseif (y) q(4,k) = (P(3,k)-th(91))/th(17); else q(4,k) = 0; end elseif (preparation == 5) x = (P(3,k) >= P(4,k)); mbintscalar(x); if (x) q(4,k) = (P(3,k)-P(4,k))/th(17); else q(4,k) = 0; end else x = (P(9,k) >= P(4,k)); mbintscalar(x); if (x) q(4,k) = (P(9,k)-P(4,k))/th(87); else q(4,k) = 0; end end if (preparation ~= 2) x = (P(4,k) > P(5,k)); mbintscalar(x); if (x) q(5,k) = (P(4,k)-P(5,k))/th(18); else q(5,k) = 0; end elseif (preparation == 2) x = (P(4,k) > th(28)); mbintscalar(x); if (x) q(5,k) = (P(4,k)-th(28))/th(18); else q(5,k) = 0; end end if (preparation == 2 | preparation == 5) q(6,k) = (P(5,k)-P(6,k))/th(19); elseif (preparation == 0 | preparation == 1 | preparation == 4 | preparation == 6 |preparation == 7 | preparation == 8 | preparation == 9 | preparation == 10) h1 = (1330/(1.06*980))*(P(6,k)-P(8,k)); x = h1 < -10; mbintscalar(x); y = h1 > 20; mbintscalar(y); if (x) h1 = -10; elseif (y) h1 = 20; end h2 = (1330/(1.06*980))*(P(5,k)-P(8,k)); x = h2 < -10; mbintscalar(x); y = h2 > 20; mbintscalar(y); if (x) h2 = -10; elseif (y) h2 = 20; end q(6,k) = (((P(5,k)-P(6,k))/(30*th(19)))*(h1+10)) + (((P(5,k)-P(8,k))/(30*th(19)))*(h2-h1)) - (((1.06*980)/(2660*(30*th(19))))*(h2^2-h1^2)); elseif (preparation == 3) q(6,k) = 0; end if (preparation == 10) x = (P(3,k) >= th(91) & P(9,k) >= th(91)); y = (P(3,k) > th(91) & th(91) > P(9,k)); z = (P(9,k) > th(91) & th(91) > P(3,k)); mbintscalar(x); mbintscalar(y); mbintscalar(z); if (x) q(7,k) = (P(3,k)-P(9,k))/th(17); elseif (y) q(7,k) = (P(3,k)-th(91))/th(17); elseif (z) q(7,k) = (th(91)-P(9,k))/th(17); else q(7,k) = 0; end elseif (preparation == 6 | preparation == 8) q(7,k) = P(11,k); end if (preparation == 10) q(8,k) = (P(6,k)-P(11,k))/th(20); end % Writing waveforms and annotations to files in MIT format every step parameter % seconds once a window parameter duration of data have been calculated. if (strcmp(signals,'-1') == 0 & t(k) > th(104) & (t(k)-t(kstart)) > th(78)) % Writing newly generated waveform data to MIT format files. X = [P(1:9,kstart:k); Q(1:6,kstart:k); Q(7,kstart:k)*0.1; q(1:6,kstart:k); ap(1:2,kstart:k)*100; ap(3,kstart:k); ap(4,kstart:k)*100; ap(5,kstart:k)*600; ve(1:2,kstart:k)*10]*10; fwrite(fid,X,'short'); % Updating variables necessary for writing waveforms. kstart = k+1; start_time = t(k)-th(104); % Writing newly generated annotations to MIT format files. qrso = []; qrso = diff(ap(8,qrs_index_start:qrs_index))'; for i = 1:length(qrso) fwrite(fid2,qrso(i),'bit10'); fwrite(fid2,1,'ubit6'); % If parameter update has been made, writing auxillary information. x = (ap(9,qrs_index_start+i) ~= 0); mbintscalar(x) if (x) suffix = num2str(ap(9,qrs_index_start+i)); fwrite(fid2,Nbytes+(length(suffix)-1),'bit10'); fwrite(fid2,63,'ubit6'); fwrite(fid2,[parameterfile '.' suffix],[num2str(Nbytes+length(suffix)-1) '*uchar']); end end qrs_index_start = qrs_index; % Alternating outputfile signaled to WAVE in order to permit % on-line updating of the annotation flag. if (wrflag == 0) wave_remote( outputfile, annotator, start_time, signals ); wrflag = 1; else wave_remote( outputfile2, annotator, start_time, signals ); wrflag = 0; end end % If cardiac function/venous return curves are complete, there % is no need for further integration. That is, for-loop is exited. if (preparation == 1 | preparation == 2) if (countn >= length(num')) tics = k; break; end end end % Writing remaining portion of simulated data to the MIT format files. if (strcmp(signals,'-1') == 0) % Writing last portion of generated waveform data. X = [P(1:9,kstart:tics); Q(1:6,kstart:tics); Q(7,kstart:tics)*0.1; q(1:6,kstart:tics); ap(1:2,kstart:tics)*100; ap(3,kstart:tics); ap(4,kstart:tics)*100; ap(5,kstart:tics)*600; ve(1:2,kstart:tics)*10]*10; fwrite(fid,X,'short'); % Writing last annotations. qrso = []; qrso = diff(ap(8,qrs_index_start:qrs_index))'; for i = 1:length(qrso) fwrite(fid2,qrso(i),'bit10'); fwrite(fid2,1,'ubit6'); % If parameter updates have been made, writing auxillary info. x = (ap(9,qrs_index_start+i) ~= 0); mbintscalar(x) if (x) suffix = num2str(ap(9,qrs_index_start+i)); fwrite(fid2,Nbytes+(length(suffix)-1),'bit10'); fwrite(fid2,63,'ubit6'); fwrite(fid2,[parameterfile '.' suffix],[num2str(Nbytes+length(suffix)-1) '*uchar']); end end fwrite(fid2,0,'bit10'); fwrite(fid2,0,'ubit6'); fclose(fid2); fclose(fid); end % If MATLAB execution, writing qrs vector as times of ventricular contractions. % If Linux execution, writing qrs vector as samples of ventricular contractions. if (nargin == 2) qrs = ap(7,1:qrs_index); else qrs = ap(8,1:qrs_index); end % Only supplying as output the pressures that are generated by % the model, for MATLAB execution only. if (preparation == 6 | preparation == 8) P = P(1:10,:); q = q(1:7,:); Q = Q(1:8,:); ve = ve(1:2,:); elseif (preparation == 10 | preparation == 13) P = P([1:9 11],:); else P = P(1:9,1:tics); q = q(1:6,1:tics); Q = Q(1:7,1:tics); ve = ve(1:2,1:tics); ap = ap(:,1:tics); t = t(1:tics); end