ECGPUWAVE 1.3.4
(69,577 bytes)
C ======================================================================
C punts.f =
C SUBROUTINES QUE ENS TROBEN TOTS ELS PUNTS SIGNIFICATIUS DEL =
C ECG A PARTIR DE LES POSICIONS DELS QRS I DEL SENYAL FILTRAT I DERIVAT=
c Eudald Bogatell (1-6-91)
c David Vigo Anglada ( 9-92)
C Last modified: 24-2-2006 (by G. Moody, to avoid compiler warnings)
C ======================================================================
C -----------------------------------------------------------------------
C Copyright (C) 2002 Pablo Laguna
C
C This program is free software; you can redistribute it and/or modify it
C under the terms of the GNU General Public License as published by the
C Free Software Foundation; either version 2 of the License, or (at your
C option) any later version.
C
C This program is distributed in the hope that it will be useful, but
C WITHOUT ANY WARRANTY; without even the implied warranty of
C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
C General Public License for more details.
C
C You should have received a copy of the GNU General Public License along
C with this program; if not, write to the Free Software Foundation, Inc.,
C 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
C
C You may contact the author by e-mail (laguna@posta.unizar.es) or postal
C mail (Dpt. Ingenieria Electrónica y Comunicaciones, Grupo de Tecnología
C de las Comunicaciones (GTC), Centro Politécnico Superior. Universidad
C de Zaragoza, María de Luna, 3 (Pol. Actur), Edificio A, Despacho 3.16,
C 50015 Zaragoza. Spain). For updates to this software, please visit
C PhysioNet (http://www.physionet.org/).
C _______________________________________________________________________
subroutine p_significatius(dbuf,jqrs,iqrs,if,is,ns,f,ipbeg,
& ippos1, ipend, iqbeg, iqpos, ispos, isend, itbeg,
& itpos, itend, irpos, ecgpb, derfi, irrpos, iqend,isbeg,
& rrmed, ecg, deri, itpos2, morf, idis, nep)
c Aquesta subrutina es cridada desde ECGMAIN com una opcio, i ens
c troba tots els punts significatius de les ones Q,S,T, i P.
dimension dbuf(100000),irpos(8000),ecgpb(100000),iqrs(8000)
dimension ipbeg(8000),ippos1(8000),ippos2(8000),ipend(8000),iqbeg(8000)
dimension iqpos(8000),ispos(8000),isend(8000), itbeg(8000),itpos(8000)
dimension itend(8000), derfi(100000), deri(100000), basel(8000)
dimension irrpos(8000), iqend(8000), isbeg(8000), ecg(100000)
dimension itpos2(8000), morf(5,8000), idis(3,20),eauxs(100000)
dimension ecg_off(100000)
logical comp_qs, eonaq, eonas
c isf: mostra final a tractar
c dbuf: vector que conti el senyal filtrat i derivat
c ecgpb: senyal ECG filtrat a passa banda
c ecg: senyal ECG
c deri: senyal ECG derivat
c derfi: senyal dbuf filtrat
c jqrs: nombre de qrs detectats i confirmats que tractarem
c samp: interval de mostreig en ms
c iqrs: posicio dels complexes QRS detectats i confirmats
c irpos: vector que conti la posicio de l'ona R
c ipbeg, ippos, ipend: inici, pic i final de l'ona P
c iqbeg, iqpos, iqend: inici, pic i final de l'ona Q
c isbeg, ispos, isend: inici, pic i final de l'ona S
c itbeg, itpos, itpos2, itend: inici, pics i final de l'ona T
c basel: conte les linies de base de cada QRS
c idis: conte els posibles episodis de VT i VF
c nep: nombre d'episodis de VT i VF
c comp_qs: es certa si es detecta un complexe QS
c eonaq: es certa si es detecta ona Q
c eonas: es certa si es detecta ona S
kr=5
c per definir el principi i final de l'ona R
isf=(is+ns)*if
samp=1000.0/if
c inicialitzem rrmed
rrmed=(iqrs(jqrs)-iqrs(1))/(jqrs-1)
n=1
do i=1,300
iqbeg(i)=0
iqpos(i)=0
iqend(i)=0
irpos(i)=0
irrpos(i)=0
isbeg(i)=0
ispos(i)=0
isend(i)=0
ipbeg(i)=0
ippos1(i)=0
ipend(i)=0
itbeg(i)=0
itpos(i)=0
itpos2(i)=0
itend(i)=0
end do
c Apliquem un filtre passa baix de 2 grau a la derivada per tal de
c eliminar les components de alta frequencia i determinar millor
c les ones P i T.
c write(6,*) n, 'antes de los filtros pb'
call fpb(isf, if, 40, ecgpb, eauxs, retard)
c call fpb(isf, if, 40, ecg_off, eauxs, retard)
c retard=2*retard
call normaliz_i(if,10,daux,eauxs)
call der(isf, if, eauxs,derfi)
call normaliz_i(if, 2, df_rmax, derfi)
c write(6,*) if, df_rmax, derfi(1),derfi(100000)
jep=1
c QRS que estem tractant
do while(n.le.jqrs.and.isf-iqrs(n).gt.500/samp)
c afegim una proteccio en el cas de que el iqrs(n) sigui igual a
c cero; cas que es pot donar provenint de la subrutina multideriv,
c en les derivacions que s'hi ha detectat un fals negatiu.
if (iqrs(n).ne.0) then
c si el qrs cau dins dun episodi de VT o VF no hi busquem cap complexe
c QRS
if (nep.gt.0.and.iqrs(n).ge.(idis(1,jep)+is)*if-if*0.3.and.
& jep.le.nep) then
if (iqrs(n).le.(idis(2,jep)+is)*if) then
irpos(n)=iqrs(n)
go to 100
else
jep=jep+1
end if
end if
c write(6,*) n, 'antes de onar'
call onar(dbuf, ecgpb, iqrs, irpos, irrpos, iqbeg,iqpos,
& ispos, isend, iqend, isbeg, n, samp, ecg,comp_qs,ymaxaux)
c write(6,*) n, 'despues de onar'
c busquem el pic anterior i posterior a la posicio de la ona R
call busca_pic2(irpos(n), dbuf, ima, 'i')
ymax=dbuf(ima)
call busca_pic2(irpos(n), dbuf, imi, 'd')
ymin=dbuf(imi)
c protegim per R amples on la derivada ti molts pics pero que la r
c sigui significativa
if (.not.comp_qs) then
if (ymax.gt.ymaxaux/4) then
inicia=irpos(n)-nint(70/samp)
if (inicia.lt.0) inicia=0
call buscamaxmin(inicia,irpos(n),
& dbuf, iaux, yaux, imaa, ymaxa)
ilim=irpos(n)+nint(70/samp)
call buscamaxmin(irpos(n),ilim,dbuf, imia, ymina, iaux, yaux)
if (ymaxa.gt.ymax) then
ymax=ymaxa
ima=imaa
end if
if (ymina.lt.ymin) then
c write(6,*) n, iqrs(n),irpos(n), ima,'primero'
ymin=ymina
imi=imia
end if
end if
if (abs(ymax).gt.abs(ymin)) then
dermax=abs(ymax)
else
dermax=abs(ymin)
end if
c i encara afegim unaltra proteccio si no tenim una Q o S molt marcada
c es a dir amb un pic de la derivada gran.
ilim=ima-nint(70/samp)
ilim2=ima-nint(30/samp)
if (ymax.gt.ymaxaux/4) then
call buscamaxmin(ilim,ilim2,dbuf, iaux, yaux, imaa, ymaxa)
if (ymaxa.gt.dermax/5) then
c write(6,*) n, iqrs(n),irpos(n), ima,'ultimo'
ymax=ymaxa
ima=imaa
end if
ilim=imi+nint(40/samp)
ilim2=imi+nint(100/samp)
call buscamaxmin(ilim,ilim2,dbuf, imia, ymina, iaux, yaux)
if (ymina.lt.-1*dermax/5) then
ymin=ymina
imi=imia
end if
end if
c write(6,*) n, iqrs(n),irpos(n), ima
else
c tractem els complexes QS
inicia=irpos(n)-nint(150/samp)
if (inicia.lt.0) inicia=0
call buscamaxmin(inicia,irpos(n),
& dbuf,imi, ymin ,iaux, yaux)
ilim=irpos(n)+nint(180/samp)
call buscamaxmin(irpos(n),ilim,dbuf, iaux, yaux, ima, ymax)
c write(6,2) imin,imax
c 2 format('posicion QS=',i4,'isend=',i4 )
if (abs(ymax).gt.abs(ymin)) then
dermax=abs(ymax)
else
dermax=abs(ymin)
end if
c busquem el principi del QS amb el umbral de la derivada
umbral=ymin/Kr
call creuar_umbral (dbuf, umbral, imi, iqbeg(n), 'i')
c comprobem que el complexe QS no comengi amb un petit pic de pujada.
c si fos aixi no l'hauriem detectat i l'inici trobat fora dolent
c perque no el tenia amb compte. L'umbral ser` a Kr=3 i no 5 perque
c is un petit pic ara.
ilim=iqbeg(n)-nint(35/samp)
call buscamaxmin(ilim,
& iqbeg(n),dbuf,iaux,yaux,ima2,ymax2)
c write(6,*) ymax2, dermax
if (ymax2.ge.dermax/30) then
imi=ima2
umbral=ymax2/2
call creuar_umbral (dbuf, umbral, imi, iumb2, 'i')
if (iumb2.gt.iqbeg(n)-30/samp) iqbeg(n)=iumb2
end if
if (-yaux.ge.dermax/30.and.iaux.lt.ima2) then
imi=iaux
umbral=yaux/2
call creuar_umbral (dbuf, umbral, imi, iumb2, 'i')
if (iumb2.gt.iqbeg(n)-50/samp) iqbeg(n)=iumb2
end if
c Buscamos el final del complejo QS
c write(6,*) n, ' QS'
umbral=ymax/kr
call creuar_umbral (dbuf, umbral, ima, isend(n), 'd')
ilim=irpos(n)+nint(180/samp)
if (isend(n)-iqbeg(n).lt.80/samp) then
call buscamaxmin(irpos(n),ilim,
& dbuf,iaux,yaux,ima2,ymax2)
if (ymax2.gt.ymax) then
umbral=ymax2/kr
call creuar_umbral (dbuf, umbral, ima2, isend(n), 'd')
end if
end if
c Ajuste para picos a la derecha de un QS
ilim=isend(n)+nint(20/samp)
call buscamaxmin(isend(n),ilim,dbuf,imin2,ymin2,iaux,yaux)
c write(6,*) ymax2, dermax
if (-ymin2.ge.dermax/20) then
umbral=ymin2/2
call creuar_umbral (dbuf, umbral, imin2, iumb2,'d')
if (iumb2.lt.isend(n)+30/samp) isend(n)=iumb2
end if
c write(6,2) irpos(n),isend(n)
c 2 format('posicion QS=',i4,'isend=',i4 )
end if
eonaq=.true.
eonas=.true.
c write(6,*) n, 'antes de onaq'
if (irrpos(n).ne.0.or.comp_qs) then
go to 40
end if
20 call onaq (dbuf, dermax, ima, irpos, n, iqbeg, iqpos,
& iqend, samp, ecg, deri, eonaq, itend,iqrs)
c write(6,*) n, 'antes de onas'
30 call onas (dbuf, dermax, imi, irpos, n, isend, ispos,
& isbeg, samp, ecg, iqbeg, deri, eonas,iqrs)
c write(6,*) n, 'antes de onap'
40 call onap (n, derfi, isf, irpos, iqbeg, ipbeg, ippos1,
& ipend, samp, if, dermax, itend, ecgpb, ecg,iqrs)
c write(6,*) n, 'despues de onap'
call cal_base(n,ippos,ecg,basel,samp,ipend,iqbeg)
c trobem el final de la Q i el principi de la S en el creuament de
c la linea de base.
if (iqpos(n).ne.0.and..not.comp_qs.and.irrpos(n).eq.0) then
if (ecg(irpos(n)).gt.0) then
call creuar_umbral (ecg, basel(n), iqpos(n), iqend(n), 'd')
else
iqend(n)=irpos(n)
end if
c si hem anat mes enlla de irpos no existeix la ona Q
if ((irpos(n)-iqend(n).lt.0).and.
& (iqrs(n).gt.iqpos(n)+10/samp) ) then
iqbeg(n)=0
iqpos(n)=0
iqend(n)=0
eonaq=.false.
go to 20
end if
end if
if (ispos(n).ne.0.and..not.comp_qs.and.irrpos(n).eq.0) then
if (ecg(irpos(n)).gt.0) then
call creuar_umbral (ecg, basel(n), ispos(n), isbeg(n), 'i')
else
isbeg(n)=irpos(n)
end if
c si hem anat mes enlla de irpos no existeix la ona S
if ( (irpos(n)-isbeg(n).gt.0).and.
& (iqrs(n).lt.ispos(n)-10/samp) ) then
isbeg(n)=0
ispos(n)=0
isend(n)=0
eonas=.false.
go to 30
end if
end if
call calcula_rmedio(rrmed, n, samp, iqrs)
c write(6,*) n, 'antes de onat'
call onat (n, derfi, rrmed, isf, irpos, iqbeg, itbeg, itpos,
& itpos2,itend, samp, if, isend, ecg, basel, morf,iqrs)
c call onatold (n, derfi, rrmed, isf, irpos, iqbeg, itbeg, itpos,
c & itend, samp, if, isend,iqrs)
if (irpos(n).ne.0) then
if(comp_qs) then
call test_pic (ecg, irpos(n), samp, 'v')
else
call test_pic (ecg, irpos(n), samp, 'p')
end if
end if
end if
100 n=n+1
end do
c omplim el reste dels vectors a cero
do i=jqrs+1,300
irpos(i)=0
ipbeg(i)=0
ippos1(i)=0
ippos2(i)=0
ipend(i)=0
iqbeg(i)=0
iqpos(i)=0
iqend(i)=0
isbeg(i)=0
ispos(i)=0
isend(i)=0
itbeg(i)=0
itpos(i)=0
itend(i)=0
irrpos(n)=0
end do
c a continuacio tenim unes ordres que permeten escriure en uns fitxers
c les mostres que es desitgin de tots els senyals de cara a treure'n
return
end
c-----------------------------------------------------------------------------
subroutine buscamaxmin (ib, ie, date, imi, ymin, ima, ymax)
c Ens treu per min i max els minim i maxim valors del senyal date
c entre les posicions ib i ie. Les posicions del min i del max ens
c les treu per imi i ima respectivament.
dimension date(100000)
ima=ib
imi=ib
ymax=date(ib)
ymin=date(ib)
i=ib
do while (i.lt.ie)
if (date(i).ge.ymax) then
ymax=date(i)
ima=i
end if
if (date(i).le.ymin) then
ymin=date(i)
imi=i
end if
i=i+2
end do
if (date(imi-1).lt.ymin) then
ymin=date(imi-1)
imi=imi-1
end if
if (date(imi+1).lt.ymin) then
ymin=date(imi+1)
imi=imi+1
end if
if (date(ima-1).gt.ymax) then
ymax=date(ima-1)
ima=ima-1
end if
if (date(ima+1).gt.ymax) then
ymax=date(ima+1)
ima=ima+1
end if
return
end
c-------------------------------------------------------------------------
subroutine creuar_umbral (seny, umbral, inici, iumb, sentit)
c Ens treu per iumb la posicio del senyal 'seny' quan aquest
c es inferior, en modul, al valor umbral, sempre buscan en un sentit
c dreta 'd' o esquerra 'i', a partir d'una posicio inicial inici
dimension seny(100000)
character*1 sentit
iumb=inici
if (sentit.eq.'d') then
if(seny(inici).gt.umbral) then
do while (seny(iumb).gt.umbral)
iumb=iumb+1
end do
if (abs(seny(iumb-1)-umbral).lt.abs(seny(iumb)-umbral))
& iumb=iumb-1
else
do while (seny(iumb).lt.umbral)
iumb=iumb+1
end do
if (abs(seny(iumb-1)-umbral).lt.abs(seny(iumb)-umbral))
& iumb=iumb-1
end if
else
if(seny(inici).gt.umbral) then
do while (seny(iumb).gt.umbral)
iumb=iumb-1
end do
if (abs(seny(iumb+1)-umbral).lt.abs(seny(iumb)-umbral))
& iumb=iumb+1
else
do while (seny(iumb).lt.umbral)
iumb=iumb-1
end do
if (abs(seny(iumb+1)-umbral).lt.abs(seny(iumb)-umbral))
& iumb=iumb+1
end if
end if
return
end
c------------------------------------------------------------------------------
subroutine busca_pic2 (inici, seny, ipic, sentit)
c Ens treu per ipic la posicio del primer maxim o minim relatiu
c del senyal, trobat en sentit (d , i ), a partir de la posicio inici
c Evita picos d euna sola muestra
dimension seny(100000)
character*1 sentit
if (sentit.eq.'d') then
ipic=inici+1
do while ((seny(ipic).lt.seny(ipic+1).or.
& seny(ipic).lt.seny(ipic+2)).and.
& (seny(ipic).gt.seny(ipic-1).or.
& seny(ipic).gt.seny(ipic-2)).or.
& (seny(ipic).gt.seny(ipic+1).or.
& seny(ipic).gt.seny(ipic+2)).and.
& (seny(ipic).lt.seny(ipic-1).or.
& seny(ipic).lt.seny(ipic-2)))
ipic=ipic+1
end do
else
ipic=inici-1
do while ((seny(ipic).lt.seny(ipic+1).or.
& seny(ipic).lt.seny(ipic+2)).and.
& (seny(ipic).gt.seny(ipic-1).or.
& seny(ipic).gt.seny(ipic-2)).or.
& (seny(ipic).gt.seny(ipic+1).or.
& seny(ipic).gt.seny(ipic+2)).and.
& (seny(ipic).lt.seny(ipic-1).or.
& seny(ipic).lt.seny(ipic-2)))
ipic=ipic-1
end do
end if
return
end
c------------------------------------------------------------------------------
subroutine busca_pic1 (inici, seny, ipic, sentit)
c Ens treu per ipic la posicio del primer maxim o minim relatiu
c del senyal, trobat en sentit (d , i ), a partir de la posicio inici
dimension seny(100000)
character*1 sentit
if (sentit.eq.'d') then
ipic=inici+1
do while (seny(ipic).lt.seny(ipic+1).and.
& seny(ipic).gt.seny(ipic-1).or.
& seny(ipic).gt.seny(ipic+1).and.
& seny(ipic).lt.seny(ipic-1))
ipic=ipic+1
end do
else
ipic=inici-1
do while (seny(ipic).lt.seny(ipic+1).and.
& seny(ipic).gt.seny(ipic-1).or.
& seny(ipic).gt.seny(ipic+1).and.
& seny(ipic).lt.seny(ipic-1))
ipic=ipic-1
end do
end if
return
end
c------------------------------------------------------------------------------
subroutine onar(dbuf, ecgpb, iqrs, irpos, irrpos, iqbeg,iqpos,
& ispos, isend, iqend, isbeg, n, samp, ecg, comp_qs,ymaxaux)
c Ens troba la posicio de la ona R en cas de que la deteccio del
c complex QRS correspongui a una ona Q o S per ser aquestes anormalment
c grans.
c Tambe ens distingeix els complexos RSR'
dimension dbuf(100000), irpos(8000), iqrs(8000), ecgpb(100000)
dimension irrpos(8000), iqbeg(8000), isend(8000), ecg(100000)
dimension iqpos(8000), ispos(8000), iqend(8000), isbeg(8000)
logical comp_qs
c iqrs(n): posicio del QRS del qual buscarem la ona R
c irpos(n): posicio de la ona R del impuls que estem tractant
comp_qs=.false.
c Busquem els pics a dreta i esquerra de la posicio iqrs en dbuf
call busca_pic2(iqrs(n), dbuf, mpicd, 'd')
call busca_pic2(iqrs(n), dbuf, mpici, 'i')
c si el senyal en iqrs es menor que cero, o el pic de la derivada
c a l'esquerra es > 0 i el pic de la derivada a la dreta es < 0,
c sent al mateix temps l'un molt mes gran que l'altre,
c llavors estem en els casos on iqrs no correspon a la R
ydbufi=dbuf(mpici)
ydbufd=dbuf(mpicd)
if(abs(ydbufi).gt.abs(ydbufd)) then
ymaxaux=abs(ydbufi)
else
ymaxaux=abs(ydbufd)
end if
kpi=2
if (ecgpb(iqrs(n)).lt.0.or.ydbufi.gt.0.and.ydbufd.lt.0.and.
& (kpi*ydbufi.lt.-1*ydbufd.or.kpi*(-1)*ydbufd.lt.ydbufi)) then
perc=0.25
if (ecgpb(iqrs(n)).gt.0.and.ydbufi.gt.0.and.ydbufd.lt.0
& .or.(1+perc)*(-1)*ydbufi.gt.ydbufd.and.
& (1-perc)*(-1)*ydbufi.lt.ydbufd) then
c estem en el cas RSR'
c write(6,*) n, 'RsR'
perc=0.35
kr=5
krr=5
if (ecgpb(iqrs(n)).lt.0) then
c iqrs correspon a la ona s, llavors la R' estara a la dreta i la R
c a la esquerra
ncero=mpicd
call detectar_cero(dbuf, ncero, 'd')
c mirem que el pendent de despres de R' sigui mes gran que un umbral
call busca_pic2(ncero, dbuf, mpda, 'd')
if (-1*dbuf(mpda).lt.ydbufd/2) go to 5
irrpos(n)=ncero
ispos(n)=iqrs(n)
ncero=mpici
call detectar_cero(dbuf, ncero, 'i')
c mirem que el pendent de antes de R sea mes gran que un umbral
call busca_pic2(ncero, dbuf, mpda, 'i')
c write(6,*) dbuf(mpda), mpda, ydbufi
if (dbuf(mpda).lt.-ydbufi/2) go to 5
irpos(n)=ncero
else if (abs(ydbufi).lt.abs(ydbufd)) then
c iqrs correspon a la ona R
ncero=mpicd
call detectar_cero(dbuf, ncero, 'd')
c afegim una nova condicio verificadora
call busca_pic2(ncero, dbuf, mpic, 'd')
if (.not.((1+perc)*abs(ydbufd).gt.abs(dbuf(mpic)).and.
& (1-perc)*abs(ydbufd).lt.abs(dbuf(mpic)))) goto 10
ispos(n)=ncero
call detectar_cero(dbuf, ncero, 'd')
irrpos(n)=ncero
irpos(n)=iqrs(n)
else if (abs(ydbufi).gt.abs(ydbufd)) then
c iqrs correspon a la ona R'
ncero=mpici
call detectar_cero(dbuf, ncero, 'i')
c afegim una nova condicio verificadora
call busca_pic2(ncero, dbuf, mpic, 'i')
if (.not.((1+perc)*abs(ydbufi).gt.abs(dbuf(mpic)).and.
& (1-perc)*abs(ydbufi).lt.abs(dbuf(mpic)))) goto 10
ispos(n)=ncero
call detectar_cero(dbuf, ncero, 'i')
irpos(n)=ncero
irrpos(n)=iqrs(n)
end if
c afegim una verificacio sobre les distancies R-R'
if (abs(irpos(n)-irrpos(n)).gt.150/samp) then
if (ecgpb(iqrs(n)).gt.0) then
goto 10
else
goto 5
end if
end if
c associem l'inici del RSR' a iqbeg i el final a isend, segons el
c criteri de la derivada
call busca_pic2(irrpos(n), dbuf, mpicd, 'd')
call busca_pic2(irpos(n), dbuf, mpici, 'i')
c fem un ajust dels pics del complexe QRS
if (irrpos(n).ne.0) then
call test_pic (ecg, irrpos(n), samp, 'p')
end if
if (ispos(n).ne.0) then
call test_pic (ecg, ispos(n), samp, 'v')
end if
if (irpos(n).ne.0) then
call test_pic (ecg, irpos(n), samp, 'p')
end if
umbral=dbuf(mpicd)/krr
call creuar_umbral(dbuf, umbral, mpicd, isend(n), 'd')
umbral=ecg(isend(n))
call creuar_umbral(ecg, umbral, irrpos(n), isbeg(n), 'i')
umbral=dbuf(mpici)/kr
call creuar_umbral(dbuf, umbral, mpici, iqbeg(n), 'i')
umbral=ecg(iqbeg(n))
call creuar_umbral(ecg, umbral, irpos(n), iqend(n), 'd')
iqpos(n)=0
else
c estem en el cas de Q o S anormalment grans, llavors
5 irrpos(n)=0
c el pendent mes gran es el associat a la ona R, i,que tinguem
c presencia aprop de ona R per tant
c busquem les dos posibles posicions de la ona R
nrted=mpicd
call detectar_cero(dbuf, nrted, 'd')
nrtei=mpici
call detectar_cero(dbuf, nrtei, 'i')
prr=1.4
c write(6,*) n,iqrs(n),nrtei,nrted,dbuf(mpici),dbuf(mpicd)
if (abs(dbuf(mpicd)).gt.prr*abs(dbuf(mpici)).or.
& iqrs(n)-nrtei.gt.nrted-iqrs(n)) then
c tenim ona Q en la posicio iqrs(n), i la ona R estara en el primer
c cero a la dreta
ncero=mpicd
call detectar_cero(dbuf, ncero, 'd')
c mirem que el pendent de despres de R sigui mes gran que un umbral
call busca_pic2(ncero, dbuf, mpda, 'd')
c si la distancia entre ones es massa gran potser no existeix ona R
c saltem a les sentencies de ona S per verificar-ho.
c write(6,*) n, iqrs(n), ncero, mpda,dbuf(mpda),ydbufd
if(ncero-iqrs(n).gt.150/samp.or.-1*dbuf(mpda).lt.ydbufd/10)
& then
go to 7
else
irpos(n)=ncero
end if
else
c tenim ona S en la posicio iqrs(n), i la ona R estara en el primer
c cero a l'esquerra
7 ncero=mpici
call detectar_cero(dbuf, ncero, 'i')
c mirem que el pendent de despres de R' sigui mes gran que un umbral
ilim=ncero-nint(60/samp)
call buscamaxmin(ilim,ncero,dbuf,iau,yau,imax2,ymax2)
c si la distancia entre ones es massa gran, o be el pic buscat mpdi
c no supera l'umbral , no existeix ona R, associem
c irpos a iqrs, despres no es detectara ona S, pero sabrem que ho es
c per l'amplitut negativa.
c write(6,*) n,ymax2, ydbufi,ecgpb(ncero),ecgpb(iqrs(n))
if ( (iqrs(n)-ncero.gt.140/samp.or.ymax2.lt.-1*ydbufi/10)
& .or.(ecgpb(ncero).lt.-abs(ecgpb(iqrs(n))*1/6)) ) then
irpos(n)=iqrs(n)
comp_qs =.true.
else
irpos(n)=ncero
end if
end if
end if
else
c La posicio iqrs correspon a la R, sent el QRS normal
10 irpos(n)=iqrs(n)
irrpos(n)=0
end if
return
end
c------------------------------------------------------------------------------
subroutine onaq(dbuf, dermax, ima, irpos, n, iqbeg, iqpos,
& iqend, samp, ecg , deri, eonaq, itend,iqrs)
c Ens treu per iqpos i iqbeg la posicio i l'inici de la ona Q, en cas
c de no existir ens treu la poisicio =0 i inici de la ona R.
dimension dbuf(100000), irpos(8000), iqbeg(8000), iqpos(8000), iqend(8000)
dimension ecg(100000), deri(100000), itend(100000),iqrs(8000)
logical eonaq
c eonaq: ens diu si existeix la ona Q
c irpos(n): posicio de la ona R del impuls que estem tractant
c kq, kr: constants per definir els umbrals de les derivades per
c les ones Q i R respectivament
c dermax: derivada maxima del QRS
c ima: posicio del maxim anterior a la ona R en el senyal derivat
c
kq=2
kr=5
inte=nint(10/samp)
c eonaq=.true.
c busquem el cero previ a la posicio de la ona R partint del pic,
c que en principi correspondra a la posicio de la ona Q.
ncero=ima+1
nceau=ima
c busquem el cero en la derivada del ecg sense filtrar per tal de
c partir de la posicio correcta per buscar el pic posterior
call detectar_cero (deri, ncero, 'i')
call detectar_cero (dbuf, nceau, 'i')
c write(6,*) n, ncero, nceau, 'll'
c si la distancia entre ones es superior a 60 ms , no existeix ona Q
if (irpos(n) - ncero.gt.80/samp.and.irpos(n).le.iqrs(n))
& eonaq=.false.
c si tenim ona Q, busquem el pendent maxim anterior
if (eonaq) then
call busca_pic2 (nceau, dbuf, mpic, 'i')
c posem una proteccio per casos en que la derivada cuasi creua el 0.
call busca_pic2 (ima, dbuf, icep, 'i')
c si el pic es gran, i no tenim un cuasi creuament de cero,
c treballarem amb dbuf
if(abs(dbuf(mpic)).gt.dermax/12.and..not.(icep.gt.mpic.and.
& abs(dbuf(icep)).lt.dermax/50)) then
c probem de detectar be quan la ona P esta unida a la Q sense cap
c inflexio
if (irpos(n) - mpic.gt.90/samp.or.nceau-mpic.gt.30/samp
& .and.irpos(n).le.iqrs(n)) eonaq=.false.
c busquem el inici amb el umbral de la derivada o be amb el primer
c pic a l'esquerra
c umbral=dbuf(mpic)/kq
umbral=dbuf(mpic)/1.8
call creuar_umbral(dbuf, umbral, mpic, iumb, 'i')
call busca_pic1 (mpic, dbuf, ipic, 'i')
c write(6,*) n,irpos(n),nceau,mpic,iumb,ipic,dbuf(ipic),dbuf(mpic)
if(ipic.gt.iumb) iumb=ipic
c if (dbuf(ipic).gt.abs(dbuf(mpic)*0.8)) go to 10
c si la distancia es superior a 80 ms, no existeix ona Q
c write(6,*) n, mpic, dbuf(mpic), irpos(n), dermax
if (irpos(n)-iumb.gt.120/samp) eonaq=.false.
c comprobem que el complexe Q no comengi amb un petit pic de pujada.
c si fos aixi no l'hauriem detectat i l'inici trobat fora dolent
c perque no el tenia amb compte. L'umbral ser` a Kr=3 i no 5 perque
c is un petit pic ara.
ilimp=nint(30/samp)
call buscamaxmin(iumb-ilimp,
& iumb,dbuf,imin2,ymin2,imax2,ymax2)
c write(6,*) iumb,imax2,ymax2, imin2,ymin2,dermax
if (abs(ymin2).ge.dermax/20) then
umbral=ymin2/1.8
call creuar_umbral (dbuf, umbral, imin2, iumb2, 'i')
if (iumb2.gt.iumb-40/samp) iumb=iumb2
end if
c write(6,*) iumb, iumb2
if ((imax2.lt.imin2.or.abs(ymin2).lt.dermax/20)
& .and.abs(ymax2).gt.dermax/20) then
umbral=ymax2/1.8
call creuar_umbral (dbuf, umbral, imax2, iumb2, 'i')
if (iumb2.gt.iumb-40/samp) iumb=iumb2
end if
else
10 kq=3
c per tal de detectar ones Q de component frequencial molt elevat
c fem servir la derivada del ecg sense filtrar.
c busquem el pic corresponent a deri.
call busca_pic2 (ncero, deri, mpic, 'i')
call test_pic (deri, mpic, samp, 'v')
c si el pendent maxim de la ona Q es << que el pendent maxim llavors
c no existeix ona Q
if (abs(deri(mpic)).lt.dermax/10
& .or.ncero-mpic.gt.30/samp) eonaq=.false.
c si existeix la ona Q busquem el seu principi amb el umbral de la
c derivada
if (eonaq) then
umbral=deri(mpic)/kq
umbral=deri(mpic)/2.8
call creuar_umbral(deri, umbral, mpic, iumb, 'i')
c si la distancia es superior a 80 ms, no existeix ona Q
if (irpos(n)-iumb.gt.80/samp) eonaq=.false.
end if
end if
end if
c si no existeix la ona Q busquem el principi de la ona R amb el
c umbral de la derivada
if (.not.eonaq) then
c write(6,*) n,ima, dbuf(ima)
if (dbuf(ima).ge.1.5) kr=8
if (dbuf(ima).ge.3) kr=18
if (dbuf(ima).ge.4.0) kr=28
umbral=dbuf(ima)/kr
kr=5
call creuar_umbral (dbuf, umbral, ima, iumb, 'i')
c asegurem-nos que la ona R no comenga amb un petit pic :
ib=iumb-abs(30.0/samp)
call buscamaxmin(ib,iumb,dbuf,iaux,yaux,ima2,ymax2)
if (ymax2.ge.dermax/50) then
ima=ima2
umbral=ymax2/1.5
call creuar_umbral (dbuf, umbral, ima, iumb2, 'i')
if (iumb2.gt.iumb-36/samp) iumb=iumb2
end if
c write(6,*) n, ima, dbuf(ima), iumb,iumb2,ima2,ymax2
end if
c omplim els vectors de sortida
if (eonaq) then
iqpos(n)=ncero
else
iqpos(n)=0
end if
iqbeg(n)=iumb
c write(6,*) n, iqpos(n),iqbeg(n) , 'ippb'
if (n.gt.1.and.iqbeg(n).le.itend(n-1)) iqbeg(n)=itend(n-1)+1
if (iqpos(n).ne.0) then
call test_pic (ecg, iqpos(n), samp, 'v')
end if
c busquem el final de la ona Q
c if (eonaq) then
c umbral=ecg(iumb)
c call creuar_umbral(ecg, umbral, iqpos(n), iqend(n), 'd')
c else
c iqend(n)=0
c end if
return
end
c---------------------------------------------------------------------------
subroutine onas(dbuf, dermax, imi, irpos, n, isend, ispos,
& isbeg, samp, ecg, iqbeg, deri, eonas,iqrs)
c Ens treu per ispos i isend la posicio i el final de la ona S, en cas
c de no existir ens treu la poisicio igual a 0 i el final de la ona R.
dimension dbuf(100000), irpos(8000), isend(8000), ispos(8000), isbeg(8000)
dimension derfi(100000), ecg(100000),iqbeg(8000), deri(100000), iqrs(8000)
logical eonas
c eonas: ens diu si existeix la ona S
c irpos(n): posicio de la ona R del impuls que estem tractant
c ks, kr: constants per definir els umbrals de les derivades per
c les ones S i R respectivament
c dermax: derivada maxima del QRS
c imi: posicio del maxim posterior a la ona R en el senyal derivat
c busquem el cero posterior a la posicio de la ona R partint del minim,
c que en principi correspondra a la posicio de la ona S.
ks=3
kr=5
inte=nint(10/samp)
c eonas=.true.
ncero=imi
nceau=imi
c busquem el cero en la derivada del ecg sense filtrar per tal de
c partir de la posicio correcta per buscar el pic posterior
call detectar_cero (deri, ncero, 'd')
call detectar_cero (dbuf, nceau, 'd')
c si la distancia entre ones es superior a 130 ms , no existeix ona S
if ((ncero-irpos(n).gt.130/samp).and.
& irpos(n).ge.iqrs(n)) eonas=.false.
if ((nceau.lt.iqrs(n)).and.(ecg(iqrs(n)).lt.0)) then
ncero=iqrs(n)
nceau=iqrs(n)
end if
c si tenim ona S, busquem el pendent maxim posterior
if (eonas.eqv..true.) then
c en comptes de buscar el primer pic a la dreta busquem el maxim
c en un interval pero amb un valor mes restringiu per si tenim
c bloqueig de branca dreta
if (ispos(n).eq.iqrs(n)) then
ilim=nint(nceau+140./samp)
else
ilim=nint(nceau+80./samp)
end if
call buscamaxmin (nceau,ilim , dbuf, iau, yau,mpic, ypic)
c write(6,*) n, nceau, mpic
if (ypic.lt.dermax/10) call busca_pic2 (nceau, dbuf, mpic, 'd')
c posem una proteccio per casos en que la derivada cuasi creua el 0.
call busca_pic2 (imi, dbuf, icep, 'd')
c si el pic es gran, i no tenim un cuasi creuament de cero,
c treballarem amb dbuf
if( dbuf(mpic).gt.dermax/30.and.(.not.(icep.lt.mpic.and.
& abs(dbuf(icep)).lt.dermax/50).or.(iqrs(n).eq.ncero)) ) then
c posem ks en funcis de la pendent
if (dbuf(mpic).ge.4.) ks=8
if (dbuf(mpic).ge.4.75) ks=9
if (dbuf(mpic).ge.6.2) ks=10
c write(6,*) n, dbuf(mpic)
umbral=dbuf(mpic)/ks
ks=3
call creuar_umbral(dbuf, umbral, mpic, iumb, 'd')
call busca_pic1 (nint(mpic+10/samp), dbuf, ipic, 'd')
if(ipic.lt.iumb.and.dbuf(ipic).lt.dermax/15) iumb=ipic
c write(6,1) n, ncero, iqrs(n), iumb
c 1 format('c=',i4,'ncero=',i4,'iqrs(n)=',i4,'iu=',i4)
c si la distancia es superior a 200 ms, no existeix ona S
if (iumb-irpos(n).gt.200/samp) then
umbral=dbuf(mpic)/kr
call creuar_umbral(dbuf, umbral, mpic, iumb, 'd')
call busca_pic1 (nint(mpic+10/samp), dbuf, ipic, 'd')
if(ipic.lt.iumb.and.dbuf(ipic).lt.dermax/3) iumb=ipic
end if
c write(6,2) iumb-irpos(n)
c 2 format('QRS=',i4 )
else
call busca_pic2 (ncero, deri, mpic, 'd')
c si el pendent maxim de la ona S es << que el pendent maxim llavors
c no existeix ona S
c per tal de detectar ones S de component frequencial molt elevat
c fem servir la derivada del ecg sense filtrar.
c busquem el pic corresponent a deri.
ks=3
call test_pic (deri, mpic, samp, 'p')
if (abs(deri(mpic)).lt.dermax/10.and.irpos(n).ge.iqrs(n))
& eonas=.false.
c si existeix la ona S busquem el seu final amb el umbral de la
c derivada, o be, amb el primer pic a la dreta
if (eonas) then
umbral=deri(mpic)/ks
call creuar_umbral(deri, umbral, mpic, iumb, 'd')
call busca_pic1 (nint(mpic+10/samp), dbuf, ipic, 'd')
if (ipic.lt.iumb) iumb=ipic
c si la distancia es superior a 80 ms, no existeix ona S
if (iumb-irpos(n).gt.200/samp) then
umbral=dbuf(mpic)/kr
call creuar_umbral(dbuf, umbral, mpic, iumb, 'd')
call busca_pic1 (nint(mpic+10/samp), dbuf, ipic, 'd')
if(ipic.lt.iumb.and.dbuf(ipic).lt.dermax/3) iumb=ipic
end if
end if
end if
if ((iumb-irpos(n).gt.200/samp).and.
& irpos(n).ge.iqrs(n)) eonas=.false.
end if
c si no existeix la ona S busquem el final de la ona R amb el
c umbral de la derivada o be amb el primer pic a la dreta
if (.not.eonas) then
umbral=dbuf(imi)/kr
call creuar_umbral (dbuf, umbral, imi, iumb, 'd')
call busca_pic2(nint(imi+10/samp), dbuf, ipic, 'd')
if(ipic.lt.iumb) iumb=ipic
end if
c omplim els vectors de sortida
if (eonas) then
ispos(n)=ncero
else
ispos(n)=0
end if
isend(n)=iumb
if (isend(n).lt.iqrs(n)) isend(n)=iqrs(n)+1
if (ispos(n).ne.0) then
call test_pic (ecg, ispos(n), samp, 'v')
end if
c busquem l'inici de la ona S
c if (eonas) then
c umbral=ecg(iumb)
c call creuar_umbral(ecg, umbral, ispos(n), isbeg(n), 'i')
c else
c isbeg(n)=0
c end if
return
end
c--------------------------------------------------------------------------
subroutine onat (n, dbuf, rrmed, isf, irpos, iqbeg, itbeg, itpos,
& itpos2,itend, samp, if, isend, ecg, basel, morf,iqrs)
c ens localitza els punts inicial, pics i final de la ona T. Tambe ens
C treu la morfologia de l'ona T pel vector morf segons el codi:
c
c morf(4,j) -ona T 0: existeix, normal
c 1: " , invertida
c 2: " , nomes pujada
c 3: " , nomes baixada
c 4: bifasica -+
c 5: " +-
c 6: no existeix
dimension dbuf(100000), irpos(8000), iqbeg(8000), itbeg(8000),itpos(8000)
dimension itend(8000), isend(8000), ecg(100000),back(6)
dimension morf(5,8000), basel(8000), itpos2(8000), iqrs(8000)
logical flag1, inici_t, fivec
c flag1: variable de control de bucle
c inici_t: ens diu si podem buscar el inici de la ona (T normal o
c invertda)
c bwind, ewind: amplada de la finestra
c ibw: posicio a partir de la que comengarem a buscar
c iew: posicio fins la que buscarem
c ktb, kte: constants per definir els umbrals de la derivada per
c localitzar l'inici i final de la ona T respectivament
c pco=valor de comparacio entre els pics
pco=8.0
ktb=2
kdis=nint(50/samp)
c Limite hasta donde se permitira ir al fin de la T
if (rrmed.gt.900/samp) then
itqlim=nint(280/samp)
ewind=800
else if (rrmed.gt.800/samp) then
itqlim=nint(250/samp)
ewind=600
else if (rrmed.gt.600/samp) then
itqlim=nint(200/samp)
ewind=450
else
itqlim=nint(170/samp)
ewind=450
end if
c write(6,*) itqlim
c factor de aumento de los umbrales si la primera vez va muy lejos
do i=1,6
back(i)=1.0
end do
bwind=100
ibw=irpos(n)+nint(bwind/samp)
iew=irpos(n)+nint(ewind/samp)
flag1=.true.
inici_t=.true.
c inicialitzem finestres
if (n.gt.1) then
call inifinestres(rrmed, isf, irpos(n), bwind, ewind,
& ibw, iew, samp, fivec)
end if
c posem un reajust per QRS molt amples i per intervals rr anormalment
c petits.
if(ibw.le.isend(n)+kdis) then
iew=iew+isend(n)-ibw+kdis
ibw=isend(n)+kdis
end if
if (iqrs(n+1).gt.0.and.iew.gt.iqrs(n+1)-210/samp)
& iew=iqrs(n+1)-nint(210/samp)
if (iqrs(n+1).eq.0) iew=irpos(n)+nint(400/samp)
if (fivec) return
c write(6,5) n, (iqrs(n+1)-iew)*samp
c 5 format('beat=',i4,' distancia iwe QRS', f6)
c posem una altre condicio per detectar be T de pujada o baixada
call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
if (ymin.gt.0.or.ymax.lt.0) then
if (iew.eq.iqrs(n+1)-210/samp) then
if (ymin.gt.0) ymin=0
if (ymax.lt.0) ymax=0
else
do while (ymin.gt.0.or.ymax.lt.0.and.iqrs(n+1).gt.0.and.
& iew.lt.iqrs(n+1)-250/samp)
iew=iew+nint(25/samp)
call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
end do
end if
end if
c inicialitzem morf al valor de no existencia per si no es pot clasificar
c dintre de cap dels patrons
morf(4,n)=6
do while (flag1.and.iew.gt.ibw)
c si el maxim i el minim tenen valors semblants busquem els pics
c anteriors i posteriors segons cada cas
kint1=nint(250/samp)
kint2=nint(300/samp)
c kend= valor en ms de marge minim a partir de isend on buscarem pics
kend=50
c ampmi= valor minim de les amplituts de les ones T bifasiques
ampmi=0.075
c kk es el nivel de comparacion para determinar ondas bifasicas
kk=3
com=0.3
c write(6,*) n,imi, ymin, ima, ymax, ibw, iew, iqrs(n+1)
if (-com*ymin.lt.ymax.and.-ymin.gt.com*ymax) then
c write(6,2) n
c 2 format('beat=',i4,' with max and min comparables')
if (imi.lt.ima) then
call buscamaxmin(ibw, imi, dbuf, iau, yau, imaa, ymaxa)
call buscamaxmin(ima, iew, dbuf, imip, yminp, iau, yau)
c si algun dels dos pics novament trobats es petit, no el considerem
c com part de la ona T, o be si els dos a la vegada son grans
if (ymaxa.lt.ymax/kk.and.-yminp.lt.-ymin/kk.or.
& ymaxa.ge.ymax/kk.and.-yminp.ge.-ymin/kk) then
morf(4,n)=1
c write(6,*) 'invertida primera opcion'
c write(6,*) n, imi,ima,ymin,ymax
c write(6,*) n, ymaxa, ymin,ymax,yminp
else if(ymaxa.ge.ymax/kk) then
go to 200
c mirem si estem en el cas de ona bifasica
c ncea=imaa
c call detectar_cero(dbuf, ncea, 'd')
c if (ecg(ncea)-basel(n).lt.ampmi) then
c morf(4,n)=1
c else
c tenim ona t bifasica +-
c imap=ima
c ymaxp=ymax
c morf(4,n)=5
c end if
else if(-yminp.ge.-ymin/kk) then
go to 200
c mirem si estem en el cas de ona bifasica
c ncep=imip
c call detectar_cero(dbuf, ncep, 'i')
c if (ecg(ncep)-basel(n).lt.ampmi) then
c morf(4,n)=1
c else
c tenim ona t bifasica -+
c imia=imi
c ymina=ymin
c morf(4,n)=4
c end if
end if
else
c estem en el cas de minim posterior al maxim
c if (ima-kint1.gt.isend(n)+kend/samp) then
c inici=ima-kint1
c else
c inici=isend(n)+nint(kend/samp)
c end if
c if (inici.gt.ima) inici=ima
c if (imi+kint2.gt.iew) kint2=iew-imi
call buscamaxmin(imi, iew, dbuf, iau, yau, imap, ymaxp)
call buscamaxmin(ibw, ima, dbuf, imia, ymina, iau, yau)
c si algun dels dos pics novament trobats es petit, no el considerem
c com part de la ona T, o be si els dos a la vegada son grans
c write(6,*) n,n,imia,ymina,ima,ymax,imi,ymin,imap,ymaxp
if (ymaxp.lt.ymax/kk.and.-ymina.lt.-ymin/kk.or.
& ymaxp.ge.ymax/kk.and.-ymina.ge.-ymin/kk) then
morf(4,n)=0
else if(ymaxp.ge.ymax/kk) then
c mirem si estem en el cas de ona bifasica
go to 200
c ncep=imap
c call detectar_cero(dbuf, ncep, 'i')
c if (basel(n)-ecg(ncep).lt.ampmi) then
c morf(4,n)=0
c else
c tenim ona t bifasica +-
c imaa=ima
c ymaxa=ymax
c morf(4,n)=5
c end if
else if(-ymina.ge.-ymin/kk) then
c mirem si estem en el cas de ona bifasica
go to 200
c ncea=imia
c call detectar_cero(dbuf, ncea, 'd')
c if (basel(n)-ecg(ncea).lt.ampmi) then
c morf(4,n)=0
c else
c tenim ona t bifasica -+
c imip=imi
c yminp=ymin
c morf(4,n)=4
c end if
end if
end if
else
c estem en el cas de pics diferents
c sino, si el maxim es mes gran que el minim busquem els dos minims
c anteriors i posteriors
200 continue
if (ymax.gt.-1*ymin) then
c if (ima-kint1.gt.isend(n)+kend/samp) then
c inici=ima-kint1
c else
c inici=isend(n)+nint(kend/samp)
c end if
c if (inici.gt.ima) inici=ima
call buscamaxmin(ibw, ima, dbuf, imia, ymina, iau, yau)
c if (ima+kint2.gt.iew) kint2=iew-ima
call buscamaxmin(ima,iew,dbuf,imip,yminp, iau, yau)
ncea=imia
if (ymina.lt.0) call detectar_cero(dbuf, ncea, 'd')
ampa=basel(n)-ecg(ncea)
ncep=imip
if (yminp.lt.0) call detectar_cero(dbuf, ncep, 'i')
ampp=ecg(ncep)-basel(n)
c si la primera amplitud es gran podem tenir T de pujada, bifasica -+ o
c invertida
c write(6,*) n, ampa, ampp, imia,ymina,imip,yminp
if (ampa+ampp.gt.ampmi) then
if (-ymina.lt.ymax/pco.and.-yminp.lt.ymax/pco) then
c tenim ona T de nomes pujada
morf(4,n)=2
else if (-ymina.ge.ymax/pco.and.-yminp.ge.ymax/pco) then
c tenim ona T bifasica -+
morf(4,n)=4
else if (-ymina.ge.ymax/pco.and.-yminp.lt.ymax/pco) then
c tenim ona T invertida
c write(6,*) 'invertida segunda opcion'
morf(4,n)=1
ymin=ymina
imi=imia
c write(6,*) imi,ima,ymin,ymax
else if (-ymina.lt.ymax/pco.and.-yminp.ge.ymax/pco) then
c tenim ona T normal
morf(4,n)=0
ymin=yminp
imi=imip
end if
end if
else if (ymax.lt.-1*ymin) then
c if (imi-kint1.gt.isend(n)+kend/samp) then
c inici=imi-kint1
c else
c inici=isend(n)+nint(kend/samp)
c end if
c if (inici.gt.imi) inici=imi
call buscamaxmin(ibw, imi, dbuf, iau, yau, imaa, ymaxa)
c if (imi+kint2.gt.iew) kint2=iew-imi
call buscamaxmin(imi, iew,dbuf,iau,yau,imap,ymaxp)
ncea=imaa
if (ymaxa.gt.0) call detectar_cero(dbuf, ncea, 'd')
ampa=ecg(ncea)-basel(n)
ncep=imap
if (ymaxp.gt.0) call detectar_cero(dbuf, ncep, 'i')
ampp=basel(n)-ecg(ncep)
c si la primera amplitut es gran podem tenir ona T de baixada, normal
c o be bifasica +-
c write(6,*) n,imaa,ymaxa,imi,ymin,imap,ymaxp,ampa,ampp
if (ampa+ampp.gt.ampmi) then
if (ymaxa.lt.-ymin/pco.and.ymaxp.lt.-ymin/pco) then
c tenim ona T de nomes baixada
c write(6,*) n, 'bajada'
morf(4,n)=3
else if (ymaxa.ge.-ymin/pco.and.ymaxp.ge.-ymin/pco) then
c tenim ona T bifasica +-
c write(6,*) n, 'bifasica'
morf(4,n)=5
else if (ymaxa.ge.-ymin/pco.and.ymaxp.lt.-ymin/pco) then
c tenim ona T normal
c write(6,*) n, 'normal'
morf(4,n)=0
ymax=ymaxa
ima=imaa
else if (ymaxa.lt.-ymin/pco.and.ymaxp.ge.-ymin/pco) then
c tenim ona T invertida
morf(4,n)=1
ymax=ymaxp
ima=imap
c write(6,*) imi,ima,ymin,ymax
end if
end if
end if
end if
c procedim a buscar pics, inicis i finals segons cada cas
300 go to (10, 20, 30, 40, 50, 60, 70), morf(4,n)+1
c tenim ona T normal
10 umba=ymax/ktb
call creuar_umbral (dbuf, umba, ima, iumba, 'i')
c si hem anat mes enrera de isend, trobem el principi de la T
c amb un criteri del primer pic a l'esquerra
if (iumba.lt.isend(n)) call busca_pic2(ima, dbuf, iumba, 'e')
c si encara hem anat massa enrera l'associem a isend
if (iumba.le.isend(n)) iumba=isend(n)+2
itbeg(n)=iumba
C kte valdr` 4,5,6,7 en funcis del valor de la derivada max.
if (abs(ymin).ge.0.41) then
kte=7
else if (abs(ymin).ge.0.35) then
kte=6
else if (abs(ymin).ge.0.25) then
kte=5
else if (abs(ymin).ge.0.10) then
kte=4
else if (abs(ymin).lt.0.10) then
kte=3.5
end if
if (kte/back(1).ge.1.1) then
umbp=ymin*back(1)/kte
else
umbp=ymin/1.1
end if
call creuar_umbral (dbuf, umbp, imi, iumbp, 'd')
itend(n)=iumbp
icero1=imi
call detectar_cero (dbuf, icero1, 'i')
icero2=ima
call detectar_cero (dbuf, icero2, 'd')
if (icero1.ne.icero2) then
icero=(icero1+icero2)/2
else
icero=icero1
end if
if (icero.ge.itend(n).or.icero.le.itbeg(n))
& icero=itbeg(n)+(itend(n)-itbeg(n))/2
itpos(n)=icero
itpos2(n)=icero
go to 100
c tenim ona T invertida
20 umba=ymin/ktb
call creuar_umbral (dbuf, umba, imi, iumba, 'i')
c si hem anat mes enrera de isend, trobem el principi de la T
c amb un criteri del primer pic a l'esquerra
if (iumba.lt.isend(n)) call busca_pic2(imi, dbuf, iumba, 'e')
c si encara hem anat massa enrera l'associem a isend
if (iumba.le.isend(n)) iumba=isend(n)+2
itbeg(n)=iumba
C kte valdr` 4,5,6,7 en fuincis del valor de la derivada max.
if (abs(ymax).ge.0.41) then
kte=7
else if (abs(ymax).ge.0.35) then
kte=6
else if (abs(ymax).ge.0.25) then
kte=5
else if (abs(ymax).ge.0.10) then
kte=4
else if (abs(ymax).lt.0.10) then
kte=3.5
end if
if (kte/back(2).gt.1.1) then
umbp=ymax*back(2)/kte
else
umbp=ymax/1.1
end if
call creuar_umbral (dbuf, umbp, ima, iumbp, 'd')
itend(n)=iumbp
c write(6,*) n, imi, ima, iumbp, itbeg(n), itend(n),ymax,umbp,kte
icero1=ima
call detectar_cero (dbuf, icero1, 'i')
icero2=imi
call detectar_cero (dbuf, icero2, 'd')
if (icero1.ne.icero2) then
icero=(icero1+icero2)/2
else
icero=icero1
end if
if (icero.ge.itend(n).or.icero.le.itbeg(n))
& icero=itbeg(n)+(itend(n)-itbeg(n))/2
c write(6,1) icero1, icero2, icero
c 1 format('icero1=',i4, ' icero1=',i4,' icero1=',i4)
itpos(n)=icero
itpos2(n)=icero
go to 100
c tenim ona T de nomes pujada
30 continue
C kte valdr` 4,5,6,7 en fuincis del valor de la derivada max.
if (ymax.ge.0.41) then
kte=7
else if (ymax.ge.0.30) then
kte=6
else if (ymax.ge.0.20) then
kte=5
else if (ymax.gt.0.10) then
kte=4
else if (ymax.le.0.10) then
kte=3.5
end if
if (kte/back(3).ge.1.1) then
umbp=ymax*back(3)/kte
else
umbp=ymax/1.1
end if
call creuar_umbral (dbuf, umbp, ima, iumbp, 'd')
itend(n)=iumbp
icero=ima
call detectar_cero (dbuf, icero, 'i')
call busca_pic2(ima-kdis, dbuf, ipic, 'i')
if (ipic.gt.icero) then
itpos(n)=ipic
else
itpos(n)=icero
end if
if (itpos(n).le.isend(n)) itpos(n)=isend(n)+1
itpos2(n)=0
itbeg(n)=0
go to 100
c tenim ona T de nomes baixada
40 continue
C kte valdr` 4,5,6,7 en funcis del valor de la derivada max.
if (abs(ymin).ge.0.41) then
kte=7
else if (abs(ymin).ge.0.30) then
kte=6
else if (abs(ymin).ge.0.20) then
kte=5
else if (abs(ymin).ge.0.10) then
kte=4
else if (abs(ymin).lt.0.10) then
kte=3.5
end if
if (kte/back(4).ge.1.1) then
umbp=ymin*back(4)/kte
else
umbp=ymin/1.1
end if
call creuar_umbral (dbuf, umbp, imi, iumbp, 'd')
itend(n)=iumbp
icero=imi
call detectar_cero (dbuf, icero, 'i')
call busca_pic2(imi-kdis, dbuf, ipic, 'i')
if (ipic.gt.icero) then
itpos2(n)=ipic
else
itpos2(n)=icero
end if
if (itpos2(n).le.isend(n)) itpos2(n)=isend(n)+1
itpos(n)=0
itbeg(n)=0
go to 100
c tenim ona T bifasica -+
50 umba=ymina/ktb
call creuar_umbral(dbuf, umba, imia, iumba, 'i')
if (iumba.lt.isend(n)) call busca_pic2(imia, dbuf, iumba, 'e')
c si encara hem anat massa enrera l'associem a isend
if (iumba.le.isend(n)) iumba=isend(n)+2
itbeg(n)=iumba
C kte valdr` 4,5,6,7 en funcis del valor de la derivada max.
if (abs(yminp).ge.0.41) then
kte=7
else if (abs(yminp).ge.0.30) then
kte=6
else if (abs(yminp).ge.0.20) then
kte=5
else if (abs(yminp).ge.0.10) then
kte=4
else if (abs(yminp).lt.0.10) then
kte=3.5
end if
if (kte/back(5).ge.1.1) then
umbp=yminp*back(5)/kte
else
umbp=yminp/1.1
end if
call creuar_umbral(dbuf, umbp, imip, iumbp, 'd')
itend(n)=iumbp
icero=imia
call detectar_cero (dbuf, icero, 'd')
itpos2(n)=icero
icero=imip
call detectar_cero (dbuf, icero, 'i')
itpos(n)=icero
if (itpos(n).lt.itpos2(n)) itpos(n)=itpos2(n)
go to 100
c tenim ona T bifasica +-
60 umba=ymaxa/ktb
call creuar_umbral(dbuf, umba, imaa, iumba, 'i')
if (iumba.lt.isend(n)) call busca_pic2(imaa, dbuf, iumba, 'e')
c si encara hem anat massa enrera l'associem a isend
if (iumba.le.isend(n)) iumba=isend(n)+2
itbeg(n)=iumba
C kte valdr` 4,5,6,7 en funcis del valor de la derivada max.
if (abs(ymaxp).ge.0.41) then
kte=7
else if (abs(ymaxp).ge.0.30) then
kte=6
else if (abs(ymaxp).ge.0.20) then
kte=5
else if (abs(ymaxp).ge.0.10) then
kte=4
else if (abs(ymaxp).lt.0.10) then
kte=3.5
end if
if (kte/back(6).ge.1.1) then
umbp=ymaxp*back(6)/kte
else
umbp=ymaxp/1.1
end if
call creuar_umbral(dbuf, umbp, imap, iumbp, 'd')
itend(n)=iumbp
icero=imaa
call detectar_cero (dbuf, icero, 'd')
itpos2(n)=icero
icero=imap
call detectar_cero (dbuf, icero, 'i')
itpos(n)=icero
if (itpos(n).lt.itpos2(n)) itpos(n)=itpos2(n)
go to 100
c no tenim ona t
70 itbeg(n)=0
itpos(n)=0
itpos2(n)=0
itend(n)=0
go to 100
c apliquem una regla de validesa respecte el interval QT
c 100 write(6,3) n, itend(n)-iqbeg(n), 750/samp
c 3 format('beat=',i2,' QT=', i4, ' QT limite=', f4)
100 if (itend(n).ge.isf) go to 70
c write(6,*)n, 'isf=', isf, itend(n)
if (itend(n)-iqbeg(n).lt.950/samp.and.
& (iqrs(n+1)-itend(n).gt.itqlim.or.iqrs(n+1).eq.0.or.
& itend(n)-iqbeg(n).lt.400/samp) ) then
flag1=.false.
else
if (iew.gt.ibw+100/samp) then
iew=iew-nint(50/samp)
else
iew=iew-nint(25/samp)
end if
call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
back(morf(4,n)+1)=back(morf(4,n)+1)*1.8
end if
c write(6,*) n,itend(n), iqrs(n+1),itend(n)-iqbeg(n)
end do
if (itend(n).gt.iqrs(n+1)-100/samp.and.iqrs(n+1).ne.0) then
itend(n)=0
itpos(n)=0
itbeg(n)=0
itpos2(n)=0
end if
return
end
c------------------------------------------------------------------------------
subroutine onatold (n, dbuf, rrmed, isf, irpos, iqbeg, itbeg, itpos,
& itend, samp, if, isend,iqrs)
c subrutina vella on no esta implementat la posiblitat de ones T
c bifasiques.
c ens localitza els punts inicial, pic i final de la ona T
dimension dbuf(100000), irpos(8000), iqbeg(8000), itbeg(8000),itpos(8000)
dimension itend(8000), isend(8000),iqrs(8000)
logical flag1, inici_t, fivec
c flag1: variable de control de bucle
c inici_t: ens diu si podem buscar el inici de la ona (T normal o
c invertda)
c bwind, ewind: amplada de la finestra
c ibw: posicio a partir de la que comengarem a buscar
c iew: posicio fins la que buscarem
c ktb, kte: constants per definir els umbrals de la derivada per
c localitzar l'inici i final de la ona T respectivament
ktb=3
kte=2
kdis=nint(20/samp)
bwind=100
ewind=450
ibw=irpos(n)+nint(bwind/samp)
iew=irpos(n)+nint(ewind/samp)
c filtrem passa-baix la derivada del senyal compresa entre les finestres
c call filtre_pb (ibw, iew-ibw, if, 30, dbuf,retard)
flag1=.true.
inici_t=.true.
c inicialitzem finestres
call inifinestres(rrmed, isf, irpos(n), bwind, ewind, ibw, iew,
& samp, fivec)
c posem un reajust per QRS molt amples i per intervals rr anormalment
c petits.
if(ibw.le.isend(n)+kdis) then
iew=iew+isend(n)-ibw+kdis
ibw=isend(n)+kdis
end if
if (iqrs(n+1).gt.0.and.iew.gt.iqrs(n+1)-100/samp)
& iew=iqrs(n+1)-100/samp
if (fivec) return
c posem una altre condicio per detectar be T de pujada o baixada
call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
if (ymin.gt.0.or.ymax.lt.0) then
do while (ymin.gt.0.or.ymax.lt.0)
iew=iew+25/samp
call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
end do
iew=iew+100/samp
end if
if (iqrs(n+1).gt.0.and.iew.gt.iqrs(n+1)-100/samp)
& iew=iqrs(n+1)-100/samp
do while (flag1.and.iew.gt.ibw)
ieaux=nint(iew-50/samp)
call buscamaxmin (ibw, ieaux, dbuf, imi, ymin, ima, ymax)
imig=imi
yming=ymin
if (imi.lt.ima)
& call buscamaxmin (ima, iew, dbuf, imi, ymin, iaux1, aux2)
c regla de decisio per clasificar la ona T com a normal, invertida,
c depujada o de baixada
if (imi.ne.imig.and.ymin.gt.0.or.
& abs(ymin).lt.ymax/3.or.
& abs(yming)/4.gt.ymax.and.abs(yming)/4.gt.abs(ymin)) then
if (abs(yming).gt.3*ymax.or.ima.gt.iew-50/samp) then
c tenim ona T de nomes baixada
imi=imig
ymin=yming
inici_t=.false.
else
c tenim ona T invertida o be de pujada
if (imi.eq.imig.and.ymax.gt.3*abs(ymin)) then
c tenim ona t de nomes pujada
ymin=ymax
imi=ima
inici_t=.false.
else
c tenim ona T invertida
imi=ima
ymin=ymax
ima=imig
ymax=yming
end if
end if
end if
c altrament tenim ona T normal
icero=imi
c busquem el cero anterior al que en cada cas correspongui a la posicio
c imi, i que en principi sera el pic de la ona T
call detectar_cero (dbuf, icero, 'i')
c si hem anat mes enrera de isend associem el pic a la primera vall
c a la esquerra
if (icero.lt.isend(n)) call busca_pic2(imi, dbuf,icero, 'e')
c buquem el final de la ona T definint un umbral de la derivada
umbral=ymin/kte
call creuar_umbral (dbuf, umbral, imi, iumb, 'd')
c apliquem una regla de validesa respecte el interval QT
if (iumb-iqbeg(n).lt.620/samp) then
flag1=.false.
itpos(n)=icero
itend(n)=iumb
else
iew=iew-50/samp
end if
end do
itpos(n)=icero
c busquem el inici de la ona T mitjangant un umbral
if(inici_t) then
umbral=ymax/ktb
call creuar_umbral(dbuf, umbral, ima, iumb, 'i')
c si hem anat mes enrera de isend, trobem el principi de la T
c amb un criteri del primer pic a l'esquerra
if (iumb.lt.isend(n)) call busca_pic2(ima, dbuf, iumb, 'e')
c si encara hem anat massa enrera l'associem a isend
if (iumb.lt.isend(n)) iumb=isend(n)
itbeg(n)=iumb
else
itbeg(n)=0
endif
return
end
c------------------------------------------------------------------------------
subroutine inifinestres (rrmed, isf, irp, bwind, ewind, ibw,
& iew,samp, fivec)
c inicialitza les finestres a on es buscara l'ona T.
logical fivec
fivec=.false.
if (irp+ewind/samp.lt.isf)then
if (rrmed.lt.750/samp) then
c ibw=nint(100/samp)+irp
ibw=nint(125/samp)+irp
iew=nint(rrmed*0.6)+irp
else
ibw=nint(bwind/samp)+irp
iew=nint(ewind/samp)+irp
end if
else
if (irp+bwind/samp.lt.isf) then
ibw=nint(bwind/samp)+irp
iew=isf
else
fivec=.true.
endif
end if
return
end
c ---------------------------------------------------------------------------
subroutine filtre_pb (ni,n,if,ifc,x,retard)
dimension x(100000),y(400)
c APLICA A LA SEQAL QUE ENTRA EN EL VECTOR x UN FILTRO PASO BAJO. lA
C SEQAL QUE ENTRA LA SUPONGO MUESTREADA A if hZ.
C EL FILTRO TIENE UN POLO DOBLE EN (0,1) Y ifc CEROS DOBLES EN
C EL CIRCULO UNIDAD .LA GANANCIA DEL
C FILTRO SERIA DEl NUMERO de CEROS AL CUADRADO.
C EL RETARDO DEL FILTRO ES DE NUMERO de CEROS MENOS UNO
C LAS CONDICIONES INICIALES SUPONGO QUE LA SEQAL ES CONSTANTE ANTES DEL
C INSTANTE INICIAL CON VALOR 0
C lA ECUACION SERIA Y(nT)=2Y(nT-T)-Y(nT-2T)+X(nT)-2X(nT-cerosT)
c +X(nT-2*cerosT).
C lA SEQAL FILTRADA LA DEVUELVE EN EL VECTOR y
C RM ES EL VALOR MEDIO DE LOS 10 PRIMEROS PUNTOS
c sum=x(ni)
c do i=ni+2,ni+10
c sum=sum+x(i)
c end do
rm=x(ni)
c l ES EL NUMERO DE CEROS
C ifc ES LA FRECUENCIA A LA QUE EL FILTRO CAE A CERO
C if ES LA FRECUENCIA A LA QUE ESTA MUESTREADA LA SEQAL
C ni ES LA POSICION INICIAL A PARTIR DE LA CUAL QUIERO FILTRAR
c n ES EL NUMERO DE PUNTOS A FILTRAR
C SE DEBE CUMPLIR (n<1000-l) SI NO SE SALDRA DE LOS LIMITES DEL VECTOR
l=nint(1.*if/ifc)
y(1)=x(ni+1)+(l**2-1)*rm
y(2)=(2*y(1)+x(ni+2)-(l**2+1)*rm)
do i=3,l
y(i)=(2*y(i-1)-y(i-2)+x(ni+i)-rm)
end do
do i=l+1,2*l
y(i)=(2*y(i-1)-y(i-2)+x(ni+i)-2*x(ni+i-l)+rm)
end do
do i=2*l+1,n+l
y(i)=(2*y(i-1)-y(i-2)+x(ni+i)-2*x(ni+i-l)+x(ni+i-2*l))
end do
C QUITO EL RETARDO DE LA SEQAL
retard=l
if (n.le.(400-l+1)) then
do i=1,n
x(ni+i)=y(i+l)
end do
else
do i=1,400-l+1
x(ni+i)=y(i+l)
end do
c do i=400-l+1,n
c y(i)=0
c end do
end if
C PONGO EL RESTO A CERO
do i=n+1,400
y(i)=0
end do
return
end
C ---------------------------------------------------------------
subroutine onap (n, dbuf, isf, irpos, iqbeg, ipbeg, ippos1,
& ipend, samp, if, dermax, itend, ecgpb,ecg,iqrs)
c Aquesta subroutina ens busca inici i final de la ona P. Considera
c tant ones P normals com invertides.
dimension dbuf(100000), irpos(8000), iqbeg(8000), ipbeg(8000), ipend(8000)
dimension ippos1(8000), ippos2(8000), itend(8000) ,ecgpb(100000)
dimension ecg(100000), iqrs(8000)
logical nofi
c bwind, ewind: amplada de la finestra
c ibw: posicio a partir de la que comengarem a buscar
c iew: posicio fins la que buscarem
c kpb, kpe: constants per definir els umbrals de la derivada per
c localitzar l'inici i final de la ona P respectivament
counter=0
nofi=.true.
kpb=2
kpe=2
bwind=200
c bwind=380
ewind=30
ippos1(n)=0
iew=iqbeg(n)-nint(ewind/samp)
ibw=iqbeg(n)-nint(bwind/samp)
if (ibw.lt.0) ibw=0
if (iew.lt.0) iew=0
do while (nofi.and.ippos1(n).eq.0.and.iqbeg(n)-ibw.lt.300/samp)
c no busquem mes enlla del final de T anterior, i a una distancia minima
c de qbeg (Vigo : he canviat 330 per 400)
if (n.eq.1.or.itend(n-1).eq.0) then
nofi=.false.
else
if (ibw.lt.itend(n-1)) then
ibw=itend(n-1)
nofi=.false.
else
nofi=.true.
end if
end if
kdis=nint(20/samp)
c Estaba cuando los limites se amrcaban desde el QRS
c if(iqbeg(n)-iew.lt.kdis) then
c iew=iqbeg(n)-kdis
c end if
if (iew.lt.0) iew=0
c busquem el maxim i el minim dins la finestra
10 call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
C---------------------------------------------------------------------------
C Aixs is el criteri de l'Audal:
C si les pendents son molt inferiors a les del QRS o be
c si la posicio del minim esmenor que la del maxim, no tenim ona P
c if (imi.le.ima.or.ymax.lt.dermax/50.or.abs(ymin).lt.dermax/50) then
c tambe detectem ones P invertides, pertant nomes si els pendents
c son molt inferiors als del QRS, sent mes exigents en les invertides
c per tal de no detectar-ne de falses.
C---------------------------------------------------------------------------
c Vigo: canvio 70 per 30 per detectar millor ones p molt prrximes a la q
if (imi.le.ima.and.iqbeg(n)-ima.lt.30/samp) then
iew=iqbeg(n)-nint(30/samp)
ibw=ibw-nint(30/samp)
call buscamaxmin (ibw, iew, dbuf, imi, ymin, ima, ymax)
end if
C---------------------------------------------------------------------------
C Aixs is el criteri de l'Audal:
C if (ima.le.imi.and.(ymax.lt.dermax/50.or.abs(ymin).lt.dermax/50)
c &.or.ima.ge.imi.and.(ymax.lt.dermax/25.or.abs(ymin).lt.dermax/25))
c & then
C-------------------------------------------------------------------------
C Ara se'n adopta un altre:
C si la diferencia d'amplituds entre la posicio de R i la del punt de
C maxima amplitud a la finestra on busquem P, es superior a un cert valor
C considerarem que no existeix ona P. Les amplituds ser`n buscades en
C la senyal ecgpb. Primer calculem el punt de m`xima amplitud absoluta en
C la finestra de bzsqueda de P, i despres podrem comparar-la. De fet con-
C siderarem bones aquelles ones P l'amplitud de les quals sigui superior a
C un 7% de la de la ona R, o que tinguin una pendent superior al 1.4% la
C del complexe QRS.
C
base=0
itimes=0
do ii=1, nint(15/samp)
base=base+(ecgpb(iqbeg(n)-ii))
itimes=itimes+1
end do
base=base/itimes
ecgpbmax=0.
do ii=ibw,iew
if (abs(ecgpb(ii)-base).ge.ecgpbmax) then
ecgpbmax=abs(ecgpb(ii)-base)
posmax=ii
end if
end do
c write(6,*) n, ecgpbmax, abs(ecgpb(iqrs(n))), ymax, ymin,dermax
if (ecgpbmax.le.(abs(ecgpb(iqrs(n))-base)/30).or.
& ((ymax.lt.dermax/100.and.abs(ymin).lt.dermax/100).and.
& (ymax.lt.abs(ymin)/1.5.or.ymax.gt.abs(ymin)*1.5)) )then
ippos1(n)=0
ippos2(n)=0
ipbeg(n)=0
ipend(n)=0
else
c definim si es normal o invertida
if (imi.le.ima) then
c tenim ona P invertida
iaux=imi
yaux=ymin
imi=ima
ymin=ymax
ima=iaux
ymax=yaux
end if
c busquem els dos ceros a dreta i esquerra de la posicio del maxim i
c minim respectivament, que correspondran als posibles pics de la ona P
icero1=ima
call detectar_cero (dbuf, icero1, 'd')
icero2=imi
call detectar_cero (dbuf, icero2, 'i')
c si els dos pics disten mes de un cert valor
c if (icero2-icero1.gt.20/samp) then
c considerem que la ona p te dos pics
c ippos1(n)=icero1
c ippos2(n)=icero2
c else
c considerem que el pic esta en el cente dels dos pics
ippos1(n)=nint((icero1+icero2)/2.)
ippos2(n)=0
c end if
c busquem l'inici i final de la ona P segons el criteri del umbral de
c la derivada
c Vigo: fem Kpb=1.65 i ara 1.5 i ara 1.35
umbral=ymax/1.35
c umbral=ymax/kpb
ima2=ima
20 call creuar_umbral (dbuf, umbral, ima2, iumb, 'i')
if ((iqbeg(n)-iumb).ge.240.or.
& (iumb.le.itend(n-1).and.n.gt.1.and.itend(n-1).ne.0)) then
ibw=ibw+20
if (ibw.gt.iew-20/samp) go to 100
call buscamaxmin (ibw,iew,dbuf,imi2,ymin2,ima2,ymax2)
goto 20
end if
call busca_soroll(iumb-40,iumb-5,ecg,soroll)
c D. Vigo: confirmem que l'inici trobat es bo; fem un test comparant
c l'algada del'ona p trobada amb l'algada de soroll, i comprobant
c que l'inici de p no estgui massa aprop del pic de p.
if (abs(ecgpb(iumb)-ecgpb(ippos1(n))).lt.(1.5*soroll).and.
& (ippos1(n)-iumb).lt.40/samp) then
iew2=ima2-nint(15./samp)
if (iew2.gt.itend(n-1).and.iew2.ge.ibw) then
call buscamaxmin (ibw,iew2,dbuf,imi2,ymin2,ima2,ymax2)
if (ymax2.ge.ymax/2) then
go to 20
end if
end if
end if
ipbeg(n)=iumb
umbral=ymin/kpe
call creuar_umbral (dbuf, umbral, imi, iumb, 'd')
c si el umbral es rebassa mes enlla de iqbeg definim el final amb un
c criteri de la derivada minima
if (iumb.ge.iqbeg(n))
& call buscamaxmin(imi,iqbeg(n),dbuf,iumb,ymin,iau,yau)
ipend(n)=iumb
c si encara hem anat massa enll`, fem ipend=iqbeg
if (ipend(n).ge.iqbeg(n)) then
if (counter.eq.0) then
iew=iew-nint(10/samp)
counter=1
c write(6,1) ipend(n), iqbeg(n)
c 1 format('Pend=',i4,' Qbeg=',i4)
go to 10
else
ipend(n)=iqbeg(n)-1
end if
end if
C comprobem que la diferencia d'algades entre pic i final de P sigui
C significativa respecte el soroll calculat
call busca_soroll(ibw,iew,ecg,soroll)
if(abs(ecgpb(ippos1(n))-ecgpb(ipend(n))).le.(1.5*soroll))then
goto 100
end if
c fem una verificacio dels resultats obtinguts per validar la ona P
if (ipbeg(n).ge.ipend(n).or.ippos1(n).le.ipbeg(n)
& .or.ippos1(n).ge.ipend(n).or.ipbeg(n).lt.itend(n-1)
& .or.ipend(n)-ipbeg(n).gt.180/samp) then
c & .or.ipend(n)-ipbeg(n).gt.150/samp) then
go to 100
else
go to 110
end if
end if
100 ippos1(n)=0
ippos2(n)=0
ipbeg(n)=0
ipend(n)=0
110 iew=iew-50./samp
ibw=ibw-50./samp
c eliminem el bucle de buscar la ona P mes enrera si no la trobem a la
c primera finestra
c nofi=.false.
end do
return
end
c----------------------------------------------------------------------------
subroutine calcula_rmedio (rrmed, n, samp, irpos)
c aquesta subrutina calcula el la distancia mitja entre les ones R
c consequtives. Aquells intervals que es desviin molt de la mitja son
c rebutjats
dimension irpos(8000)
perc=0.5
if (n.le.1) then
if (rrmed.eq.0) then
rrmed=irpos(2)-irpos(1)
if (rrmed.gt.1000/samp.or.rrmed.lt.500/samp)
& rrmed=nint(650/samp)
else
return
end if
else
if (n.lt.7) then
if (irpos(n)-irpos(n-1).gt.rrmed*(1-perc).and.
& irpos(n)-irpos(n-1).lt.rrmed*(1+perc)) then
rrmed=rrmed*(n-2)/(n-1)+(irpos(n)-irpos(n-1))/(n-1)
end if
else
if (irpos(n)-irpos(n-1).gt.rrmed*(1-perc).and.
& irpos(n)-irpos(n-1).lt.rrmed*(1+perc)) then
rrmed=rrmed*4/5+(irpos(n)-irpos(n-1))/5
end if
end if
end if
c write(6,1) rrmed
c 1 format('rrmed=',f8)
return
end
c---------------------------------------------------------------------------
subroutine test_pic (seny, lpic, samp, t)
c aquesta subrutina ens fa un test per comprobar si el pic trobat
c amb el criteri de la derivada nula correspon exactament amb el
c pic del senyal 'seny'.
c 't' ens diu si tenim un pic 'p' o una vall 'v'
dimension seny(100000)
character*1 t
kpos=nint(10/samp)
c busquem kpos posicions a dreta i esquerra de lpic
laux=lpic
if (t.eq.'p') then
do i=lpic-kpos, lpic+kpos
if(seny(i).gt.seny(laux)) laux=i
end do
else
do i=lpic-kpos, lpic+kpos
if(seny(i).lt.seny(laux)) laux=i
end do
end if
lpic= laux
return
end
c----------------------------------------------------------------------------
subroutine cal_base(n,ippos,ecg,basel,samp,ipend,iqbeg)
dimension basel(8000),ipend(8000), iqbeg(8000),ippos(8000)
dimension ecg(100000)
c busquem la linea de base com la mitjana dels punts del segment PR
nqui=nint(15./samp)
ntre=nint(30./samp)
ntre_q = nint(10./samp)
nqui_q = nint(5./samp)
if (iqbeg(n).ne.0) then
if (ippos(n).ne.0) then
sum=0.
if (iqbeg(n)-ipend(n).gt.33/samp) then
do k=ipend(n)+nqui, iqbeg(n)-nqui
sum=sum+ecg(k)
end do
baselin=sum/(iqbeg(n)-nqui-nqui-ipend(n)+1)
else
if(iqbeg(n).eq.ipend(n)) then
baselin=ecg(iqbeg(n))
else
do k=ipend(n), iqbeg(n)
sum =sum+ecg(k)
end do
baselin= sum/(iqbeg(n)-ipend(n)+1)
end if
end if
else
sum=0.
if(iqbeg(n)-nqui_q.gt.1) then
k=iqbeg(n)-nqui_q
do while(k.ge.iqbeg(n)-ntre_q-nqui_q.and.k.gt.0)
sum=sum+ecg(k)
k=k-1
end do
if(k.eq.0)then
baselin=sum/(iqbeg(n)-nqui_q)
else
baselin=sum/(ntre_q+1)
end if
else
do k=1,iqbeg(n)
sum=sum+ecg(k)
end do
baselin=sum/iqbeg(n)
end if
end if
basel(n)=baselin
end if
return
end
c --------------------------------------------------------------
subroutine busca_soroll(ibw,iew,ecg,soroll)
dimension ecg(100000)
if (ibw.lt.0) ibw=0
if (iebw.lt.0) iew=0
soroll=0.
inici=ibw
ncont=0
do while (inici.lt.iew)
ncont=ncont+1
ifinal=inici+5
if (ifinal.gt.iew) then
ifinal=iew
end if
call buscamaxmin(inici,ifinal,ecg,imi2,ymin2,ima2,ymax2)
soroll=(ymax2-ymin2)+soroll
inici=ifinal
end do
if (ncont.gt.0) then
soroll=abs(soroll/ncont)
end if
return
end