Você está na página 1de 22

Machine Translated by Google

capítulo 5
Análise de dados astronômicos

Resumo A astronomia e a astrofísica são campos de pesquisa altamente orientados por dados:
hipóteses são construídas sobre dados existentes, modelos são usados para fazer previsões e
discrepâncias entre teoria e observação impulsionam o progresso científico, forçando-nos a modificar
modelos existentes ou apresentar novas soluções. Neste capítulo, discutimos técnicas para analisar
uma variedade de dados, desde espectros estelares individuais e curvas de luz até grandes
levantamentos, como GAIA. Naturalmente, a entrada e a saída de arquivos são um pré-requisito
importante para o processamento de dados. Concluímos com uma breve introdução às redes neurais
convolucionais e sua aplicação a dados de imagem e espectros.

5.1 Análise Espectral

No Cap. 3, discutimos como as estrelas podem ser classificadas por propriedades espectrais. Os
espectrógrafos modernos podem produzir espectros com alta resolução de comprimento de onda, o
que permite a análise detalhada das linhas de absorção. Como exemplo, o material online para este
livro (uhh.de/phy-hs-pybook) inclui um espectro óptico da estrela ÿ Persei obtido com o Ultraviolet and
Visual Echelle Spectrograph (UVES) do ESO. O espectro é armazenado no formato de arquivo FITS,
que pode ser considerado um padrão de fato para dados astronômicos. Ao contrário dos formatos
baseados em texto simples (ASCII), os arquivos FITS são binários, o que reduz a sobrecarga
operacional durante os processos de leitura e gravação.
Além disso, cada arquivo FITS contém um cabeçalho com uma descrição detalhada dos dados e seu
formato. Esta informação é chamada de metadados.
Graças à biblioteca Astropy, os arquivos FITS podem ser acessados com apenas algumas linhas de
código. Ferramentas para lidar com arquivos FITS são fornecidas pelo módulo astropy.io:

1 da importação astropy.io se encaixa 2 import


matplotlib.pyplot as plt 3 import numpy as np

Após especificar o caminho e o nome do arquivo FITS, podemos carregar seu conteúdo com a função
open() e exibir algumas propriedades básicas:

© Springer Nature Switzerland AG 2021 185


W. Schmidt e M. Völschow, Python Numérico em Astronomia e Astrofísica, Notas de
Palestra de Graduação em Física, https://doi.org/10.1007/978-3-030-70347-9_5
Machine Translated by Google

186 5 Análise de Dados Astronômicos

4 arquivo = "data_files/ADP.2014-10-29T09_42_08.747.fits"
5 fit_data = fit.open(arquivo)
6 fit_data.info()

Este código solicita os metadados do arquivo (última linha abreviada):

Nome do arquivo: ADP.2014-10-29T09_42_08.747.fits


Não. Nome Ver Modelo Formato das dimensões dos cartões
0 PRIMÁRIO 1 HDU Primário 788 ()
1 ESPECTRO 1 BinTableHDU 71 1R x 6C [134944D, 134944E, ..., 134944E]

Na tabela, estão listadas as HDUs (Header Data Units) do arquivo. O segundo HD


contém o espectro completo, que é tabulado em seis colunas. Para um mais detalhado
descrição das colunas, por exemplo, as unidades físicas das quantidades,
pode executar o comando print(fits_data[1].columns) , levando ao
seguinte saída:

ColDefs(
nome = 'ONDA'; formato = '134944D'; unidade = 'Angstrom'
nome = 'FLUX_REDUCED'; formato = '134944E'; unidade = 'adu'
nome = 'ERR_REDUCED'; formato = '134944E'; unidade = 'adu'
nome = 'BGFLUX_REDUCED'; formato = '134944E'; unidade = 'adu'
nome = 'FLUXO'; formato = '134944E'; unidade = '10ˆ-16 erg/cmˆ2/s/Angstrom'
nome = 'ERR'; formato = '134944E'; unidade = '10ˆ-16 erg/cmˆ2/s/Angstrom'
)

Especificamente, estamos interessados nas colunas 0 e 4, ou seja, o comprimento de onda e o fluxo.


Todo o espectro é acessível via fit_data[1]. Para trabalhar com os dados,
primeiro extraia o espectro completo e despeje-o em um novo array, após o qual o arquivo FITS
pode ser fechado:

7 scidata = fit_data[1].data
8 fit_data.close()

É importante que o scidata tenha um tipo específico de FITS que seja herdado de numpy.
Você pode verificar com type() e isinstance(), conforme descrito na Seção. 2.1.3.
Formalmente, scidata é definido como um array com apenas uma linha e seis colunas. Por
para facilitar a referência, extraímos as colunas desejadas e as copiamos
em matrizes NumPy unidimensionais:

9 comprimento de onda = scidata[0][0]


10 fluxo = scidata[0][4]

Como não exigimos valores absolutos de fluxo espectral, normalizamos o espectro por
dividindo pelo valor de pico. Moveover, convertemos comprimentos de onda de Angstrom
para nanômetros:

11 norma = np.max(fluxo)
12 fluxo = fluxo/norma
13 comprimento de onda = comprimento de onda*0,1

Agora estamos preparados para exibir os dados. O código


Machine Translated by Google

5.1 Análise Espectral 187

Fig. 5.1 Linhas de absorção de hélio e sódio no espectro de ÿ Persei

14 %matplotlib inline 15 16
plt.plot(wavelength, flux,
linestyle='-' , color='navy') 17 plt.xlabel("$\lambda$ / nm") 18 plt.ylabel("Flux / ADU" ) 19
plt.xlim(587.590) 20 21 plt.savefig("spectrum_full.pdf")

produz Fig. 5.1. O gráfico mostra o espectro de ÿ Persei na faixa de comprimento de onda
de 587 a 590 nm. Pode-se ver dois tipos muito distintos de características de absorção.
Como ÿ Persei é uma supergigante do tipo B com uma temperatura efetiva de 20 800 K,
linhas de absorção de hélio como a linha larga em 587,6 nm podem ser vistas. No entanto,
observadores notaram já no início do século 20 que estrelas distantes tendem a mostrar
características inesperadas em seus espectros que provavelmente não se originam de
uma fotosfera estelar. Isso levou à descoberta da matéria entre as estrelas, o chamado
meio interestelar (ISM). Um exemplo são as duas linhas estreitas em 589,0 e 589,6 nm,
que se originam do sódio no ISM. Essas linhas foram descobertas em estrelas binárias
espectroscópicas por Mary L. Heger em 1919. Ela percebeu que sua largura estava em
desacordo com a ampla aparência de outras linhas de absorção no espectro estelar. Você
pode explorar melhor essas linhas e o espectro de ÿ Persei nos exercícios a seguir.
Exercícios

5.1 Investigue o espectro de ÿ Persei na faixa de comprimento de onda de 480 a 660 nm.
Use plt.axvline() para marcar as linhas de absorção de Balmer Hÿ e Hÿ em comprimentos
de onda 656,3 e 486,1 nm, respectivamente, por linhas verticais tracejadas (veja a
documentação online do Matplotlib e a próxima seção para exemplos). Você pode rotular
as linhas com a ajuda de plt.text(). Além das linhas Balmer, procure identificar a absorção
Machine Translated by Google

188 5 Análise de Dados Astronômicos

linhas de ção de He I nos comprimentos de onda 471,3, 492,1, 501,6, 504,7, 587,6 e 667,8 nm
e marque-as com linhas tracejadas em uma cor diferente.

5.2 Elabore um algoritmo para estimar a largura total na metade do máximo, ÿ1/2, das linhas
de absorção de hélio e sódio na Fig. 5.1. ÿ1/2 mede a largura de uma linha espectral na metade
de sua profundidade [4, Sec. 9.5]. Assumindo que o alargamento da linha é causado pelo
alargamento Doppler térmico, temos

2ÿ 2kT log 2
ÿ1/2 = ,
c m

onde k é a constante de Boltzmann, c a velocidade da luz e m a massa dos átomos.


Como ambas as atmosferas estelares e o ISM são compostos principalmente de hidrogênio,
você pode assumir m ÿ mH. Quais temperaturas estão implícitas em suas estimativas de ÿ1/2
e o que seus resultados sugerem sobre a origem das linhas de sódio?

5.2 Curvas de Luz de Trânsito

As últimas três décadas viram uma revolução dramática em nossa compreensão dos sistemas
planetários e, graças aos limiares instrumentais cada vez menores, a detecção de sistemas
exoplanetários tornou-se rotina diária. No outono de 2020, cerca de 4.300 exoplanetas
confirmados em mais de 3.000 sistemas estelares foram encontrados, incluindo planetas em
torno de estrelas binárias ou mesmo terciárias . proximidade de uma estrela. No diagrama de
dispersão mostrado na Fig. 5.2, os Júpiteres quentes são encontrados na região superior
esquerda (pequeno eixo maior e grande massa; veja também o Exercício 2.9).

A maioria dos sistemas planetários confirmados foram detectados através de trânsitos


planetários ou variações periódicas da velocidade radial de uma estrela. A seguir, vamos nos
concentrar no método de trânsito. Quando o plano orbital de um exoplaneta está quase
alinhado com a linha de visão da Terra, o exoplaneta passa entre nós e sua estrela hospedeira,
fazendo com que bloqueie uma fração da luz emitida pela estrela e reduzindo o fluxo medido
(veja Fig. 5.3).
Assumindo um brilho de superfície uniforme e dado o raio estelar e planetário
RS e RP, respectivamente, a fração de luz bloqueada pode ser estimada via

2
F 4ÿ R2P PR
= = . (5.1)
F 4ÿ R2S RS

Para um planeta joviano orbitando uma estrela do tipo solar, temos RP/RS ÿ 0,1, o que implica
que apenas 1% da luz da estrela será bloqueada pelo planeta. As coisas ficam ainda piores para
um planeta parecido com a Terra onde temos RP/RS ÿ 0,01, ou seja, apenas 0,01% de luz bloqueada.

1Recurso para dados atuais são exoplanets.nasa.gov e www.exoplanet.eu.


Machine Translated by Google

5.2 Curvas de Luz de Trânsito 189

Fig. 5.2 Distribuição de massas de exoplanetas (confirmadas) em função do semi-eixo maior da órbita
(Diagrama gerado com o site interativo www.exoplanet.eu/diagrams)

Fig. 5.3 Ilustração de um trânsito de exoplanetas (Crédito da imagem: Hans Deeg, commons.wikimedia.org)

Embora a detecção de planetas terrestres exija grandes telescópios e condições atmosféricas


excepcionais, que só são alcançadas nos níveis astronômicos atuais,
instalações, os sistemas de Júpiter quente são rotineiramente detectados por telescópios menores com
visão limitada.
Machine Translated by Google

190 5 Análise de Dados Astronômicos

Nos recursos on-line, fornecemos uma curva de luz do sistema TrES-2 tomada pelo
1,2 m Oskar-Lühning-Teleskop em Hamburgo em junho de 2013.2 O arquivo ASCII
tres2_data.dat contém três colunas, a saber, a data Juliana modificada MJD,3 a fluxo
relativo e o erro de fluxo. Uma curva de luz é o registro dependente do tempo do fluxo
incidente recebido de um objeto. Primeiro, carregaremos os dados usando a função
loadtxt() do NumPy e, em seguida, dividiremos as colunas em matrizes separadas:

1 importação numpy como np


2
3 dados = np.loadtxt("tres2_data.dat")
4
5 mjd = dados[:,0] 6 fluxo =
dados[:,1] 7 err = dados[:,2]

Podemos usar errorbar() do pyplot para traçar os pontos de dados com barras de erro
indicando o erro da medição:
8 import matplotlib.pyplot como plt 9 %matplotlib
inline 10 11 plt.errorbar(mjd, flux, yerr=err,
ecolor='steelblue', 12

linestyle='none', marker='o', color='navy')


13 plt.xlabel("MJD") 14
plt.ylabel("Flux / ADU") 15 16
plt.savefig("tres2_lightcurve.pdf")

Isso nos dá a Fig. 5.4. Podemos ver claramente uma queda na curva de luz que abrange
cerca de 100 min (a data juliana está em unidades de dias), que é causada pelo objeto
conhecido como TrES-2b ou Kepler-1b.4 No entanto, a natureza refrativa da Terra atmosfera
em combinação com flutuações de temperatura e movimentos turbulentos causa um
significativo jitter e dispersão nos dados com os quais temos que lidar.
Para análise científica, seria preciso ajustar modelos de trânsito complexos aos dados.
Aqui, identificaremos propriedades básicas por meio de inspeção visual e cálculos
elementares. Em primeiro lugar, estimamos o início do trânsito, quando o exoplaneta
apenas começa a se mover sobre a borda do disco estelar (ingresso), e o final, quando
ele se move para fora do disco (egresso)5:

2Nome em homenagem a Oskar Lühning, que foi morto quando jovem na Segunda Guerra Mundial antes que pudesse
ver seu desejo de estudar astrofísica se tornar realidade. O telescópio foi financiado por uma doação do pai de Oskar
em memória de seu filho.
3A data juliana com os dois primeiros dígitos removidos; veja também Seção. 3.3.
4Ele foi originalmente descoberto em 2006. A convenção de nomenclatura para exoplanetas é adicionar uma letra
minúscula ao nome do sistema estelar, que geralmente é derivado de uma campanha observacional. A letra 'b' indica
o primeiro exoplaneta detectado no sistema.
5O intervalo de tempo [T1, T4] cobre toda a extensão do trânsito, enquanto [T2, T3] é o período em que o
exoplaneta está inteiramente dentro do disco estelar.
Machine Translated by Google

5.2 Curvas de Luz de Trânsito 191

Fig. 5.4 Curva de luz de um trânsito de TrES-2b observado de Hamburgo em 6 de julho de 2013

17 T1 = 5,645e4 + 0,445 18 T4 = 5,645e4


+ 0,520

Podemos usar esses tempos para calcular um fator de normalização de todos os valores de
fluxo fora do trânsito. O NumPy nos permite realizar essa tarefa sem esforço selecionando
valores de matriz de fluxo com base em uma condição como mjd<T1 (indexação condicional):

19 norma1 = np.mean(flux[mjd<T1]) # antes do trânsito 20 norma2 = np.mean(flux[mjd>T4])


# após trânsito 21 norma = 0,5*(norm1+norm2)

22
23 print(f" Fator de normalização de fluxo: {norm:.3f}")
24
25 # normaliza fluxos
26 fluxo /= norma 27 err /=
norma

Nas duas últimas linhas, tanto o fluxo quanto o erro de fluxo são normalizados por

Fator de normalização de fluxo: 1,509

Para determinar a profundidade de trânsito, que por sua vez nos permite calcular o tamanho do
exoplaneta, precisamos encontrar um valor estatístico do fluxo mínimo, apesar das flutuações nas
medições. Um método relativamente simples para suavizar a curva de luz é uma média móvel. Vamos
denotar a i- ésima medida do fluxo na série temporal por Fi . Podemos suavizar o fluxo calculando a
média sobre um determinado número, N, de pontos de dados vizinhos:
Machine Translated by Google

192 5 Análise de Dados Astronômicos

1 N/2
F(n) = Fi+n (5.2)
eu

N+1
n=ÿN/ 2

Com o aumento de i, a janela sobre a qual a média é obtida desliza ao longo da curva de
luz.6 Isso é prontamente implementado por meio de fatiamento de matriz:
28 # largura e deslocamento da janela de amostra
29 deslocamento = 7
30 largura = 2*deslocamento + 1
31
32 # calcula a média móvel 33 flux_smoothed
= np.ones(flux.size - width + 1) 34 for i,val in enumerate(flux_smoothed):
flux_smoothed[i] = np.sum(flux[i:i+width])/ largura
35
36
37 flux_min = np.min(flux_smoothed) 38 print(f"Fluxo
mínimo: {flux_min:.3f}")

As variáveis offset e largura correspondem a N/2 e N + 1 na Eq. (5.2). Em nosso exemplo,


temos N = 15, ou seja, cada valor suavizado é uma média de 15 pontos de dados. O mínimo
do fluxo suavizado será usado abaixo:

Fluxo mínimo: 0,985

Vamos traçar agora a curva de luz suavizada no topo do ponto de dados:


39 plt.errorbar(mjd, fluxo, yerr=err, ecolor='steelblue', 40 41
linestyle='none', marker='o', color='navy', zorder=1) 42
plt.xlim(np.min(mjd), np.max(mjd)) 43 plt.xlabel("MJD") 44
plt.ylabel("rel. flux") 45 46 # smoothed flux 47 plt.plot(mjd[offset:-offset], flux_smoothed,
48 lw=2, color='orange', zorder=2)

49 50 # entrada, saída e fluxo mínimo 51 plt.axvline(T1,


color='crimson', lw=1, linestyle=':') 52 plt.axvline(T4, color='crimson', lw=1, linestyle=':')
53 plt.axhline(flux_min, lw=1, linestyle='--', color='black') 54

55 plt.savefig("tres2_lightcurve_smooth.pdf")

O resultado pode ser visto na Fig. 5.5. O array flux_smoothed é plotado na linha 47. Devemos
levar em conta que este array tem menos elementos e seu índice tem um

6Esta é uma variante da média móvel simples (SMA), que calcula uma média de N medições anteriores.
Em geral, as médias móveis são definidas por convolução sobre uma função de janela de largura e
forma prescritas.
Machine Translated by Google

5.2 Curvas de Luz de Trânsito 193

Fig. 5.5 Curva de luz suavizada calculada a partir dos pontos de dados plotados na Fig. 5.4. As linhas pontilhadas
verticais indicam a duração do trânsito e a linha tracejada horizontal a redução máxima do fluxo da estrela

deslocamento de N/2 em comparação com a matriz de dados original. Por esta razão,
precisamos pegar a fatia mjd[offset:-offset] da matriz de tempo. O argumento de palavra-
chave zorder nas linhas 41 e 48 traz a curva laranja no topo dos pontos de dados com
barras de erro. Nas linhas 51-52, o início da entrada, T1, e o final da saída, T4, são
marcados por linhas verticais. Além disso, o fluxo mínimo calculado acima é mostrado
como uma linha tracejada horizontal. Nosso resultado, F/F ÿ 1 ÿ 0,985 = 0,015, nos
permite calcular a razão do raio estrela-planeta. Da Eq. (5.1), segue que RP/RS ÿ 0,12,
o que é típico para um planeta joviano orbitando uma estrela parecida com o Sol.
Como a duração do trânsito, Ttrans = T4 ÿ T1, depende da velocidade orbital e da
distância do exoplaneta à estrela, é possível derivar o tamanho do exoplaneta através
do raciocínio geométrico e da terceira lei de Kepler. Assumindo que o plano orbital está
exatamente alinhado com a linha de mira, ou seja, o exoplaneta transita pelo centro do
disco estelar, segue que

ÿ Ttrans
pecado = RS + PR
P uma

onde P é o período orbital e a o semi-eixo maior do exoplaneta. O período orbital também


é observável com o método de trânsito: é apenas o tempo entre dois trânsitos
subsequentes (P = 2,47063 d para TrES-2b). Como Ttrans/P é relativamente pequeno,
podemos aplicar a aproximação de pequeno ângulo. Reescrevendo a equação acima em
termos da deficiência de fluxo F/ F, a seguinte relação aproximada para o raio do planeta
é obtida:
ÿ1
ÿ Ttrans F
RP a 1+ (5.3)
P F
Machine Translated by Google

194 5 Análise de Dados Astronômicos

Desprezando a massa planetária, o semi-eixo maior a está relacionado ao período orbital


P por
1/3 P 2/3
=
uma
EM
(5.4)
1 UA M 365,25 d

A massa da estrela pode ser determinada independentemente: MS = 0,98 M , implicando a


= 0,0355 UA. Substituição de todos os parâmetros na Eq. (5.3) produz RP ÿ 0,8 RJup.
Utilizando um modelo mais preciso (ver Exercício 5.4), obtém-se RP ÿ 1,27 RJup .
Assim, podemos classificar o TrES-2b como um típico Júpiter quente.

Exercícios

5.3 A estimativa de F/F da curva de luz suavizada depende de várias escolhas. Além de T1
e T4, é principalmente a largura da média móvel, N, que determina o resultado. Para nossa
análise do trânsito TrES-2, esses parâmetros podem ser considerados como parâmetros de
ajuste . Para uma análise mais sistemática, escreva uma função Python que execute a linha
de código do formulário de cálculo 19 a 37 para determinados horários de início e término
do trânsito e largura da janela. A função deve retornar o suavizado
fluxo e seu mínimo.

(a) Varie os parâmetros de sintonia dentro de limites razoáveis e analise a sensibilidade de


F/ F. Aplique a lei da propagação do erro para estimar como isso afeta o raio do planeta
seguindo a Eq. (5.3). (b) A Figura 5.5 sugere um impacto relativamente forte de valores
discrepantes, como o valor de fluxo muito baixo próximo ao intervalo da transição. Você
consegue pensar em um critério para excluir valores discrepantes extremos dos dados?
Verifique se isso reduz a sensibilidade nos parâmetros de ajuste.

5.4 Se o plano orbital não estiver exatamente alinhado com a linha de visão, o modelo de
trânsito se torna mais complicado porque Ttrans também depende da inclinação i do sistema.
No caso geral, pode-se mostrar que

ÿ1
F
RP = a 1 ÿ sen i cos2ÿTtrans 1+ (5.5)
P F

A inclinação pode ser obtida a partir de uma análise detalhada das fases de entrada e saída
do trânsito. No caso do sistema TrES-2, foi determinado i = 83,6ÿ. Aplique o modelo
melhorado em combinação com a profundidade de trânsito resultante do Exercício 5.3 para
calcular RP.

5.3 Conjuntos de Dados de Pesquisa

Nas últimas décadas, grandes pesquisas de objetos astronômicos foram realizadas,


principalmente por telescópios espaciais. Por exemplo, o censo mais exaustivo da
Machine Translated by Google

5.3 Conjuntos de Dados de Pesquisa 195

A vizinhança solar galáctica é feita pela missão GAIA.7 As propriedades básicas de mais de um
bilhão de estrelas foram medidas com precisão, representando aproximadamente 1% de todas
as estrelas dentro de nossa galáxia. estrutura da Via Láctea.

Os dados da pesquisa podem ser acessados online através do arquivo GAIA.8 No menu de
pesquisa do arquivo, as consultas podem ser feitas enviando comandos ADQL na guia Avançado
(ADQL). O ADQL estende a linguagem do banco de dados SQL por meio de vários comandos e
rotinas numéricos que são comumente usados em astronomia. Uma consulta típica consiste em
três linhas selecionando colunas de dados de um catálogo específico e extraindo itens de dados
onde determinadas condições booleanas são atendidas:

SELECT l, b, parallax, parallax_over_error, radial_velocity, phot_g_mean_mag FROM gaiadr2.gaia_source WHERE


phot_g_mean_mag<12 AND ABS(radial_velocity)>0 AND parallax>=1.0 AND parallax_over_error>=10

Nesta consulta, escolhemos o catálogo de origem individual do GAIA Data Release 2. No


catálogo, selecionamos a longitude galáctica le latitude b, a paralaxe e seu erro relativo, a
velocidade radial ao longo da linha de visão e a média Magnitude da banda G como propriedades
estelares. O significado das coordenadas galácticas é explicado na Fig. 5.6. Na última linha,
aplicamos vários filtros. Primeiro, limitamos o número de objetos considerando apenas estrelas
mais brilhantes que a magnitude 12. Além disso, só permitimos objetos com valores válidos de
velocidade radial, paralaxe ÿ 1 mas (correspondendo a distâncias menores que 1 kpc) e erros de
paralaxe relativos menores que 10% em nossa amostra. Após processar nossa consulta, o
sistema informa que um total de 1.386.484 objetos foram selecionados do catálogo. Você mesmo
pode enviar essa consulta e baixar a amostra resultante. Recomendamos usar o formato CSV
(você pode escolher através do formato de download do menu suspenso). O tamanho é de cerca
de 130 MB, então isso pode demorar um pouco.

Depois de baixar o arquivo de dados, você pode carregar em um array NumPy:

1 import numpy como np 2


import matplotlib.pyplot como plt 3

4 data = np.loadtxt("gaia_12mag_1kpc-result.csv", 5 dtype='float64',


usecols=(0, 1, 2, 4),
6
7 delimitador=',', skiprows=1)

A seguir, usaremos apenas a longitude e latitude galáctica, a paralaxe e a velocidade radial. Por
esse motivo, apenas as colunas 0, 1, 2 e 4 são usadas.
Como o arquivo de dados começa com uma linha de comentário com um caractere # inicial,9 que

7Site da missão: sci.esa.int/web/gaia.


8Site do arquivo: gea.esac.esa.int/archive.
9Em computadores Linux ou Mac, você pode verificar isso facilmente no shell com a ajuda do comando
head.
Machine Translated by Google

196 5 Análise de Dados Astronômicos

Fig. 5.6 Ilustração do sistema


de coordenadas galácticas.
A longitude galáctica l é o
ângulo entre a linha de visão de
um objeto distante projetado no
plano médio galáctico (linha
sólida) e a direção de referência
do Sol ao centro da Via Láctea
(linha tracejada).

A latitude b é a distância angular


medida a partir do plano médio
galáctico

não pode ser interpretado como uma linha de números float por np.loadtext(), precisamos pular a
primeira linha. Isso é indicado pelo argumento de palavra-chave skiprows, que especifica o
número de linhas a serem ignoradas (não confundir com o índice da primeira linha, que é zero).
Além disso, np.loadtext() espera espaços em branco como delimitadores entre colunas por
padrão. Na tabela CVS, no entanto, as vírgulas são usadas.
Isso precisa ser especificado por delimitador=','.
Quais são as dimensões dos dados da matriz ?

8 print(data.shape)

impressões

(1386484, 3)

Embora tenhamos aplicado vários filtros, o conjunto de dados ainda é bastante grande, com
aproximadamente 1,4 milhão de linhas e 3 colunas. Os histogramas são um meio simples de
exibir propriedades estatísticas de tais amostras de dados. Para começar, vamos traçar a
distribuição das distâncias estelares. A distância pode ser calculada diretamente a partir da paralaxe medida ÿ:

d 1
= (5.6)
1 peça ÿ

Como temos paralaxes em microarcsegundos (mas), obtemos a distância em unidades de kpc


invertendo as paralaxes:

9 d = 1/dados[:,2]
10
Machine Translated by Google

5.3 Conjuntos de Dados de Pesquisa 197

Fig. 5.7 Distribuição de distâncias em uma amostra de 1,4 milhão de estrelas do arquivo GAIA

11 fig = plt.figure(figsize=(6, 4), dpi=300)


12
13 plt.hist(d, 100) 14
plt.xlabel('d / kpc') 15 plt.ylabel('N') 16
plt.savefig('d_histogram.png')

O histograma é mostrado na Fig. 5.7. Para 100 caixas (consulte a linha 12), o tamanho da
caixa é 1 kpc/100 = 10 unidades. Na vizinhança próxima do Sol, o número de estrelas por
bin de distância aumenta até um máximo localizado aproximadamente em 0,3 kpc. Além
disso, o número de estrelas por bin diminui com a distância. O histograma é moldado por
vários fatores:

• Assumindo uma densidade de estrelas quase constante, o número de estrelas dN em uma


casca de espessura dr ao redor do Sol escala com distância como dN ÿ r 2 esférica dr. este

determina o crescimento de N para pequenas distâncias.


• Como nossa galáxia tem uma geometria semelhante a um disco com uma espessura
média de cerca de 0,3 kpc na vizinhança solar, a inclinação do histograma diminui além
de 0,15 kpc à medida que as conchas se sobrepõem cada vez mais às regiões fora do
disco galáctico. Além disso, a densidade estelar diminui longe do plano central da Via
Láctea.
• Um fator adicional é que estrelas fracas na extremidade inferior da sequência principal,
que são mais abundantes na população estelar da galáxia, ficam abaixo do limite de
magnitude 12 imposto em nossa amostra e, em última análise, abaixo do limite de
detecção do telescópio GAIA.
• Devido ao aumento da densidade de estrelas em direção ao centro galáctico, o número
de estrelas por bin satura a distâncias maiores que 1 kpc.
Machine Translated by Google

198 5 Análise de Dados Astronômicos

Tendo explicado a distribuição espacial das estrelas em nosso conjunto de dados, podemos
passar para a distribuição de velocidade radial. Desta vez, definimos explicitamente as bordas das
caixas, começando na borda esquerda da primeira caixa e terminando na borda direita da última
caixa, em um array chamado bins. A largura do compartimento é de 2,5 km/s e as bordas mais à
esquerda e à direita que limitam o alcance ou as velocidades radiais são -140 e 140 km/s, respectivamente:

17 bin_width = 2,5 # em km/s 18 rv_lim = 140


# limite superior 19 bins = np.arange(-rv_lim,
rv_lim+bin_width,
bin_width)
20
21 fig = plt.figure(figsize=(6, 4), dpi=300)
22
23 rv_histogram = plt.hist(data[:,3], bins=bins) 24 plt.xlabel(' velocidade
radial / km/s') 25 plt.ylabel('N') 26 plt.savefig('rv_histogram.png ')

A Figura 5.8 mostra que a distribuição de velocidade radial aparece notavelmente como uma
distribuição gaussiana (também chamada de distribuição normal) da forma

y(x) = y0 exp(x ÿ x0)2 (5.7)


2ÿ2

com amplitude y0, valor médio x0 e desvio padrão ÿ. A função y(x) é a chamada função
densidade de probabilidade, ou seja, especifica a probabilidade diferencial de encontrar o
valor da variável aleatória no intervalo infinitesimal[x, x + dx]. Como a probabilidade de x
assumir qualquer valor deve ser unitária, a normalização da integral de y(x) implica y0 = 1/
ÿÿ2ÿ. No nosso caso, a variável aleatória x corresponde à velocidade radial. No entanto,
os dados do histograma não são normalizados para o tamanho total da amostra. Por esta
razão, tratamos y0 como um parâmetro livre.
Para verificar se os dados seguem uma distribuição gaussiana, calculamos um ajuste baseado no
modelo dado pela Eq. (5.7). Para isso, precisamos dos centros dos compartimentos, que podem ser
obtidos deslocando as bordas esquerdas pela metade da largura dos compartimentos:

27 x = bins[:-1] + bin_width/2 28 y =
rv_histogram[0]

As contagens de bin são retornadas em uma linha por plt.hist() (veja a linha 22). Você pode
facilmente verificar se as matrizes x e y têm o mesmo tamanho e x é executado em etapas
de 2,5 km/s de -138,75 a +138,75 km/s:
Ao aplicar curve_fit() formulário scipy.optimize, podemos descobrir qual conjunto de
parâmetros y0, x0 e ÿ se ajusta melhor aos dados:
29 import scipy.optimize como opt 30

31 # definição da função de ajuste 32 def


gaussian(x, y0, x0, sigma_sqr): 33 return y0*np.exp(-(x-
x0)**2/(2*sigma_sqr))
Machine Translated by Google

5.3 Conjuntos de Dados de Pesquisa 199

Fig. 5.8 Distribuição de velocidade radial

34 35 params, params_covariance = opt.curve_fit(gaussian, x, y) 36 print("Parameters


best-fit:", params)

Usando

Parâmetros de melhor ajuste: [ 4.85506870e+04 -8.95860537e-01 7.59083786e+02]

podemos plotar os dados junto com a função de ajuste:

37 y_gauss = gaussian(x, params[0], params[1], params[2])


38
39 fig = plt.figure(figsize=(6, 4), dpi=300)
40
41 plt.hist(data[:,3], bins=bins) 42 plt.plot(x, y_gauss,
color='red') 43 plt.xlim(-100,100) 44 plt.xlabel('radial
velocity / km/ s') 45 plt.ylabel('N') 46
plt.savefig('rv_histo_fit.png')

A função de ajuste resultante, mostrada na Fig. 5.9, parece estar em boa concordância com os
dados. Olhando mais de perto, você pode notar que o núcleo da distribuição é um pouco mais
estreito, enquanto as chamadas caudas em direção a velocidades extremas tendem a ser mais
amplas do que a função de ajuste.
Esses desvios são apenas por acaso ou sistemáticos? Tirar outras conclusões
requer a aplicação de testes estatísticos. Um método comum de calcular a probabilidade
de que dois conjuntos de dados, como valores observados e previsões teóricas, sigam
a mesma distribuição subjacente é o teste de Kolmogorov-Smirnov. Este teste é
implementado no módulo scipy.stats :
Machine Translated by Google

200 5 Análise de Dados Astronômicos

Fig. 5.9 Distribuição de velocidade radial e gaussiana de melhor ajuste (linha vermelha)

47 de scipy.stats import ks_2samp


48

49 ks_2samp(y, y_gauss)
E o resultado é

KstestResult(estatística=0,29464285714285715, pvalue=0,00010829928148128113)

O famoso valor p (valor p impresso) é uma medida importante para significância estatística.
Em resumo, assumindo que os dados seguem uma dada distribuição estatística – esta é a
chamada hipótese nula – o valor p quantifica a probabilidade de que uma amostra aleatória
extraída da distribuição seja pelo menos tão extrema quanto os dados observados. Um
valor de p muito pequeno indica que tal resultado é muito improvável se a hipótese nula
fosse realmente verdadeira. Como consequência, a hipótese nula pode ser rejeitada se o
valor de p for muito pequeno.10 No nosso caso, a hipótese nula é que os dados são gaussianos.
Como os dados parecem se desviar de uma distribuição gaussiana, testamos a significância
estatística de nossa observação. De fato, temos um valor de p tão baixo quanto 0,01%, que
está bem abaixo do limite comumente usado de 5%. Portanto, podemos concluir que a
distribuição das velocidades radiais nos dados do GAIA não segue estritamente uma distribuição
gaussiana, mas apresenta desvios sistemáticos. Distribuições gaussianas são observadas
sempre que uma determinada variável é o resultado de uma superposição de um grande
número de processos aleatórios. Para a vizinhança solar, a velocidade radial de uma estrela
em relação ao Sol é determinada por muitos fatores diferentes, incluindo a dinâmica da região
de formação de estrelas da qual a estrela se originou ou encontros próximos com outras
estrelas. À medida que avançamos para escalas maiores, a contribuição do perfil de rotação
galáctica global torna-se cada vez mais importante.

10É importante estar ciente de que o valor-p não nos permite tirar conclusões sobre a probabilidade de qualquer hipótese
alternativa.
Machine Translated by Google

5.3 Conjuntos de Dados de Pesquisa 201

A dinâmica galáctica começa a brilhar quando olhamos para a distribuição espacial das velocidades
radiais. Começamos dividindo os dados em dois subarrays.
Estrelas com velocidades radiais positivas, que aparecem desviadas para o vermelho, são separadas
das estrelas desviadas para o azul com velocidade radial negativa por meio de indexação condicional:

50 rv = dados[:,3] 51 redshift,
blueshift = dados[rv > 0], dados[rv <= 0]
52

53 print("Estrelas com desvio para o vermelho:", len(desvio para o vermelho)) 54


print("Estrelas com desvio para o azul:", len(desvio para o azul))

Estrelas desviadas para o vermelho: 675676


Estrelas deslocadas para o azul: 710808

O número de estrelas com desvio para o azul é ligeiramente maior do que o número de estrelas com desvio para
o vermelho, o que sugere uma distribuição ligeiramente assimétrica.
Para uma imagem mais detalhada, produzimos um gráfico de dispersão de estrelas com desvio para vermelho e azul
no plano medido pela longitude galáctica le latitude b (ver Fig. 5.6):

55 fig = plt.figure(figsize=(10, 10*60/360+1), dpi=300) 56 ax = fig.add_subplot(111)


57 58 step = 10 59

60 plt.scatter(blueshift[::step,0], blueshift[::step,1], 61 s=1, marker='.', color='blue',


alpha=0.1) 62 plt.scatter(redshift [::step,0],
color='red', redshift[::step,1],
alpha=0.1) 63 s=1, marker='.',
64 plt.xlabel('longitude [graus]') 65
plt.ylabel('lat. [deg]') 66 plt.xlim(0,360) 67 plt.ylim(-30,30) 68 69 # define ticks no
eixo em intervalos de 30plt.yticks([-30,
graus 70 plt.xticks([30*n
0, 30]) 72 para n no intervalo(13)]) 71

73 # garante que os graus sejam exibidos igualmente ao longo de ambos os eixos 74 ax.set_aspect('equal') 75
76 plt.savefig('rv_map.png')

Nós traçamos apenas cada décima estrela. Caso contrário, o gráfico ficaria muito cheio de pontos. Ao
definir a proporção para 'igual' (o objeto do eixo é definido na linha 55), garantimos que as longitudes e
latitudes sejam mostradas em proporção. Também definimos os tiques nos dois eixos explicitamente
(veja as linhas 69–70). O gráfico é mostrado na Fig. 5.10. Você pode ver que as estrelas tendem a ser
desviadas para o vermelho ou para o azul dependendo da longitude galáctica, enquanto elas estão
espalhadas aleatoriamente ao longo da latitude galáctica. A explicação para esta variação pode ser
encontrada na estrutura em forma de disco da Via Láctea, com modulações
Machine Translated by Google

202 5 Análise de Dados Astronômicos

Fig. 5.10 Distribuição de estrelas desviadas para o azul e para o vermelho no plano lb

causada por seus braços espirais. No exercício a seguir, você será solicitado a analisar
quantitativamente a dependência da longitude.
Exercícios

5.5 Use o conjunto de dados discutido nesta seção para calcular valores médios e desvios
padrão da velocidade radial para 5ÿ bins da longitude galáctica e plote seus resultados. Se
você assumir que a curva de rotação galáctica na vizinhança solar é plana, ou seja, a magnitude
da velocidade orbital é constante, e as velocidades radiais médias refletem principalmente os
movimentos orbitais das estrelas ao redor do centro da galáxia, quais tendências você espera?
Tenha em mente que a velocidade radial é o componente da diferença de velocidade entre
uma estrela e o Sol na direção do Sol para a estrela.

5.6 Para distâncias d R0, onde R0 ÿ 8,5 kpc é a distância entre o Sol e o centro da Via Láctea,
a velocidade radial é aproximadamente dada pela fórmula de Oort

vr
= Um sen(2l) , (5.8)
d

onde A = 14,8 km sÿ1 kpcÿ1 [4, Seção. 25.3].

(a) Crie um gráfico de dispersão de vrad/d versus longitude galáctica l para aquelas estrelas no
Conjunto de dados GAIA que estão mais próximos que 0,05R0.

(b) Ajuste a Eq. (5.8) aos dados de (a) e determine o valor de melhor ajuste de A. Adicione a
curva resultante ao gráfico de dispersão e discuta seus resultados.

5.4 Processamento de Imagem

O acesso online a grandes coleções de imagens de telescópios espaciais é fornecido pelo


Arquivo Barbara A. Mikulski para Telescópios Espaciais (MAST) da NASA,11 incluindo o
arquivo legado do famoso Telescópio Espacial Hubble (HST).12 Por exemplo, você pode
pesquisar para imagens do Whirpool Galaxy M51 e baixe imagens tiradas em

11Site do arquivo: archive.stsci.edu.

12Veja hubblesite.org e www.spacetelescope.org. Uma imagem de exemplo é mostrada na Fig. 4.14.


Machine Translated by Google

5.4 Processamento de Imagem 203

várias bandas de comprimento de onda diferentes de archive.stsci.edu/prepds/m51/datalist.html.


Essas imagens estão disponíveis no formato de arquivo FITS, que não é usado apenas para
dados como espectros, mas também para imagens astronômicas. Per se, as câmeras CCD usadas
em telescópios astronômicos são daltônicas. Cada pixel simplesmente conta o número de elétrons
criados pelos fótons incidentes, independentemente de seu comprimento de onda. No entanto, a
sensibilidade do dispositivo depende do comprimento de onda.
Para reconstruir uma imagem colorida, precisamos de pelo menos três imagens tiradas com
diferentes filtros de comprimento de onda. A seguir, selecionamos os dados de imagem dos
filtros azul (435 nm), verde/visual (555 nm) e vermelho/Hÿ (658 nm) (a seguir também chamados
de canais). Você precisa baixar os filesh_m51_b_s20_drz_sci.fits, h_m51_b_s20_drz_sci.fits e
h_m51_b_s20_drz_sci.fits do URL mencionado acima. Começamos lendo o cabeçalho FITS da
imagem do canal vermelho:

1 import numpy as np 2 import


matplotlib.pyplot como plt 3 de astropy.io import se
encaixa
4
5 m51r_file = "h_m51_h_s20_drz_sci.fits" 6 m51r = fit.open(m51r_file)
7 m51r.info()

O método info() mostra que o arquivo contém um array de 2150 vezes 3050 números de ponto
flutuante:

Nome do arquivo: h_m51_h_s20_drz_sci.fits Cartões Dimensões


Não. Nome Ver Tipo Formato
0 PRIMÁRIO 1 HDU Primário 1691 (2150, 3050) float32

Depois de copiar os dados da HDU primária (veja também a Seção 5.1), podemos fechar o
arquivo.

8 m51r_data = m51r[0].data 9 m51r.close()

É útil criar um histograma dos dados da imagem achatando m51r_data em uma matriz
unidimensional, ou seja, reorganizando a matriz bidimensional de valores de imagem em uma
sequência linear:

10 plt.hist(m51r_data.flatten(), log=True, bins=100) 11 plt.xlabel('Signal') 12 plt.ylabel('N')


13 plt.savefig('m51_histogram.png', dpi= 300)

Como as contagens de caixas N diferem em ordens de magnitude, usamos uma escala logarítmica.
O histograma mostra que, de longe, o maior número de pixels tem um sinal próximo a 0, com
apenas um pequeno número de leituras individuais maiores que 5 (veja a Fig. 5.11). Esta razão
para isso fica clara ao visualizar a imagem.
Machine Translated by Google

204 5 Análise de Dados Astronômicos

Fig. 5.11 Distribuição de valores na imagem do canal vermelho M51

Para produzir uma imagem, temos que mapear os valores do array para algum
esquema de cores. Isso é feito pela função imshow() do pyplot. Por padrão, o intervalo
entre o mínimo e o máximo é mapeado para cores. Isso resultaria em uma imagem
totalmente preta, pois a maioria dos valores é pequena. Por esta razão, definimos
limites razoáveis com clim(). O limite superior é cerca de dez vezes o valor mediano,
que você pode calcular utilizando NumPy.

14 plt.imshow(m51r_data, cmap='gray') 15 plt.clim(0,0.1)


16 plt.colorbar() 17 plt.savefig('m51r.pdf')

A imagem que começa a emergir na Fig. 5.12 é sem dúvida uma das imagens mais populares
de uma galáxia espiral, compartilhando muitas semelhanças com nossa própria galáxia, exceto
pela pequena companheira que causa alguma ruptura de maré nos braços espirais externos.
No entanto, ainda falta o belo azul claro de seus braços espirais, entrelaçados por faixas de poeira
escura e regiões avermelhadas de formação de estrelas.
Os dados de imagem dos três filtros nos permitem compor uma imagem usando o sistema
de cores RGB. Nesse sistema, as cores são representadas por uma combinação de valores de
8 bits que variam de 0 a 255 para vermelho, verde e azul. Primeiro, complementamos os dados
da imagem carregando os canais verde e azul:

18 m51g_file = "h_m51_v_s20_drz_sci.fits" 19 m51g =


fit.open(m51g_file) 20 m51g_data = m51g[0].data 21 m51g.close()

22
23 m51b_file = "h_m51_b_s20_drz_sci.fits"
Machine Translated by Google

5.4 Processamento de Imagem 205

Fig. 5.12 Imagem monocromática


de M51 no canal vermelho (Hÿ). Os
eixos vertical e horizontal indicam
as posições dos pixels e a barra de

cores à direita mostra o mapeamento


da intensidade do sinal para uma
escala de cinza

24 m51b = fit.open(m51b_file) 25 m51b_data =


m51b[0].data 26 m51b.close()

O próximo passo é converter os dados em valores de 8 bits. Como a maioria dos valores
está agrupada em torno da média, dividimos os arrays pelos valores médios nos três
canais e multiplicamos por 255. Além disso, incorporamos um fator alfa que nos permite
deslocar todos os canais de uma vez, permitindo controlar o brilho do a imagem.
27 alfa = 0,15 28 29
m51rgb = np.zeros([2150,
3050, 3]) 30

31 m51rgb[:,:,0] = m51r_data.transpose() / np.mean(m51r_data) 32 m51rgb[:,:,1] =


m51g_data.transpose() / np.mean(m51g_data) 33 m51rgb[:,: ,2] = m51b_data.transpose() /
np.mean(m51b_data) 34 35 m51rgb *= 255*alfa

Os dados RGB são coletados em uma nova matriz tridimensional, onde a terceira
dimensão abrange os canais vermelho, verde e azul. Os dois primeiros índices especificam
a posição de um pixel, onde trocamos as direções horizontal e vertical transpondo as
matrizes bidimensionais contendo os dados brutos. Como etapa final, cortamos em 255
usando np.where():

36 m51rgb = np.onde(m51rgb > 255, 255, m51rgb)


Machine Translated by Google

206 5 Análise de Dados Astronômicos

Fig. 5.13 Imagem RGB de M51 composta de dados de imagem HST de três filtros diferentes
(archive.stsci.edu/prepds/m51/datalist.html)

Agora temos valores no intervalo apropriado. Para empilhá-los e transformá-los em


uma imagem, vamos usar a Python Imaging Library (Pillow).13 A biblioteca é importante
sob o nome de PIL. Entre várias ferramentas para manipulação e análise básica de
imagens, ela fornece a função Image.fromarray() para criar um objeto de imagem que
pode ser salvo em qualquer formato gráfico comum, como PNG. Como os valores RGB
devem ser especificados como inteiros sem sinal de 8 bits, aplicamos o método astype()
para alterar o tipo de dados do array de float para np.uint8 ao passar m51rgb como
argumento.
37 da importação PIL Imagem 38

39 # converte para inteiros sem sinal de 8 bits e transforma array em imagem 40 img =
Image.fromarray(m51rgb.astype(np.uint8)) 41 img.show() 42 img.save('m51rgb.png')

Se tudo funcionar, você será saudado pela imagem mostrada na Fig. 5.13. Tenha em
mente que as imagens astronômicas são até certo ponto artificiais. Eles não correspondem
exatamente à impressão que o olho humano teria se pudesse ver esses objetos. Mesmo
assim, eles nos ajudam a revelar estruturas como as regiões de formação de estrelas
proeminentes em M51.

13Para documentação online, consulte pillow.readthedocs.io/en/stable/handbook/overview.html.

Você também pode gostar