Programa para el cálculo de los
coeficientes de un modelo de
apuntado para un telescopio.Leonel Gutiérrez
Octubre, 2005
1. Introducción
Generalmente, cuando se instala un telescopio, su alineación no es
perfecta. Esta falta de alineación se traduce siempre en errores, tanto en
el apuntado como en el seguimiento de los objetos estelares con el
telescopio. Por tanto, en un telescopio profesional es necesario alinearlo
de la mejor manera posible, moviendo la montura del telescopio hasta
que los errores se reducen al mínimo. Esta tarea se ha realizado ya en los
telescopios del Observatorio Astronómico Nacional en San Pedro Mártir.
Sin embargo, aún en esas circunstancias, quedan errores residuales muy
difíciles de corregir mecánicamente, por lo que es necesario contar con
un modelo que permita corregir previamente las coordenadas para
conseguir un óptimo apuntado del telescopio. Aunque aquí nos
referiremos sólo a los telescopios con montura ecuatorial, la idea también
se aplica a otros tipos de monturas. Actualmente, los telescopios del
Observatorio Astronómico Nacional en San Pedro Mártir cuentan con un
modelo que hace un ajuste en base a polinomios. Sin embargo, debido a
diversos factores como el hecho de que la distribución de cargas del
telescopio no sea constante en el tiempo, pues están sujetos a cambios
de instrumentos, es necesario recalcular con cierta frecuencia los
coeficientes del modelo para optimizar la precisión de apuntado de
telescopio. Pero esto requiere de un método de fácil implementación que
permita el cálculo de los coeficientes por parte del personal técnico del
Observatorio, a fin de contar siempre con el mejor modelo de apuntado.
En este trabajo se describe un modelo de ajuste trigonométrico y,
se propone un programa con el que se ha conseguido encontrar los
coeficientes para la corrección de los errores de alineación al polo, falta
de perpendicularidad de los ejes, flexiones mecánicas y falta de
alineación del eje óptico. El programa está escrito en Fortran y hace uso
de las nuevas características del Fortran 95, lo que permite hacer una
gran cantidad de cálculos de manera muy simple. Existe también una
versión para IDL y en breve estará lista una versión del programa en
Fortran77. El caso que se presenta como ejemplo usa datos que
corresponden al telescopio de 1 m de diámetro del OAN en Tonantzintla,
pero el método puede aplicarse directamente a cualquier tipo de
telescopios con montura ecuatorial. Aplicando el modelo de correcciones
a una base de datos de errores de apuntado, los errores rms se han
reducido en Declinación de 49.8” a 8.9” y en Ángulo Horario de 99.7” a
30.1”.
2. Entendiendo el problema
Un objeto en el cielo se identifica por sus coordenadas: ascensión
recta y declinación (AR/Dec o /αδ). Las declinaciones se miden hacia el
norte y hacia el sur del ecuador celeste, mientras que la ascensión recta
se mide hacia el este del equinoccio (la intersección entre el ecuador
celeste y la eclíptica, siendo esta última el plano de la órbita de la Tierra
alrededor del Sol). Pero, conocer AR y Dec no es el final de la historia.
Hay una serie de correcciones y transformaciones astronómicas para
hacer antes de estar listos para apuntar el telescopio. Luego, es
necesario traducir estas coordenadas a otras coordenadas que sirvan
para mover el telescopio. Pero en un telescopio ecuatorial (ver figuras 1, 2
y 3) la situación es, en teoría, simple, ya que si el eje polar del telescopio
es paralelo al eje polar de la Tierra, la declinación del telescopio coincide
con la declinación celeste; el otro eje del telescopio, denominado ángulo
horario (AH) y medido hacia el este y el oeste del meridiano, se relaciona
con la ascensión recta mediante la ecuación AR = TS – AH, donde TS es
el tiempo sideral local (el tiempo sideral local corre un poco mas rápido
que el tiempo regular, de tal manera que se adelanta casi 4 minutos
diarios).
Figura 1. Dos tipos de monturas ecuatoriales simétricas.
Figura 2. Dos tipos de monturas ecuatoriales asiméticas.
Pero el problema no ha terminado. Aunque ya tenemos las
coordenadas del telescopio y estamos listos para moverlo, hemos
olvidado que vivimos en un planeta que gira y se balancea, que vemos a
través de una atmósfera y que el telescopio no es una máquina perfecta.
Todos estos factores han de tomarse en cuenta antes de apuntar el
telescopio. La secuencia de cálculos y ajustes que debemos hacer se
muestra en la figura 4.
Figura 3. Telescopio de 2.1m de SPM. Su montura es ecuatorial de yugo (simétrica).
Los tres pasos principales son: pasar de coordenadas medias a
aparentes, de aparentes a observadas y de observadas a instrumentales.
El primer paso corrige el hecho de que el eje de la Tierra y, por tanto, el
ecuador celeste están en constante movimiento debido a la precesión y a
la nutación, así como el hecho de que nuestro movimiento alrededor del
Sol hace que las estrellas parezcan desplazarse debido a la aberración
anual. La transformación de aparentes a observadas se debe a la rotación
de la Tierra, a la ubicación geográfica del telescopio y a la refracción
atmosférica. El último paso consiste en corregir las imperfecciones
instrumentales del telescopio.
Figura 4. Diagrama que muestra la secuencia de las correcciones.
Las primeras trasformaciones se realizan con ecuaciones que se
aplican de igual manera en cualquier telescopio y no dependen de la
construcción del mismo. Sin embargo, la última es una transformación
única para cada telescopio, pues sólo depende de sus propias
características.
La precesión del polo terrestre alrededor del polo de la eclíptica,
junto con una inclinación gradual de la eclíptica, es la componente de
largo plazo de un movimiento complejo causado por los efectos
gravitacionales de los miembros del Sistema Solar sobre la Tierra que
gira. El periodo de este movimiento es de 26000 años y produce cambios
de hasta 50 segundos de arco por año en las coordenadas de las
estrellas. El “cabeceo” residual del eje terrestre, que tiene un período de
18.6 años, es la nutación y afecta el apuntado del telescopio en el orden
de los 10 segundos de arco. La aberración anual es culpable de hasta 20
segundos de error en el apuntado de un telescopio.
Luego, dado que el telescopio está en la Tierra y dentro de la
atmósfera, es necesario hacer las otras correcciones para lo cual es
necesario conocer la latitud, la longitud y altura sobre el nivel del mar del
sitio donde está el observatorio, así como la presión y la temperatura
ambiente y el tiempo exacto. Los errores que pueden cometerse por el
efecto de la refracción son hasta del orden de 1 minuto de arco para una
elevación de 45º al nivel del mar.
Todas estas correcciones proporcionan las coordenadas
observadas, que, si todo fuera perfecto, nos permitiría ver la estrella
perfectamente centrada en el telescopio. Pero el telescopio es real y, por
tanto, sus codificadores pueden tener un ligero desplazamiento en sus
lecturas, puede haber un ligero juego en los engranes (backlash), sus
ejes pueden no ser perfectamente perpendiculares y el eje polar del
telescopio puede no estar apuntando exactamente al polo. Corregir
físicamente estas imperfecciones puede ser una tarea larga y costosa,
por lo que en ocasiones es mejor aceptarlas y tenerlas en cuenta al
calcular las coordenadas del objeto.
3. El modelo de apuntado
En una montura ecuatorial, estas imperfecciones causan un efecto
que puede modelarse mediante seis términos puramente geométricos,
complementados con tres debidos a flexiones (Wallace y Tritton,1975;
Trueblood y Genet, 1998; Wallace, 2001). En la tabla 1 se muestran estos
términos.
Los términos HI y DI son simplemente errores de inicialización en
las lecturas de las coordenadas instrumentales y pueden calcularse con
un apuntado inicial del telescopio. El término CO describe qué tan precisa
es la alineación entre el eje mecánico del telescopio y el eje óptico y si el
instrumento de detección está bien alineado (la componente que afecta a
declinación no depende del ángulo, por lo que queda integrada en DI). El
término NP depende de qué tan lejos del ángulo recto está el eje de
declinación con respecto al eje polar.
Término Descripción hΔ Δδ
HI Error constante de posición HI
DI Error constante de posición DI
CO Error de colimación CO*secδ
NP y el eje polar noδ perpendiculares
NP*tanδ
PV Efecto en elevación de la no coincidencia con el polo
PV*senh*tanδ PV*cosh
PH Efecto perpendicular a PV -PH*cosh*tanδ PH*senh
FT Flexión del tubo FT*cos *senφ h*senδ FT*(cos *cosφ h*sen -δsen *cos )φ δ
FY Flexión del yugo FY*cosh
FD Flexión del eje de declinación
-FD*(cos *cosφ h+ sen *tan )φ δ
Tabla 1. Términos que afectan en una montura ecuatorial. h y son el ánguloδ
horario y la declinación y es la latitud del observatorio.φ
Los términos PH y PV describen qué tan apartado está el eje polar
del eje verdadero en la dirección horizontal en el caso de PH y en la
vertical para PV. FT describe cuánto cae el telescopio al acercarse más a
una posición horizontal. FY es la flexión del yugo (o tenedor) y FD es un
término de flexiones para el eje de declinación, que sólo se aplica en el
caso de los telescopios como los de montura alemana, en la que el eje de
declinación no está soportado en ambos extremos.
Además de estos términos, generalmente existen términos
menores que presentan un comportamiento periódico, causados por
defectos de maquinado y de alineación de los diferentes ejes y
acoplamientos, que generalmente son de magnitud menor. Estos no se
incluyen en el modelo aquí descrito.
En la Tabla 1, cada uno de los coeficientes es en general un
ángulo pequeño, usualmente del orden de segundos de arco. Las
fórmulas para corregir cada uno de los ejes están dadas por la suma de
los elementos en sus respectivas columnas. Así, despreciando el término
FD, las fórmulas de corrección para el modelo de apuntado son:
h = Δ HI + CO*sec + δ NP*tan -δ PH*cosh*tan + δ PV*senh*tan +δ FT*cos *senφ h*senδ
= Δδ DI + PH*senh + (PV+FY)*cosh + FT*(cos *cosφ h*sen -sen *cos ) δ φ δ
Aplicando este modelo puede mejorarse notablemente el apuntado
del telescopio.
4. ¿Cómo encontrar los coeficientes?
Encontrar los coeficientes del modelo no es una tarea fácil
(excepto por HI y DI). Además, los coeficientes varían ligeramente con el
tiempo y un modelo no puede durar toda la vida: la fatiga de los
elementos del telescopio y el esquema instrumental provocarán ligeras
variaciones en los coeficientes de flexión, el desplazamiento del eje óptico
durante los procesos de mantenimiento provocarán una variación en el
coeficiente CO y los asentamientos del suelo provocarán variaciones en
la alineación del eje polar del telescopio. Esto hace que deban calcularse
los coeficientes con cierta periodicidad.
Por esta razón, se ha creado el programa encuentra_modelo. Este
programa ha sido escrito en Fortran, usando las nuevas
implementaciones incorporadas en el Fortran 95 y se debe usar en
ambiente Linux. También es importante que se encuentre instalada una
versión del Gnuplot. Existe también una versión para IDL. Para usarlo, es
necesario apuntar el telescopio a diferentes estrellas brillantes en el cielo,
cuyas coordenadas observadas hayan sido previamente calculadas. Es
importante incluir diferentes posiciones en el cielo, anotando la corrección
manual que haya tenido que hacerse, tanto en ángulo horario como en
declinación. Los datos deben tabularse en un archivo de texto de la
siguiente manera:
AH dAH Dec dDec
donde AH y Dec son el ángulo horario (en horas con respecto al
meridiano) y la declinación (en grados) de las coordenadas calculadas del
objeto y dAH y dDec son las correcciones que tuvieron que hacerse para
centrar el objeto en el telescopio, dadas en segundos de arco.
Por ejemplo:
-2.473 -33 -16.686 -50.2
-1.799 42 22.515 16.0
(AH) (dAH) (Dec) (dDec)
Es importante incluir el mayor número de puntos en la muestra
para garantizar un mejor ajuste del modelo. Se recomiendan unos 40
puntos, para tener del orden de 10 en cada cuadrante del cielo.
5. Descripción del programa
A este texto se anexa en el Apéndice A un listado del programa en
Fortran y en el Apéndice B el correspondiente listado de la versión para
IDL. El programa escrito en Fortran funciona de la siguiente manera:
a) Busca el archivo con los datos. El programa solicita al usuario
que proporcione el nombre del archivo (el que se ha usado para hacer las
pruebas se llama ‘epos.txt’).
b) Solicita al usuario la latitud del lugar en grados.
c) Cuenta cuántas líneas no vacías tiene el archivo, a fin de alojar
en memoria un array suficientemente grande para contener los datos. Los
elementos de este array son de tipo derivado y contienen cuatro
elementos de tipo real: AH, Dec, dAH y dDec.
d) Grafica los errores dDec contra dAH para que el usuario tenga
una idea de la magnitud de los errores.
e) Calcula el término cos *cosφ h*sen -sen *cos δ φ δ y ajusta la recta
tomando como eje vertical a dDec. La pendiente encontrada corresponde
al termino FT. Presenta al usuario los datos (pendiente, ordenada al
origen y correlación del ajuste), quien puede aceptar o no la corrección.
f) Una vez corregidos los errores por este término, se calcula el
término cosh y repite el proceso anterior. Esto da como resultado la suma
de los términos PV y FY. Nuevamente, pregunta al usuario si acepta la
corrección.
g) Corrige los errores, si así lo ha decidido el usuario, y calcula el
término senh. Al repetir el proceso se tiene el término PH. De esta manera
se han encontrado ya los coeficientes que corrigen declinación.
h) Grafica, llamando al “gnuplot”, los datos mostrando cómo
estaban distribuidos los datos durante los ajustes.
i) Incorpora los términos calculados (FT y PH) y corrige los errores
en ángulo horario. Revisa si existe algún posible backlash en el
mecanismo y lo corrige.
j) Calcula el término senh*tanδ y ajusta de nuevo una recta,
tomando ahora como eje vertical a dAH. La pendiente del ajuste es ahora
PV. Esto permite discriminar ya también el término FY, pues sólo se
conocía la suma PV+FY.
k) Si el usuario acepta la corrección, se corrigen los errores y se
calcula ahora el término tan . Esto permite encontrar el término δ NP.
l) Finalmente, calcula el término secδ y encuentra el término CO.
m) Grafica ahora los datos de ángulo horario mostrando cómo
estaban distribuidos durante los ajustes. También muestra los errores
corregidos graficando nuevamente dDec contra dAH y presenta los
valores de los coeficientes encontrados.
El programa escrito para IDL funciona de manera parecida, con
algunas pequeñas variantes:
a) El programa recibe como argumentos lel nombre del archive con
los datos, la latitud del observatorio y un arreglo de “unos” y “ceros” que
indican qué correcciones se harán. Por ejemplo:
ENCUENTRA_MODELO, archivo="epos.txt", latitud=19.5, corrige=[1,1,1,0,1,0,1]
indica que se harán las correcciones correspondientes a PH, PV, FT, NP
y BL y que no se aplicarán las correcciones por el término combinado
PV_FY ni la de colimación óptica. El orden es:
PH, PV, FT, PV_FY, NP, CO, BL
La ausencia de este arreglo en el argumento hará que se calculen todas
las correcciones. De hecho, se recomienda habilitar todas las
correcciones en una primera ejecución y determinar de allí los términos
que pueden o deben omitirse. La latitud deberá darse en grados.
b) Busca el archivo con los datos.
c) Grafica los errores dDec contra dAH para que el usuario tenga
una idea de la magnitud de los errores.
d) Calcula el término cos *cosφ h*sen -sen *cos δ φ δ y ajusta la recta
tomando como eje vertical a dDec. La pendiente encontrada corresponde
al termino FT.
e) Una vez corregidos los errores por este término, se calcula el
término cosh y repite el proceso anterior. Esto da como resultado la suma
de los términos PV y FY.
f) Corrige los errores, si así lo ha decidido el usuario con los
valores del argumeno, y calcula el término senh. Al repetir el proceso se
tiene el término PH. De esta manera se han encontrado ya los
coeficientes que corrigen declinación.
g) Grafica los datos usando las propias utilerías de IDL, mostrando
cómo estaban distribuidos durante los ajustes.
h) Incorpora los términos calculados (FT y PH) y corrige los errores
en ángulo horario. Revisa si existe algún posible backlash en el
mecanismo y lo corrige.
i) Calcula el término senh*tanδ y ajusta de nuevo una recta,
tomando ahora como eje vertical a dAH. La pendiente del ajuste es ahora
PV. Esto permite discriminar ya también el término FY, pues sólo se
conocía la suma PV+FY.
j) Se corrigen los errores y se calcula ahora el término tan . Estoδ
permite encontrar el término NP.
k) Finalmente, calcula el término secδ y encuentra el término CO.
l) Grafica ahora los datos de ángulo horario mostrando cómo
estaban distribuidos durante los ajustes. También muestra los errores
corregidos graficando nuevamente dDec contra dAH y presenta los
valores de los coeficientes encontrados.
Los términos HI y DI encontrados durante este ajuste no deben ser
definitivos, ya que dependen del proceso de inicialización al empezar una
sesión de observación. Estos valores deben recalcularse cada vez que se
inicia una sesión de observación, apuntando una estrella después de
haber aplicado el modelo calculado. El error en este primer apuntado
corresponde directamente a los términos HI y DI. Si se desea, pueden
apuntarse varias estrellas y promediar los errores encontrados. Pero este
hecho puede obviarse en los telescopios del OAN en SPM, pues el
sistema de control de los telescopios calcula estos términos cuando se
corrigen las coordenadas después del primer apuntado.
Los coeficientes encontrados pueden sustituirse ahora en las
fórmulas de la sección 3 para hacer las correcciones a las coordenadas.
Para obtener mejores resultados de este modelo trigonométrico, en
el caso de los telescopios del OAN en San Pedro Mártir, se sugiere inhibir
el modelo polinomial que actualmente corrige los errores mecánicos de
apuntado, calcular los coeficientes del modelo trigonométrico y, después
de aplicarlo, recalcular el modelo polinomial, pues con este último pueden
modelarse los demás errores residuales (errores de los acoplamientos de
los codificadores, errores de los engranes, etc.) que prácticamente no
cambian con el tiempo.
6. Resultados
Para probar el algoritmo, hemos aplicado el programa a una base
de datos con errores de apuntado del telescopio del Observatorio
Astronómico Nacional en Tonantzintla y hemos encontrado los siguientes
coeficientes para el modelo (en este caso se usó descartaron las
correcciones para CO y para el término combinado PV_FY:
Término Valor en segundos de arco
Offset en AH HI 9.328
Offset en Dec DI 9.550
Error de colimación CO 0.000
Falta de perpendicularidad NP 67.520
Error horizontal en el polo PH -17.693
Error horizontal en el polo PV -117.582
Flexión del tubo FT 137.124
Flexión del yugo FY 117.582
Backlash en AH BL 171.394
Estos valores permiten disminuir el valor rms de los errores desde
99.7” y 49.8” para AH y Dec, respectivamente, hasta 30.1” y 8.9”.
En las figuras 5, 6, 7 y 8 se reproducen las gráficas entregadas por
el programa.
El código de ambas versiones del programa presentadas aquí se
encuentra en la dirección:
http://www.astrosen.unam.mx/~leonel/progs/modelo/
Figura 4. Gráfica con los errores de Dec y de AH, antes de ser corregidos. Los aparentes 2 grupos
de datos se deben al error por juego mecánico (backlash).
Figura 5. Gráfica de los errores de la figura 5 después de ser corregidos. Nótese la escala de los
ejes.
Figura 6. Gráficas de los errores de Declinación durante el proceso de corrección.
Figura 7. Gráfica de los errores en Ángulo Horario durante el proceso de corrección. Nótese el
escalón en la primera gráfica al pasar por cero en AH debido al backlash.
7. Referencias
1. Wallace, P. T, y Tritton, K. P., 1979, MNRAS, 189, 115.
2. Trueblood, M. y Genet, R. M., Telescope Control, Willman-Bell, Inc.,
Richmond, Virginia, USA, 1998.
3. Wallace, P., “Telescope Pointing”,
http://www.tpsoft.demon.co.uk/pointing.htm (2001).
Apéndice A. Listado del programa en Fortran95! Listado del programa!******************************************************************************************!! Programa 'encuentra_modelo' elaborado por Leonel Gutierrez !! Este programa lee un archivo con una serie de datos que muestran los errores de! apuntado de un telescopio con montura ecuatorial y calcula los coeficientes de! un modelo trigonometrico para corregir dicho apuntado. !!******************************************************************************************!!! Lo que sigue es un modulo con los elementos necesarios para el programa! Contiene las siguientes funciones y subrutinas!! 1) ! Funcion para contar los renglones del archivo! function cuantas_lineas(archivo) result(cuantas)!! 2) ! Subrutina para traer todos los elementos a sus lugares en el arreglo! subroutine trae_lineas(archivo, arreglo)!! 3) ! Subrutina para guardar en un archivo provisional los datos a graficar! subroutine guarda_lineas(archivo, matriz)!! 4) ! Subrutina para ajustar por minimos cuadrados una recta a una distribucion. Calcula! ! la pendiente, la ordenada al origen y la correlacion! subroutine ajusta_recta(x, y, m, b, corr)!! 5) ! Funcion que calcula el valor rms de un vector.! function calcula_rms(x)!! 6) ! Subrutina que prepara el archivo que se le va a entregar al 'gnuplot'! subroutine prepara_archivo_de_grafica()!! 7) ! Subrutina que agrega las diferentes graficas al archivo que usara el 'gnuplot'.! ! Podemos poner hasta 4 graficas en una ventana. (El 'gnuplot' permite muchas! ! mas, pero en este programa nos hemos limitado a 4.)! subroutine agrega_grafica(x, y, sx, sy, posx, posy, etiqueta, archivo_prov)!
! 8) ! Subrutina que inicia una grafica llamando al 'gnuplot'! subroutine inicia_grafica()!! 9) ! Subrutina que grafica los errores de Declinacion contra los de AH! subroutine grafica_errores(etiqueta)!!10) ! Subrutina que calcula los coeficientes del modelo usando los errores de Declinacion! subroutine encuentra_coeficientes_dec()!!11) ! Subrutina que calcula los demas coeficientes del modelo usando los errores de AH! subroutine encuentra_coeficientes_ah()
module utilerias
! variables y constantes para usarse en el modulo
integer, parameter :: dp = selected_real_kind(8,30) ! La clase de doble precision character(len = 256) :: linea ! define una cadena para ir leyendo el archivo integer :: ioss ! variable para almacenar los errores del READ
! Voy a poner los reales de doble precision para no tener problemas de redondeo! en las funciones trigonometricasreal(kind=dp), parameter :: pi = acos(-1.)real(kind=dp), parameter :: gra_rad = pi/180. ! Factor multiplicativo para convertir
! grados en radianesreal(kind=dp), parameter :: horas_rad = gra_rad*15.0 ! Factor multiplicativo para convertir
! horas de cielo en radianesinteger :: d1, d2, d3,d4 ! dummiesreal(kind=dp), dimension(4) :: correlacion ! para guardar las correlacionesreal(kind=dp), dimension(4) :: m ! las pendientesreal(kind=dp), dimension(4) :: b ! y las ordenadascharacter(len=10) :: resp ! para los dialogos
real(kind=dp) :: PH = 0.0 ! Error horizontal en el poloreal(kind=dp) :: PV = 0.0 ! Error vertical en el poloreal(kind=dp) :: FT = 0.0 ! Flexiones del tuboreal(kind=dp) :: FY = 0.0 ! Flexiones del yugoreal(kind=dp) :: NP = 0.0 ! Falta de perpendicularidadreal(kind=dp) :: CO = 0.0 ! Colimacionreal(kind=dp) :: PV_FY = 0.0 ! Flexiones del yugo + error vertical en poloreal(kind=dp) :: DAF = 0.0 ! Flexiones del eje de declinacion; No se
! aplica en este caso
real(kind=dp) :: BL = 0.0 ! Error de backlashreal(kind=dp) :: HI = 0.0 ! Offset inicial en AHreal(kind=dp) :: DI = 0.0 ! Offset inicial en Dec
real(kind=dp) :: phi = 19.5*gra_rad ! La latitud del observatorioreal(kind=dp) :: senphi ! Esto es el seno de la latitudreal(kind=dp) :: cosphi ! Esto es el coseno de la latitud
! variables derivadas
type coordenadasreal(kind=dp) :: AH ! Angulo horario del telescopioreal(kind=dp) :: Dec ! Declinacionreal(kind=dp) :: dAH ! Error en AHreal(kind=dp) :: dDec ! Error en Dec
end type coordenadas
! variables globales
! En este arreglo pongo todos los datos del archivotype(coordenadas), dimension(:), allocatable :: arreglo
! Esta es una matriz de n x 9 donde pondremos los ejes a graficar; las columnas quedaran! asignadas como sigue:! 1) para el eje x! 2) para los errores antes de corregirse; estos se graficaran en el eje y! En las demas columnas se pondran los mismos errores conforme se les vaya! aplicando las correcciones
real(kind=dp), dimension(:,:), allocatable :: matriz
integer :: ii ! un indice
contains
!***************************************************!! Funcion para contar los renglones no vacios del archivo. Esto permite reservar el numero de lugares! necesario para los arreglos usados en el programa. Basicamente son 'arreglo' y 'matriz', asi como! algunos vectores auxiliares dentro de las subrutinas!function cuantas_lineas(archivo) result(cuantas)
character(*), intent(in) :: archivointeger :: cuantas
logical :: existe ! variable para verificar que el archivo existeinquire(FILE = archivo, EXIST = existe)
cuantas = 0if (existe) then
open (unit=1,file=archivo,status='old')i = 0
do read(1,'(a)',IOSTAT=ioss) linea
if(IOSS == 0) thenif(len_trim(linea) > 0) i = i + 1
elseexit
endif enddo
cuantas = i
close(1)else
print*,"No existe el archivo"end if
end function cuantas_lineas
!***************************************************!! Subrutina que lee todos los renglones del archivo de entrada y pone todos los elementos en! sus lugares correspondientes en el arreglo.!Subroutine trae_lineas(archivo, arreglo)
character(*), intent(in) :: archivotype(coordenadas), dimension(*) :: arreglo
logical :: existe ! variable para verificar que el archivo existe
inquire(FILE = archivo, EXIST = existe)
if (existe) thenopen (unit=1,file=archivo,status='old')i = 1
do read(1,'(a)',IOSTAT=ioss) linea
if(IOSS == 0) thenif(len_trim(linea) > 0) then
read(linea,*), arreglo(i)%AH, arreglo(i)%dAH, &arreglo(i)%Dec, arreglo(i)%dDec
i = i + 1endif
elseexit
endifend do
close(1)else
print*,"No existe el archivo"end if
end Subroutine trae_lineas
!***************************************************!! Esta subrutina guarda la matriz en un archivo provisional para que sea de alli donde tome el 'gnuplot' los! datos a graficar. El archivo provisional no se borrar al terminar el programa, a fin de que el usuario! pueda tener los datos como referencia. El archivo para graficar los errores de Declinacion en cada etapa! de la correccion, quedan guardados en el archivo 'prov.txt'; los de AH quedan en 'prov_ah.txt'; los errores! ya corregidos por el modelo quedan en 'prov_i.txt'. Al reiniciarse el programa, los archivos se sobreescriben.!Subroutine guarda_lineas(archivo, matriz)
character(*), intent(in) :: archivoreal(kind=dp), dimension(:,:), intent(in) :: matriz
integer :: nn = size(matriz,1)
open (unit=1,file=archivo,status='replace')i = 1
do write(1,'(9(f10.5,3X))',IOSTAT=ioss) matriz(i,1), matriz(i,2), matriz(i,3), matriz(i,4), &
matriz(i,5), matriz(i,6), matriz(i,7), matriz(i,8), matriz(i,9) if(IOSS == 0) then
i = i + 1if (i == n) exit
elseexit
endifend do
close(1)end Subroutine guarda_lineas
!***************************************************!! Esta subrutina ajusta una recta usando el metodo de minimos cuadrados!subroutine ajusta_recta(x, y, m, b, corr)
real(kind = dp), dimension(:), intent(in) :: xreal(kind = dp), dimension(:), intent(in) :: yreal(kind = dp), intent(out) :: mreal(kind = dp), intent(out) :: breal(kind = dp), intent(out) :: corr
real, dimension(:), allocatable :: va, vb, vc ! vectores auxiliaresinteger :: n ! tamanio de x o y
! variables para calcular la estadisticareal(kind = dp) :: sumax, sumay, sumaxy, sumax2, &
cociente, varx, vary, covxy, Xm, Ym
! Procedemos con los minimos cuadrados canonicos
n = size(x) ! Aqui calculamos el tamanio del arreglo
allocate(va(n)) ! Reserva n lugares para va, vb y vcallocate(vb(n))allocate(vc(n))
sumay = sum(y) ! Suma de todos los elementos en ysumax = sum(x) ! Suma de todos los elementos en xva = x*xsumax2 = sum(va) ! Suma de todas las x^2va = x*ysumaxy = sum(va) ! Suma de todas los elementos cruzadoscociente = n*sumax2 - sumax*sumax
! La ordenada al origenb = (sumay*sumax2-sumax*sumaxy)/cociente
! La pendientem = (n*sumaxy-sumax*sumay)/cociente
! Vamos a sacar ahora la correlacionXm = sumax/n ! La media de xYm = sumay/n ! La media de y
va = x - Xm ! Calcula los errores en xvb = y - Ym ! Calcula los errores en y
vc = vb*vb ! Calcula el vector de los cuadrados de las! diferencias en y
sumay2 = sum(vc) ! Aqui la suma de todo ese vectorvc = va*va ! Calcula el vector de los cuadrados de las
! diferencias en xsumax2 = sum(vc) ! Aqui la suma de todo ese vectorvc = va*vb ! Calcula el vector de los productos cruzadossumaxy = sum(vc) ! Aqui la suma de todo ese vector
varx = sumax2/n ! La varianza en x vary = sumay2/n ! La varianza en y
covxy = sumaxy/n ! La covarianzacorr = covxy/(sqrt(varx*vary))
! Finalmente ya tenemos el coeficiente de correlaciondeallocate(va) ! Libera la memoriadeallocate(vb)deallocate(vc)
end subroutine ajusta_recta
!***************************************************!! Esta funcion calcula el valor rms de un vector. En este caso, se trata de un! vector de errores!function calcula_rms(x) result(rms)
real(kind = dp), dimension(:), intent(in) :: xreal(kind = dp) :: rms
real, dimension(:), allocatable :: va, vb, vc ! vectores auxiliaresinteger :: n ! tamanio de x o y
! variables para calcular la estadisticareal(kind = dp) :: sumax, sumax2, varx, Xm, Ym
n = size(x) ! Aqui calculamos el tamanio del arreglo
allocate(va(n)) ! Reserva n lugares para va
! Vamos a calcular el RMSsumax = sum(x) ! Suma de todos los elementos en xXm = sumax/n ! La media de xva = x - Xm ! Calcula los errores en xva = va*va ! Calcula el vector de los cuadrados de las
! diferencias en
sumax2 = sum(va) ! Aqui la suma de todo ese vector
varx = sumax2/n ! La varianza en xrms = sqrt(varx) !
! Finalmente ya tenemos el coeficiente de correlaciondeallocate(va) ! Libera la memoria
end function calcula_rms
!***************************************************!! Esta subrutina prepara el archivo que luego se le entregara al 'gnuplot' para hacer las! graficas!subroutine prepara_archivo_de_grafica()
open (unit=3,file="pp.prg",status='replace')write(3,'(A)') "set origin 0,0"write(3,'(A)') "set size 1,1"write(3,'(A)') "set multiplot"
close(3)end subroutine prepara_archivo_de_grafica
!***************************************************!! Esta subrutina ordena al sistema que arranque el 'gnuplot' usando el archivo 'pp.prg'! como archivo de lotes para hacer las graficas!subroutine inicia_grafica()
character(len = 25) :: salida
salida = "gnuplot -persist pp.prg"call system(salida)
end subroutine inicia_grafica
!***************************************************!! Esta subrutina agrega al archivo 'pp.prg' los mandos necesarios para insertar una grafica en! la ventana del 'gnuplot'!subroutine agrega_grafica(x, y, sx, sy, posx, posy, etiqueta, archivo_prov)
! 'x' es el numero de columna que se usara en el eje x; lo mismo con 'y'! 'sx' es la etiqueta que ira en el eje x; lo mismo con y
integer, intent(in) :: x, ycharacter(len = *), intent(in) :: sx, sy ! etiquetas para la graficainteger, intent(in) :: posx, posy ! pueden valer 0 y 1, para
! indicar en que cuadrante se van a poner
! 'archivo_prov' es donde se han puesto los datos a graficarcharacter(len = *), intent(in) :: etiquetacharacter(len = *), intent(in) :: archivo_prov
integer :: mx, my, mmx, mmy ! para poner los max y min! Calcula los valores maximos y minimosmx = floor(minval(matriz(:,x)))my = floor(minval(matriz(:,y)))mmx = ceiling(maxval(matriz(:,x)))mmy = ceiling(maxval(matriz(:,y)))
open (unit=3,file="pp.prg",status='old', position='append')
write(3,'(A12,I4,A1,I4,A1)') "set xrange [", mx, ":", mmx, "]"write(3,'(A12,I4,A1,I4,A1)') "set yrange [", my, ":", mmy, "]"write(3,'(A)') "set size 0.5,0.5"write(3,'(A,F3.2,A1,F3.2)') "set origin ", 0.5*posx,",", 0.5*posywrite(3,'(A12,A)') "set xlabel ", sxwrite(3,'(A12,A)') "set ylabel ", sywrite(3,'(A6,A,A7,I2,A1,I2,A3,A)') "plot '",archivo_prov, "' using ", x, ":", y, " t ",etiqueta
close(3)
end Subroutine agrega_grafica
!***************************************************!! Esta subrutina grafica los errores de Declinacion contra los errores de Angulo horario para que el! usuario tenga una idea de la magnitud de los errores. Se llama al inicio del programa y al final! para poder comparar los errores iniciales contra los finales!subroutine grafica_errores(etiqueta, rmsdec, rmsah)
character(len = *), intent(in) :: etiquetareal, intent(out) :: rmsdec, rmsah
integer :: mx, my, mmx, mmy ! para poner los max y min
matriz(:,1) = arreglo%dDecmatriz(:,2) = arreglo%dAH
! Calcula los valores maximos y minimosmx = floor(minval(matriz(:,1)))my = floor(minval(matriz(:,2)))mmx = ceiling(maxval(matriz(:,1)))mmy = ceiling(maxval(matriz(:,2)))
rmsdec = calcula_rms(matriz(:,1))rmsah = calcula_rms(matriz(:,2))call guarda_lineas("prov_i.txt", matriz)
open (unit=3,file="pp.prg",status='replace')write(3,'(A)') "set origin 0,0"write(3,'(A)') "set size 1,1"write(3,'(A12,I4,A1,I4,A1)') "set xrange [", mx, ":", mmx, "]"write(3,'(A12,I4,A1,I4,A1)') "set yrange [", my, ":", mmy, "]"write(3,'(A,F5.1,A)') "set xlabel 'dDec: ", rmsdec, " rms'"write(3,'(A,F5.1,A)') "set ylabel 'dAH: ", rmsah, " rms'"write(3,'(A,A)') "plot 'prov_i.txt' using 1:2 t ", etiqueta
close(3)
call inicia_grafica()end subroutine grafica_errores
!***************************************************!! Esta subrutina se encarga de hacer los calculos necesarios para encontrar los coeficientes del! modelo de correccion correspondientes a Declinacion. Solicita al usuario la confirmacion de! las correcciones. El usuario debe decidir si se hacen las correcciones o no, en funcion de la! informacion presentada, en particular la correlacion del ajuste!subroutine encuentra_coeficientes_dec()
! Pone en la primera columna los errores en declinacion antes de ninguna correccioninteger :: tam, kk
matriz(:,1) = arreglo%dDec
! En la segunda columna pone el termino de flexiones del tubo; en los calculos, va! multiplicando a Dec, que esta dada en grados, por el termino 'gra_rad' para ponerla! en radianes y a AH, que esta en horas, por 'horas_rad'
matriz(:,2) = -senphi*cos(arreglo%Dec*gra_rad) + & cosphi*sin(arreglo%Dec*gra_rad)*cos(arreglo%AH*horas_rad);
!!!!! Primer ajuste (para el termino FT) !!!!!! Calcula la mejor recta que se ajusta a esta distribucion
call ajusta_recta(matriz(:,2), matriz(:,1), m(1), b(1), correlacion(1))
! Imprime los valores de m, b y la correlacion para que el usuario decida si se
! aplica la correccion
write(*,'(A,3F14.6)') " Flexiones del tubo: m, b y corr=", m(1), b(1), correlacion(1)
! Pregunta si aplica la correccionwrite(*,'(/a)', advance = "no") "Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores usando la recta encontradaarreglo%dDec = arreglo%dDec-( m(1)*matriz(:,2) + b(1) );FT = m(1)DI = DI + b(1)
endif
! En la tercera columna de la matriz pone los errores con esta primera correccion; si no hubo! correccion se dejan como estaban pero se ponen en esa columna para poder graficarlos
matriz(:,3) = arreglo%dDec
! En la cuarta columna pone el termino de flexiones del yugo + alineacion vertical al polomatriz(:,4) = cos(arreglo%AH*horas_rad);
!!!!! Segundo ajuste (para el termino PV_FY) !!!!!! Calcula la mejor recta que se ajusta a esta distribucion
call ajusta_recta(matriz(:,4), matriz(:,3), m(1), b(1), correlacion(1))write(*,'(A,3F14.6)') " Flexiones del yugo y no alin. vertical: m, b y corr=", m(1), b(1), correlacion(1)
! De nuevo, dejamos que el usuario decidawrite(*,'(/a)', advance = "no") "Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores usando la recta encontradaarreglo%dDec = arreglo%dDec-( m(1)*matriz(:,4) + b(1) );PV_FY = m(1)DI = DI + b(1)
endif
! En la columna 5 de la matriz pone los errores para ser graficados despuesmatriz(:,5) = arreglo%dDec
! Y en la columna 6 pone el termino de alineacion horizontal al polomatriz(:,6) = sin(arreglo%AH*horas_rad)
!!!!! Tercer ajuste (termino PH) !!!!!! Calcula la mejor recta que se ajusta a esta distribucioncall ajusta_recta(matriz(:,6), matriz(:,5), m(1), b(1), correlacion(1))write(*,'(A,3F14.6)') " No alin. horiz.: m, b y corr=", m(1), b(1), correlacion(1)
! Igual. Dejamos que el usuario decidawrite(*,'(/a)', advance = "no") "Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores usando la recta encontradaarreglo%dDec = arreglo%dDec-( m(1)*matriz(:,6) + b(1) );PH = m(1)DI = DI + b(1)
endif
! En la columna 7 de la matriz pone los errores para ser graficados despues matriz(:,7) = arreglo%dDec
! Aqui los datos estan acomodados como sigue:! Col 1 | 2 | 3 | 4 | 5 | 6 | 7 !! --------------------------------------------------------------!! dDec | FT | dDec_FT | PV_FY | dDec_PV_FY | PH | dDec_PH !
call guarda_lineas("prov.txt", matriz)
call prepara_archivo_de_grafica()call agrega_grafica(2,1,'"FT"', '"dDec"', 0, 1,'"Flexiones del tubo"', "prov.txt")call agrega_grafica(4,3,'"PV+FY"', '"dDec"', 1, 1,'"Flex. yugo + No alin. vert."', "prov.txt")call agrega_grafica(6,5,'"PH"', '"dDec"', 0, 0,'"No alin. horiz."', "prov.txt")call agrega_grafica(2,7,'"FT"', '"dDec"', 1, 0,'"Errores corregidos vs. FT"', "prov.txt")call inicia_grafica()
tam = size(matriz(:,7))do kk = 1, tam
if( matriz(kk,7) < -30) thenwrite(*,*) "El valor es: ",matriz(kk,7), "con kk = ", k
endifenddo
end subroutine encuentra_coeficientes_dec
!***************************************************!! Como en el caso de Declinacion, esta subrutina se encarga de hacer los calculos necesarios para! encontrar los coeficientes del modelo de correccion correspondientes al Angulo Horario. Tambien! solicita al usuario la confirmacion de las correcciones, para que sea el usuario el que decida! si se hacen las correcciones o no.!subroutine encuentra_coeficientes_ah()
real :: media_mas, media_menosinteger :: cuantos_masinteger :: cuantos_menos
media = 0.0cuantos_mas = 0cuantos_menos = 0
media_mas = sum(arreglo%dAH, mask = arreglo%AH > 0)media_menos = sum(arreglo%dAH, mask = arreglo%AH <= 0)cuantos_mas = count(arreglo%AH > 0)cuantos_menos = count(arreglo%AH <= 0)media_mas = media_mas/cuantos_masmedia_menos = media_menos/cuantos_menos
! Pone en la primera columna los errores en AH antes de ninguna correccionmatriz(:,1) = arreglo%dAH
! Pone en la columna 9 AH para graficar despuesmatriz(:,9) = arreglo%AH
! Pregunta si aplica la correccionwrite(*,'(/a,F6.1,/a)', advance = "no") "Encontre un error de backlash de ", media_mas-media_menos, &
"Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores restando el backlash a los del lado positivowhere(arreglo%AH > 0) arreglo%dAH = arreglo%dAH - (media_mas - media_menos)BL = (media_mas - media_menos)
endif
! Ahora corrige con los coeficientes que ya conocearreglo%dAH = arreglo%dAH - FT*cosphi*sin(arreglo%AH*horas_rad)*sin(arreglo%Dec*gra_rad)arreglo%dAH = arreglo%dAH + PH*cos(arreglo%AH*horas_rad)*tan(arreglo%Dec*gra_rad)
! Pone en la segunda columna los errores en AH despues de las correcciones conocidas
matriz(:,2) = arreglo%dAH
! En la tercera columna pone el termino de falta de alineacion verticalmatriz(:,3) = tan(arreglo%Dec*gra_rad)*sin(arreglo%AH*horas_rad);! Limita los valores pues la tangente puede hacerse muy grandewhere(matriz(:,3) > 1000) matriz(:,3) = 1000where(matriz(:,3) < -1000) matriz(:,3) = -1000
! Calcula la mejor recta que se ajusta a esta distribucioncall ajusta_recta(matriz(:,3), matriz(:,2), m(1), b(1), correlacion(1))write(*,'(A,3F14.6)') " No alineacion vertical: m, b y corr=", m(1), b(1), correlacion(1)
! Pregunta si aplica la correccionwrite(*,'(/a)', advance = "no") "Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores usando la recta encontradaarreglo%dAH = arreglo%dAH-( m(1)*matriz(:,3) + b(1) );PV = m(1)HI = HI + b(1)
endif
! En la cuarta columna pone los errores con la correccion anteriormatriz(:,4) = arreglo%dAH
! En la quinta columna pone el termino de falta de perpendicularidadmatriz(:,5) = tan(arreglo%Dec*gra_rad);! Tambien limitamos los valores de la tangentewhere(matriz(:,5) > 1000) matriz(:,5) = 1000where(matriz(:,5) < -1000) matriz(:,5) = -1000
! Calcula la mejor recta que se ajusta a esta distribucioncall ajusta_recta(matriz(:,5), matriz(:,4), m(1), b(1), correlacion(1))write(*,'(A,3F14.6)') " No perpendicularidad: m, b y corr=", m(1), b(1), correlacion(1)
! Pregunta si aplica la correccionwrite(*,'(/a)', advance = "no") "Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores usando la recta encontradaarreglo%dAH = arreglo%dAH-( m(1)*matriz(:,5) + b(1) );NP = m(1)HI = HI + b(1)
endif
! En la columna 6 pone los errores con la correccion anteriormatriz(:,6) = arreglo%dAH
! En la columna 7 pone el termino de falta de colimacionmatriz(:,7) = 1.0/cos(arreglo%Dec*gra_rad);where(matriz(:,7) > 1000) matriz(:,7) = 1000where(matriz(:,7) < -1000) matriz(:,7) = -1000
! Calcula la mejor recta que se ajusta a esta distribucioncall ajusta_recta(matriz(:,7), matriz(:,6), m(1), b(1), correlacion(1))write(*,'(A,3F14.6)') " Colimacion: m, b y corr=", m(1), b(1), correlacion(1)
! Pregunta si aplica la correccionwrite(*,'(/a)', advance = "no") "Aplico esta correccion (s,n)? "read(*,*) respif(resp == "s") then
! Corrige los errores usando la recta encontradaarreglo%dAH = arreglo%dAH-( m(1)*matriz(:,7) + b(1) )CO = m(1)HI = HI + b(1)
endif
! En la columna 8 pone los errores con todas las correccionesmatriz(:,8) = arreglo%dAH
! Aqui los datos estan acomodados como sigue:! Col 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 !! ---------------------------------------------------------------------------!! dAH | dAH_ | PV | dAH_PV | NP | dAH_PV_NP | CO | dAH_PV_NP_CO | AH !call guarda_lineas("prov_ah.txt", matriz)
call prepara_archivo_de_grafica()call agrega_grafica(9,1,'"AH"', '"dAH"', 0, 1,'"Errores iniciales"', "prov_ah.txt")call agrega_grafica(3,2,'"PV"', '"dAH"', 1, 1,'"Alineacion vertical"', "prov_ah.txt")call agrega_grafica(5,4,'"NP"', '"dAH"', 0, 0,'"Falta de perpendicularidad"', "prov_ah.txt")call agrega_grafica(7,6,'"CO"', '"dAH"', 1, 0,'"Falta de colimacion"', "prov_ah.txt")call inicia_grafica()
end subroutine encuentra_coeficientes_ah
end module utilerias
!*************************************************************!! Empieza el programa !!*************************************************************!
Program calcula_modelo! Trate de poner lo mas posible en subrutinas en el modulo a fin de hacer el programa! mas compacto.
use utilerias ! En este modulo estan las subrutinas
implicit none
character(len=40) :: archivo ! Para el nombre del archivo que! contiene los datos
integer :: n_lineas ! Numero de lineas en el archivo
real :: rmsdec, rmsah, rmsdec_ant, rmsah_ant, dummy
! Primero pide al usuario el nombre del archivo con los datos
write(unit=*, fmt='(a)', advance="no") "Teclea el nombre del archivo con los datos: "read(*,*) archivo
! Pide al usuario la latitude del observatorio y verifica que sea un numero razonabledo
write(unit=*, fmt='(/a,f4.1,a)', advance="no") "Dame la latitud del observatorio en grados (", phi/gra_rad, "): "read(*,*) dummyif(dummy > -80.0 .and. dummy < 80.0) exit
enddo
phi = dummy*gra_rad ! la convierte en radianessenphi = sin(phi) ! Esto es el seno de la latitudcosphi = cos(phi) ! Esto es el coseno de la latitud
! Luego calcula el numero de renglones del archivo para! definir los arreglos
n_lineas = cuantas_lineas(archivo) ! Verifica que exista y revisa cuantas lineas! con datos tiene
print*, "Hay", n_lineas, "lineas validas"
! Si no hay lineas validas, termina el proceso
if(n_lineas == 0) return
allocate(arreglo(n_lineas)) ! Acomoda el arreglo de n_lineasallocate(matriz(n_lineas,9)) ! Acomoda la matriz donde pondra
! los datos a graficar
call trae_lineas(archivo, arreglo) ! Trae todos los datos y los pone en 'arreglo'
! Luego verifica que AH este entre -12 y 12where(arreglo%AH > 12.0) arreglo%AH = arreglo%AH-24.0;
call grafica_errores('"Errores iniciales"', rmsdec_ant, rmsah_ant)
! Aqui llama a una subrutina que calcula los coeficientes de correccion para la! Declinacioncall encuentra_coeficientes_dec()
! Luego llama a otra subrutina para calcular los coeficientes de correccion para! el Angulo Horariocall encuentra_coeficientes_ah()
call grafica_errores('"Errores finales"', rmsdec, rmsah)
! Muestra los coeficientes calculadoswrite(*,'(/A)') "Los coeficientes calculados son:"write(*,'(/A,F8.3)') " (Alineacion horizontal) - PH: ", PHwrite(*,'(A,F8.3)') " (Alineacion vertical) - PV: ", PVwrite(*,'(A,F8.3)') " (Flexion del tubo) - FT: ", FTwrite(*,'(A,F8.3)') " (Flexion del yugo) - FY: ", PV_FY - PVwrite(*,'(A,F8.3)') "(Falta de perpendicularidad) - NP: ", NPwrite(*,'(A,F8.3)') " (Error de colimacion) - CO: ", COwrite(*,'(A,F8.3)') " (Backlash en AH) - BL: ", BLwrite(*,'(A,F8.3)') " (Offset en AH) - HI: ", HIwrite(*,'(A,F8.3)') " (Offset en Dec) - DI: ", DI
write(*,'(/A)') "Con esta correccion se han bajado del errores RMS como sigue:"write(*,'(A,F5.1,A,F5.1,A)') " AH: de ", rmsah_ant, " a ", rmsah, " (arcsec)"write(*,'(A,F5.1,A,F5.1,A)') "Dec: de ", rmsdec_ant, " a ", rmsdec, " (arcsec)"
! Pregunta si cerramos los graficoswrite(*,'(/a)', advance = "no") "Cierro los graficos (s,n)? "
read(*,*) resp
if(resp == "s") thencall system("killall gnuplot_x11")! Cierra todas las ventanas con gnuplot
endif
deallocate(arreglo)deallocate(matriz)
End Program calcula_modelo
!************************************************************************
Apéndice B. Listado del programa en IDLFUNCTION rms, vector media = mean(vector) va = vector - media return, sqrt(mean(va*va))END
PRO encuentra_modelo, ARCHIVO=archivo, LATITUD=latitud, CORRIGE=corrige;**********************************************************************************; Programa 'encuentra_modelo.pro' elaborado por Leonel Gutierrez .;; Este programa lee un archivo con una serie de datos que muestran ; los errores de apuntado de un telescopio con montura ecuatorial ; y calcula los coeficientes de un modelo trigonometrico para corregir ; dicho apuntado.;**********************************************************************************
; sintaxis: ENCUENTRA_MODELO, archivo="epos.txt", latitud=19.5, corrige=[1,1,1,0,1,0,1]
if (NOT keyword_set(ARCHIVO)) then archivo="epos.txt"if (NOT keyword_set(LATITUD)) then latitud=19.5if (NOT keyword_set(CORRIGE)) then begin corrigePH=1 corrigePV=1 corrigeFT=1 corrigePV_FY=1 corrigeNP=1 corrigeCO=1 corrigeBL=1endif else begin if n_elements(corrige) ne 7 then begin print, "Corrige debe tener 7 elementos en el orden [PH,PV,FT,PV_FY,NP,CO,BL]." print, "Poner 1 en la correccion que se desea y 0 en la que no." return endif corrigePH=corrige(0) corrigePV=corrige(1)
corrigeFT=corrige(2) corrigePV_FY=corrige(3) corrigeNP=corrige(4) corrigeCO=corrige(5) corrigeBL=corrige(6) endelse
;Trae los datos del archivo readcol,archivo,f='(f,f,f,f)', ah, dah, dec, ddec
; Inicia una ventana para desplegar las graficaswindow, 1, xsi=300,ysi=300,retain=2, title="Errores iniciales"white = !D.N_COLORS-1!P.color = 0!p.background = white; Desplegara solo una grafica!p.multi = [0,1,1,0,0]sx = "dDec (rms=" +string(rms(dDec),f='(f6.2)') + ")"sy = "dAH (rms=" +string(rms(dAH),f='(f6.2)') + ")"plot,ddec,dah,psym=4,symsize=0.5,xtitle=sx, ytitle=sy
print, "rms de dAH y dDec (antes): ", rms(dAH), rms(dDec); Mi definicion de PIpi=acos(-1)
; Pone la latitud y calculas el seno y el cosenophi=latitudsenphi = sin(phi*pi/180.0)cosphi = cos(phi*pi/180.0)
; Inicia otra ventana para desplegar el proceso de correccion en declinacionwindow, 2, xsi=600,ysi=600,retain=2, title="Correcciones en declinacion"; Desplegara 4 graficas!p.multi = [0,2,2,0,0]
; Para calcular el termino correspondiente a las flexiones del tubo term1 = -senphi*cos(dec*pi/180.0) + cosphi*sin(dec*pi/180.0)*cos(ah*15*pi/180.0)
; Grafica los erroresplot,term1,ddec,psym=4,symsize=0.5,xtitle='FT', ytitle='dDec'xyouts, 120,260+300,"Flexiones del tubo", /device; Ajusta una recta y calcula FTparams = fltarr(2)
params = linfit(term1,ddec)DI = params(0)
FT = 0.0if corrigeFT then begin FT = params(1) ; Corrige los errores ddec = ddec - (FT*term1 + DI)endif
; Para corregir las flexiones del yugo y la falta de alineacion verticalterm2 = cos(ah*15*pi/180.0)plot, term2,ddec,psym=4,symsize=0.5,xtitle='PV+FY', ytitle='dDec'xyouts, 120+300,260+300,"Flex. yugo + alin. vert.", /device
; Ajusta una recta y calcula PV_FYparams = linfit(term2,ddec)DI = params(0) + DI
PV_FY = 0.0if (corrigePV_FY) then begin PV_FY = params(1) ; Corrige los errores ddec = ddec-(PV_FY*term2 + params(0))endif
; Para corregir la falta de alineacion horizontalterm3 = sin(ah*15*pi/180.0)plot, term3,ddec,psym=4,symsize=0.5,xtitle='PH', ytitle='dDec'xyouts, 120,260,"Alin. horizontal", /device
; Ajusta una recta y calcula FTparams = linfit(term3,ddec)DI = params(0) + DI
PH = 0.0if (corrigePH) then begin PH = params(1) ; Corrige los errores ddec = ddec-(PH*term3 + params(0))endif
; Grafica los errores en declinacion una vez corregidos
plot,term1,ddec,psym=4,symsize=0.5,xtitle='FT', ytitle='dDec'xyouts, 120+300,260,"Errores corregidos en Dec", /device
; Inicia otra ventana para desplegar el proceso de correccion en AHwindow, 3, xsi=600,ysi=600,retain=2, title="Correcciones en AH"
; Grafica los erroresplot,AH,dAH,psym=4,symsize=0.5,xtitle='AH', ytitle='dAH'xyouts, 120,260+300,"Errores iniciales", /device
; Para calcular el Backlash, calcula la media de los errores donde AH > 0crit = where(ah>0)mediamas = mean(dAh(crit))
; Luego calcula la media del lado negativocrit1 = where(ah<0)mediamenos = mean(dAh(crit1))
; Calcula el backlashBL = mediamas - mediamenos
if (corrigeBL) then begin ; Lo resta a los del lado positivo dah(crit) = dah(crit) - BLendif
; Corrige los errores en AH con los terminos que ya se conocendah=dah-FT*cosphi*sin(ah*15*pi/180.0)*sin(dec*pi/180.0)dah = dah + PH*cos(ah*15*pi/180.0)*tan(dec*pi/180.0)
; Para corregir por falta de alineacion verticalterm4 = sin(ah*15*pi/180.0)*tan(dec*pi/180.0)plot, term4,dah,psym=4, symsize=0.5,xtitle='PV', ytitle='dDec'xyouts, 120+300,260+300,"Alineacion vertical", /device
; Ajusta una recta y calcula PVparams = linfit(term4,dAH)HI = params(0)
PV = 0.0if (corrigePV) then begin PV = params(1)
; Corrige los errores dAH = dAH-(PV*term4 + params(0))endif
; Para corregir por perpendicularidadterm5 = tan(dec*pi/180.0)plot, term5,dah,psym=4, symsize=0.5,xtitle='NP', ytitle='dDec'xyouts, 120,260,"Perpendicularidad", /device
; Ajusta una recta y calcula NPparams = linfit(term5,dAH)HI = HI + params(0)
NP = 0.0if (corrigeNP) then begin NP = params(1) ; Corrige los errores dAH = dAH-(NP*term5 + params(0))endif
; Para corregir por falta de colimacionterm6 = 1.0/cos(dec*pi/180.0)plot, term6,dah,psym=4, symsize=0.5,xtitle='CO', ytitle='dDec'xyouts, 120+300,260,"Falta de colimacion", /device
; Ajusta una recta y calcula COparams = linfit(term6,dAH)HI = HI + params(0)
CO = 0.0if (corrigeCO) then begin CO = params(1) ; Corrige los errores dAH = dAH-(CO*term6 + params(0))endif
; Inicia otra ventana para desplegar la grafica finalwindow, 4, xsi=300,ysi=300,retain=2, title="Errores corregidos"
; Desplegara solo una grafica!p.multi = [0,1,1,0,0]sx = "dDec (rms=" +string(rms(dDec),f='(f6.2)') + ")"sy = "dAH (rms=" +string(rms(dAH),f='(f6.2)') + ")"
plot,ddec,dah,psym=4,symsize=0.5,xtitle=sx, ytitle=sy
print, " (Alineacion horizontal) - PH: ", PHprint, " (Alineacion vertical) - PV: ", PVprint, " (Flexiones del tubo) - FT: ", FTprint, " (Flexiones del yugo) - FY: ", PV_FY - PVprint, "(Falta de perpendicularidad) - NP: ", NPprint, " (Error de colimacion) - CO: ", COprint, " (Backlash en AH) - BL: ", BLprint, " (Offset en AH) - HI: ", HIprint, " (Offset en Dec) - DI: ", DI
print, "rms de dAH y dDec (despues): ", rms(dAH), rms(dDec)
END
Top Related