C ================================================== C ALDETQRS (ALGORISME DETECCIO QRS) C AUTOR: PABLO LAGUNA/RAIMON JANE C DATA: 26-MAIG-87 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 _______________________________________________________________________ C SE LE LLAMA DESDE ECGMAIN PARA DETECTAR LOS QRSs. DE LA SENAL DE C DE ECGs. C C ------------------------------------------------------------- C REALIZA UN PRIMER APRENDIZAJE C ------------------------------------------------------------- subroutine apren1(ifm,sen,der,psen,psor,umb1,umb2) c ESTA SUBROUTINA CALCULA LOS PICOS DE SEQAL Y DE RUIDO INICALES c ASI COMO LOS UMBRALES PARA EMPEZAR A TRABAJAR. c ifm eS LA FRECUENCIA A LA QUE ESTA MUESTREADA LA SEQAL c sen eS EL VECTOR EN EL QUE PASO LA SEQAL c der eS EL VECTOR EN EL QUE PASO LA DERIVADA DE LA SEQAL c EN psen, psor SACO LOS PICOS DE SEQAL Y RUIDO INICIALES c EN n PASO EL INDICE QUYE TENGO QUE TOMAR SEGUN sen SEA c ecgpb O ecgmw (1 O 0) c EN umb1,umb2 SACO LOS UMBRALES INICIALES PARA DETECTAR LOS qrs c ipic ES UN VECTOR QUE GUARDA LAS POSICIONES DE LOS MAXIMOS(PICOS) dimension sen(100000),der(100000),ipic(8000) c BUSCO LOS PICOS ENTRE 1 SEGUNDO Y 3 SEGUNDOS i=ifm j=0 do while (i.lt.(3*ifm)) c write(6,*) ' estoy aqui', i , sen(i), sen(i+1), der(i) call detpic(sen,der,i) j=j+1 ipic(j)=i end do c TOMO COMO PICO DE SEQAL EL MAS ALTO DE LOS QUE HAY EN DOS SEGUNDOS psen=sen(ipic(1)) do l=2,j s=sen(ipic(l)) if (s.gt.psen) then psen=s end if end do c TOMO COMO PICO DE RUIDO EL MAS ALTO QUE ESTA POR DEBAJO DEL 75% DEL c DE SEQAL qrs75=0.75*psen c modificado a 0.9 psor=0. do l=1,j s=sen(ipic(l)) if (s.lt.qrs75) then if (s.gt.psor) then psor=s end if end if end do c DEFINO LOS UMBRALES SEGUN ESTA RELACION umb1=psor+0.25*(psen-psor) umb2=umb1/2 32 format(1x,'umb1=',f11.3,'umb1=',f11.3) return end C ------------------------------------------------------------- C REALIZA UN SEGUNDO APRENDIZAJE C ------------------------------------------------------------- subroutine apren2(ifm,sen,der,umb1,irrint) dimension sen(100000),der(100000),iqrs(2) c ESTA SUBROUTINA CALCULA EL INTERVALO rr INICIAL PARA LUEGO SABER c CUANDO VAMOS DEMASIADO LEJOS BUSCANDO, Y PODAMOS VOLVER ATRAS c Se busca fuera del segundo inicial (i=ifm) para evitar transitorios c del filtro i=ifm j=1 irrint=0 do while (irrint.le.(ifm/3)) c BUSCO LOS DOS PRIMEROS qrs do while (j.lt.3) i=i+1 call detpic(sen,der,i) do while (sen(i).le.umb1) i=i+1 call detpic(sen,der,i) end do iqrs(j)=i j=j+1 end do irrint=iqrs(2)-iqrs(1) c SI EL INTERVALO ES MUY CORTO PUEDE QUE SEAN ONDAS p Y NO q c LO TEXTEO CON LA RUTINA pendent QUE ME DA LA PENDIENTE DE c PICO Y TOMO SOLO LA MAYOR if (irrint.le.(ifm/3)) then call pendent(ifm,der,iqrs(2),pemax2) call pendent(ifm,der,iqrs(1),pemax1) if (pemax1.lt.pemax2) then iqrs(1)=iqrs(2) else c TEXTEO QUE NO SEA UNA ONDA r Y LUEGO UNA p if (pemax2.lt.(pemax1/1.5)) then irrint=0 end if end if j=j-1 end if end do if (irrint.gt.ifm*1.1) then irrint=ifm*1.1 end if return end C ------------------------------------------------------------- C REALIZA LA DETECCION DE LOS PICOS C ------------------------------------------------------------- subroutine detect(ifm,isf,sen,der,psen,psor,umb1,umb2,irrint, * j,iqrs) c ESTA SUBROUTINA DETECTA LOS QRS CON LOS DATOS INICIALES DE LAS DE c APRENDIZAJE c j ES EL NUMERO DE qrs Y iqrs ES EL VECTOR DONDE ESTAN LAS c POSICIONES c onat ES UNA VARIABLE LOGICA QUE DICE SI EL PICO DETECTADO PUEDE c SER ONDA t O NO SEGUN A QUE DISTANCIA DEL qrs ANTERIOR ESTE c serbak ES UNA VARIUABLE LOGICA QUE INDICA CUANDO NO HEMOS c ENCONTRADO UN qrs Y POR TANTO HEMOS DE VOLVER ATRAS Y MIRAR CON c UN UMBRAL MAS BAJO. c ionat eS LA POSICION HASTA LA CUAL ES POSIBLE EN CADA MOMENTO c QUE LA ONDA DETECTADA SEA t dimension sen(100000),der(100000),iqrs(8000) logical onat,serbak j=1 ionat=nint(ifm/5.5) c En el QRS primero no comprobara si es onda T ya que no se sabe donde c esta puede aparecer C ionat=0 c irrlim ES EL LIMITE HASTA DONDE BUSCO UN qrs DESDE EL ANTERIOR c SIN VOLVER ATRAS EN LA BUSQUEDA irrlim=nint(1.5*irrint) serbak=.false. C BUSCO EL QRS INICIAL ENTRE 1000 MS. Y 3000 MS. mf=int(ifm*3) penqrs=0 penmax=0 i=ifm do while (i.lt.mf) call detpic(sen,der,i) call pendent(ifm,der,i,pen) if ((pen.gt.(penqrs)).and.(sen(i).gt.(umb1/2))) then c umb1/2 para que coja posibles QRS de menor amplitud que la T penqrs=pen psen=sen(i) end if if (pen.gt.penmax) then penmax=pen end do c Por si entre 1 y 2.5 ms no hay picos mayores que umb1 if (penqrs.eq.0) then penqrs=penmax c REDEFINO LOS PICOS DE SEQAL Y DE RUIDO COMO EL VALOR DEL QRS Y c EL MAYOR PICO POR DEBAJO DEL 75% DE ESTE ASI COMO LOS UMBRALES psor=0.0 mf=2.5*ifm i=ifm do while (i.lt.mf) call detpic(sen,der,i) if ((sen(i).lt.psen*0.75).and.(sen(i).gt.psor)) then psor=sen(i) end if end do umb1=psor+0.25*(psen-psor) umb2=umb1/2 c BUSCO YA TODOS LOS qrs EN EL LIMITE SOLICITADO c iqrs_ant es la posicion del QRS anterior al que busco c inicialmente supongo que esta en 0 para proteger la busqueda del c primer QRS iqrs_ant=0 i=1 do while (i.lt.isf) i=i+1 call detpic(sen,der,i) if (i.gt.isf) then go to 30 end if if ((i-iqrs_ant).gt.irrlim) then c write(6,10) i,j,iqrs(j-1),irrlim,umb1 10 format(1x,'no hi ha qrs',/,1x,'i=',i5,2X,'j=',i4, * ' iqrs=',i5,1x,'irrlim=',i5,'umb1=',f8.4) if (serbak.eqv..true.) then umb1=umb2 umb2=umb2/2 icounter=icounter+1 end if c POR SI LLEGO HA CERO Y NO ENCUENTRO PICO ALARGO EL C INTERVALO DE BUSQUEDA Y PONGO EL UMBRAL ALTO NUEVAM if (umb1.lt.0.2) then irrlim=irrlim*1.1 umb1=psor+0.25*(psen-psor) umb2=umb1/2 end if if ((icounter.gt.3).and.(irrlim.lt.2.5*irrint)) then irrlim=irrlim*1.5 end if i=iqrs(j-1)+ifm/5 serbak=.true. psor=0 call detpic(sen,der,i) c else c serbak=.false. end if picact=sen(i) if (picact.gt.umb1) then onat=.false. if (i.lt.ionat) then call tonat(ifm,der,i,penqrs,onat) end if if (onat.eqv..false.) then call pendent(ifm,der,i,pen) if ((pen.gt.penqrs*0.65.and.pen.lt.1.4*penqrs) * .or.(serbak.eqv..true.)) then penqrs=0.8*penqrs + 0.2*pen c proteccion para picos muy seguidos menos de 200ms. c y posibles ondas P detectadas como QRS k=i do while ((k-i).lt.ifm/5) call detpic(sen,der,k) if ((k.lt.isf).and.(k-i.lt.ifm/5) * .and.(sen(k).gt.sen(i))) then i=k picact=sen(i) end if end do if (serbak.eqv..false.) then psen=0.125*picact+0.875*psen else psen=0.25*picact+0.75*psen end if iqrs(j)=i iqrs_ant=i ionat=i+nint(ifm*0.36) i=i+ifm/5 j=j+1 if (j.gt.2) then call ajustrr(j,iqrs,irrint,irrlim) end if if (psen.le.psor) then psor=psor/2. umb1=psor+0.25*(psen-psor) umb2=umb1/2 c psor=0 serbak=.false. icounter=0 end if end if else if (picact.gt.psor) then psor=picact end if end if end do 30 j=j-1 C LIMPIO EL RESTO DEL VECTOR do i=j+1,8000 iqrs(i)=0 end do return end C ------------------------------------------------------------- C REALIZA UN TEXT SOBRE LOS QRS C ------------------------------------------------------------- subroutine buenos(ipos,num) dimension ipos(8000) c ELIMINO LOS QRS QUE PUEDEN SER DEBIDOS A RUIDO c BUSCO EL INTERVALO MAXIMO DE LOS 10 PRIMEROS nmax=ipos(2)-ipos(1) do i=1,10 if ((ipos(i+1)-ipos(i)).gt.nmax) nmax=ipos(i+1)-ipos(i) end do c COJO LA MEDIA DE LOS INTERVALOS RAZONABLES EN n c ls,li sON LOSLIMITES SUPERIOR E INFERIOR PARA CONSIDERAR RAZONABLE ls=nint(nmax*1.1) li=nint(nmax*0.8) n=0 j=0 do i=1,10 int=ipos(i+1)-ipos(i) if ((int.lt.ls).and.(int.gt.li)) then n=n+int j=j+1 end if end do n=nint(n*1./j) c ME QUEDO SOLO CON LOS QUE ESTAN SEPARADOS DENTRO DE UNOS LIMITES ls=nint(n*1.15) li=nint(n*0.85) j=2 do i=1,num-1 int=ipos(i+1)-ipos(i) if ((int.lt.ls).and.(int.gt.li)) then ipos(j)=ipos(i+1) j=j+1 end if end do C LIMPIO EL VECTOR RESTANTE DE QRSS do i=j,num ipos(i)=0 end do num=j-1 return end C -------------------------------------------------------- C CALCULA LA AMPLITUD DEL PICO C -------------------------------------------------------- subroutine amplitud(sen,ipos,num,ampli) dimension sen(100000),ipos(8000),ampli(8000) do i=1,num ampli(i)=sen(ipos(i)) end do do i=num+1,8000 ampli(i)=0. end do return end C -------------------------------------------------------- C CALCULA LA ANCHURA DEL PICO AL 25% DEL MAXIMO C -------------------------------------------------------- subroutine anchura(sen,ipos,num,anch,ialtura) dimension sen(100000),ipos(8000),anch(8000) do i=1,num li=ipos(i) do while (sen(li).gt.sen(ipos(i))*ialtura/100.) li=li-1 end do lf=ipos(i) do while (sen(lf).gt.sen(ipos(i))*ialtura/100.) lf=lf+1 end do anch(i)=float(lf-li) end do do i=num+1,8000 anch(i)=0. end do return end C ------------------------------------------------------------ C REALIZA UN TEXT SOBRE EL VALOR DE 'TEX' DECADA QRS C ------------------------------------------------------------ subroutine buenvalortex(tex,ipos,num,toles,tolei) dimension ipos(8000),tex(8000) C RECHAZO LOS QRS QUE TENGAN UN VALOR DE TEX ANORMAL POR SI SON C RUIDO if (num.lt.3) return ampli=0. max=tex(1) min=tex(1) if (num.ge.7) then c TOMO LA MEDIA DE LOS 7 PRIMEROS QUE NO SEAN C EL MAS ANCHO NI EL MAS ESTRECHO do i=1,7 ampli=tex(i)+ampli if (tex(i).gt.max) max=tex(i) if (tex(i).lt.min) min=tex(i) end do ampli=(ampli-max-min)/5 C RECHAZO LOS VALORES QUE ESTAN MUY FUERA DE LA MEDIA amplit=ampli * 5 + max + min ica=0 do i=1,7 if (tex(i).gt.ampli*1.5) then amplit=amplit-tex(i) ica=ica+1 end if if (tex(i).lt.ampli*0.5) then amplit=amplit-tex(i) ica=ica+1 end if end do ampli=amplit/(7-ica) else do i=1,num ampli=tex(i)+ampli if (tex(i).gt.max) max=tex(i) if (tex(i).lt.min) min=tex(i) end do if (num.gt.0) ampli=(ampli-max-min)/(num-2) C RECHAZO LOS VALORES QUE ESTAN MUY FUERA DE LA MEDIA amplit=ampli * (num-2) + max + min ica=0 do i=1,num if (tex(i).gt.ampli*1.5) then amplit=amplit-tex(i) ica=ica+1 end if if (tex(i).lt.ampli*0.5) then amplit=amplit-tex(i) ica=ica+1 end if end do ampli=amplit/(num-ica) end if C RLIMS Y RLIMI SON EL LIMITE INFERIOR Y SUPERIOR PARA CONSIDERAR C VALIDO LA ANCHURA, TOLES,TOLEI SON LAS TOLERANCIAS QUE DOY SUPERIOR C E INFERIOR RESPECTIVAMENTE alims=ampli*toles alimi=ampli*tolei j=1 do i=1,num if ((tex(i).lt.alims).and.(tex(i).gt.alimi)) then ipos(j)=ipos(i) tex(j)=tex(i) if (j.gt.5) then ampli=ampli+(tex(j)-tex(j-5))/5 alims=ampli*toles alimi=ampli*tolei end if j=j+1 end if end do j=j-1 C LIMPIO EL VECTOR RESTANTE DE QRSS do i=j+1,num ipos(i)=0 end do num=j return end C ------------------------------------------------------------- C REALIZA UNA COFRONTACION DE LOS QRS C ------------------------------------------------------------- subroutine confqrs(ifm,ecgpb,ecgmw,iqrspb,nqrspb,iqrsmw,nqrsmw, * iqrs,n,ecg) C busca que todos los QRS esten en las dos seqales para afirmar C son tales qrs y no son debidos a ruidos. dimension iqrspb(8000),iqrsmw(8000),iqrs(8000),ecgpb(100000) dimension ecgmw(100000),iqrspb2(8000),iqrsmw2(8000),ampli(8000) dimension anch(8000),ecg(100000) samp=1000./ifm C TOMO iqrspb2,IQRSMW2 IGUALES A LOS QUE ENTRO do i=1,8000 iqrspb2(i)=iqrspb(i) iqrsmw2(i)=iqrsmw(i) end do nqrspb2=nqrspb nqrsmw2=nqrsmw c call buenos(iqrspb2,nqrspb2) c call buenos(iqrsmw2,nqrsmw2) c call amplitud(ecgpb,iqrspb2,nqrspb2,ampli) c call buenvalortex(ampli,iqrspb2,nqrspb2,1.3,0.7) c c call amplitud(ecgmw,iqrsmw2,nqrsmw2,ampli) c call buenvalortex(ampli,iqrsmw2,nqrsmw2,1.3,0.7) c call anchura(ecgmw,iqrsmw2,nqrsmw2,anch,20) c call buenvalortex(anch,iqrsmw2,nqrsmw2,1.15,0.85) c TOMO LOS QRS QUE ESTAN DETECTADOS EN PA Y MW CON EL RETARDO ADECUADO c correccions: agafem com a bons els que o be estiguin en PB o en MW c sempre i quan estiguin a una bona distancia respecte a rrmed l=1 m=1 n=1 pe1=30./100 pe2=50./100 c "perc" es un tant per cent del factor de normalitzacio del senyal c ECGMW perc=1 do while ((m.le.nqrsmw2).or.(l.le.nqrspb2)) call calcula_rmedio ( rrmed, n-1, samp, iqrs) if(m.gt.nqrsmw2) iqrsmw2(m)=100000 if(l.gt.nqrspb2) iqrspb2(l)=100000 idelay=iqrsmw2(m)-iqrspb2(l) if (abs(idelay).le.pe2*rrmed) then ibe=nint(iqrsmw2(m)-0.1*ifm) ien=nint(iqrsmw2(m)+0.1*ifm) call buscamaxmin(ibe,ien,ecgpb,imi,ymin,ima,ymax) c write(6,*) n,imi,ima,iqrsmw2(m),iqrspb2(l),ymax,ymin,idelay if (abs(ymin).gt.abs(ymax)) then iqrs(n)=imi else iqrs(n)=ima end if n=n+1 l=l+1 m=m+1 else if (idelay.lt.-pe2*rrmed) then if (iqrsmw2(m)-iqrs(n-1).gt.(1-pe2)*rrmed.or.n.eq.1) then ibe=nint(iqrsmw2(m)-0.1*ifm) ien=nint(iqrsmw2(m)+0.1*ifm) call buscamaxmin(ibe,ien,ecgpb,imi,ymin,ima,ymax) c write(6,*) n,imi,ima,iqrsmw2(m),ymax,ymin if (abs(ymin).gt.abs(ymax)) then iqrs(n)=imi else iqrs(n)=ima end if n=n+1 m=m+1 else m=m+1 end if else if (idelay.gt.pe2*rrmed) then if (iqrspb2(l)-iqrs(n-1).gt.(1-pe2)*rrmed.or.n.eq.1) then c fem un test per no detectar ones T molt grans com falsos QRS, en c aquest cas el qrs estara davant coincidint amb un pic de ecgmw if (ecgmw(iqrspb2(l)+nint(95*samp/2)).gt.perc) then iqrs(n)=iqrspb2(l) n=n+1 l=l+1 else ibe=nint(iqrspb2(l)-250./samp) ien=nint(iqrspb2(l)-50./samp) call buscamaxmin (ibe,ien,ecgmw,iaux,yaux,imax,ymax) if ((ymax.gt.perc).and.(n.gt.1).and. & (imax.gt.iqrs(n-1)+250/samp)) then c concretem la posicio al voltant de ima ibe=nint(imax-0.05*ifm) ien=nint(imax+0.05*ifm) call buscamaxmin (ibe,ien,ecgpb,imi,ymin,ima,ymax) if (abs(ymin).gt.abs(ymax)) then iqrs(n)=imi else iqrs(n)=ima end if n=n+1 l=l+1 else l=l+1 end if end if else l=l+1 end if end if end do n=n-1 c do i=1,n c write(6,*) i,iqrs(i) c end do C LIMPIO EL RESTO DEL VECTOR do i=n+1,8000 iqrs(i)=0 end do write(6,5) nqrspb,nqrsmw,n 5 format(1x,'QRS en el ECG:',i4,/,' QRS en la conv.:',i4,/, & ' QRS conformados:',i4) return end C ------------------------------------------------------------- C BUSCA LOS PICOS DE LA SEQAL C ------------------------------------------------------------- subroutine detpic(sen,der,i) C detecta un pico en la seqal SEN con ayuda de su derivada DER C a partir de una posicion I y lo saca en la variable I C DETMAX es una var. logica que dice si hemos detectado un maximo o no C DERPOS es una var. logica que dice si la derivada es positiva o no dimension sen(100000),der(100000) logical detmax,derpos detmax=.false. do while (der(i).eq.0.) i=i+1 if (i.gt.39999) then return end if end do if (der(i).gt.0.) then derpos=.true. else derpos=.false. end if do while (detmax.eqv..false.) if (derpos.eqv..true.) then do while (der(i).ge.0.) i=i+1 if (i.gt.39999) then return end if end do t=der(i-1)/(-der(i)) if (t.lt.1.) then i=i-1 detmax=.true. else do while (der(i).le.0) i=i+1 if (i.gt.39999) then return end if end do derpos=.true. end if end do return end C ------------------------------------------------------------- C CALCULA LA PENDIENTE EN UN LUGAR C ------------------------------------------------------------- subroutine pendent(ifm,der,i,pmax) c DADO UN VALOR DE LA DERIVADA DE UNA SEQAL der A PARTIR DE UN PUNTO c i Y MUESTREADA A UNA FRECUENCIA ifm EN pmax SACO LA PENDIENTE c MAXIMA DE LA SEQAL 80 MS. ANTES DEL PUNTO SOLICITADO QUE NORMAL- c MENTE SERA UN MAXIMO SI BIEN NO TIENE POR QUE dimension der(100000) if (i.gt.100000-80) then l=100000 else l=i+80 end if pmax=der(l) do while ((l.gt.(i-ifm*0.08)).and.(l.gt.0)) if (abs(der(l)).gt.pmax) then pmax=abs(der(l)) end if l=l-1 end do return end C ------------------------------------------------------------- C COMPRUEBA SI ES O NO ONDA T C ------------------------------------------------------------- subroutine tonat(ifm,der,i,penqrs,onat) c CON ESTA SUBROUTINA SE SI UN MAXIMO EN UNA POSICION i Y CON UNA c PENDIENTE DEL qrs ANTERIOR DE penqrs ESTE MAXIMO PUEDE SER UNA c ONDA t SI SU PENDIENTE ES MENOR QUE 0.75*penqrs dimension der(100000) logical onat call pendent(ifm,der,i,pmax) if (pmax.lt.(penqrs*0.75)) then onat=.true. else onat=.false. end if return end C ------------------------------------------------------------- C RECALCULA EL INTERVALO RR ACTUAL C ------------------------------------------------------------- subroutine ajustrr(j,iqrs,irrint,irrlim) c AJUSTA EL INTERVALO MEDIO DEL VALOR rr SEGUN LOS 5 ULTIMOS VALORES c DE LOS qrs irrint.Y CALCULA EL INTERVALO MEDIO DE LOS MAS USUALES c PARA ESTABLECER EL LIMITE DE BUSQUEDA irrlim. c j ES EL NUMERO DE qrs QUE HAY HASTA EL MOMENTO c iqrs SON LAS POSICIONES QUE OCCUPOAN ESTOS. dimension iqrs(8000),irr(8000),irrsel(8000) if(j.eq.3) then irr(1)=irrint irrsel(1)=irrint n=1 nsel=1 irrbaix=nint(0.92*irrint) irralt=nint(1.16*irrint) end if irr(j-1)=iqrs(j-1)-iqrs(j-2) n=n+1 if ((irr(j-1).gt.irrbaix).and.(irr(j-1).lt.irralt)) then nsel=nsel+1 irrsel(nsel)=irr(j-1) end if sum=0 if (n.le.8) then do l=1,n sum=irr(l)+sum end do irrp8u=nint((1./n)*sum) else do l=0,7 sum=irr(n-l)+sum end do irrp8u=nint(0.125*sum) end if sum=0 if (nsel.le.8) then do l=1,nsel sum=irrsel(l)+sum end do irrpsel=nint(sum/nsel) else do l=0,7 sum=irrsel(nsel-l)+sum end do irrpsel=nint(0.125*sum) end if irrint=irrpsel irrbaix=nint(0.92*irrp8u) irralt=nint(1.16*irrp8u) irrlim=nint(1.5*irrpsel) return end