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