Files
monitor/scripts/03_gti.py
2025-10-09 19:57:47 +03:00

213 lines
6.8 KiB
Python
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
"""
НАЗВАНИЕ:
gti.py
НАЗНАЧЕНИЕ:
рипт для создания интервалов хорошего времени по данным из файла, сбинированного по 60 минут программой create_binned_filed.py (на основе оригинального файла lc_orig_60-120.csv, выгруженного с СРГ L2 монитора https://monitor.srg.cosmos.ru/ )
Скрипт аппроксимирует кривую блеска полиномом, чтобы убрать синусоидальный тренд, ищет времена вспышек и возвращает интервалы времени без вспышек в офрмате секунд с начала 1 января 2000 года (Москва) (файл gti_sec.csv) и в формате дестичного года (файл gti_dyear.csv).
ВЫЗОВ:
conda activate
./gti.py
УПРАВЛЕНИЕ:
Название файла надо вставить внутрь скрипта (ищите lc_bin_60min_60-120.csv)
ПАРАМЕТРЫ:
N/A
ВЫВОД:
Файл с графиком monitor.png записывается в текущую директорию.
Файл с интервалами времени gti.csv записывается в текущую директорию.
ИСТОРИЯ:
Филиппова Екатерина, ИКИ РАН, kate@cosmos.ru
Сентябрь, 2025
"""
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import ticker
import pandas as pd
import datetime
import dateutil
from os.path import dirname
import inspect
from scipy.optimize import curve_fit
from scipy.ndimage import gaussian_filter1d
from scipy import signal
from scipy.stats import median_abs_deviation
import astropy.io.fits as pf
from astropy.time import Time
import monitor
from monitor.config import *
from monitor.utils import *
""" find root dir """
root_path=dirname(dirname(dirname(inspect.getfile(monitor))))
print("Monitor root path: {}".format(root_path))
products_dir=root_path+'/products/'
data_dir=root_path+'/data/'
create_folder(products_dir)
fig, ax = plt.subplots(figsize=(9, 5), dpi=100)
ax.grid(visible=True,linestyle='dotted', )
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1/12))
ax.yaxis.set_minor_locator(ticker.MultipleLocator(0.2))
ax.tick_params(axis="both", width=1, labelsize=14)
#geminga_dt = datetime.date.fromisoformat('2023-04-16')
#day_of_year = geminga_dt.timetuple().tm_yday # returns 1 for January 1st
#geminga_tm=geminga_dt.year+(day_of_year/365)
#plt.axvline(x = geminga_tm, color = 'b', linewidth=3 , linestyle='dashed', label = 'Geminga scan')
#plt.xlim([2020,2025])
#plt.ylim([2,12])
plt.ylabel('Count rate (counts s$^{-1}$)',fontsize=14, fontweight='normal')
plt.xlabel('Year',fontsize=14, fontweight='normal')
for axis in ['top','bottom','left','right']:
ax.spines[axis].set_linewidth(1)
cl='black'
input_file='default.csv'
# Сюда надо вставить название файла, скачанного с https://monitor.srg.cosmos.ru/
df = pd.read_csv(data_dir+input_file)
tm=[]
rate=[]
error=[]
for index, row in df.iterrows():
dt = dateutil.parser.parse(row['timestamp'])
dyear = get_decimal_year(dt)
tm.append(dyear)
rate.append(float(row['value_60.0-120.0']))
error.append(float(row['error_60.0-120.0']))
rate=np.array(rate)
tm=np.array(tm)
tmp=np.where(rate>0,1,0)
rate=np.compress(tmp,rate)
tm=np.compress(tmp,tm)
error=np.compress(tmp,error)
tmp=np.where(rate < 4.3,1,0)
tm_fit=np.compress(tmp,tm)
rate_fit=np.compress(tmp,rate)
# fit polinom of degree
degree = 6
#initial_guess = [1] * (degree + 1) # Initial guess for coefficients
#initial_guess = [-3.67265411e+08, 5.44675290e+05, -2.69261063e+02, 4.43698213e-02]
initial_guess = [ -6.10911582e+07, 3.02005656e+04, 1.49297834e+01, 6.53394516e-09, -3.64859359e-06, -1.80368300e-09, 8.91651441e-13]
params, covariance = curve_fit(polynomial_func, tm_fit, rate_fit, p0=initial_guess)
print("curve_fit:",params)
# Generate fitted curve (original bin)
y_fit = polynomial_func(tm, *params)
# Delaem interpolyaciyu v 100 raz
year_min = min(tm)
year_max = max(tm)
year_step = (year_max - year_min)/len(tm)
year_sim = np.arange(year_min, year_max, year_step/100)
rate_interp = np.interp(year_sim, tm, rate)
# Generate fitted curve (interpolated)
y_fit_interp = polynomial_func(year_sim, *params)
plt.plot(tm, rate, color=cl, linewidth=1, linestyle='solid')
plt.plot(tm, y_fit, color="red", linewidth=2, linestyle='solid', label=f'Degree {degree} fit')
plt.ylabel('Count rate (counts s$^{-1}$)',fontsize=14, fontweight='normal')
plt.xlabel('Year',fontsize=14, fontweight='normal')
fig.savefig(products_dir+"bestfit.png", bbox_inches='tight')
plt.show()
fig.clear() # Clears the specific figure object
fig, ax = plt.subplots(figsize=(9, 5), dpi=100)
ax.grid(visible=True,linestyle='dotted', )
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1/12))
ax.yaxis.set_minor_locator(ticker.MultipleLocator(0.2))
ax.tick_params(axis="both", width=1, labelsize=14)
#plt.xlim([2020,2025])
#plt.ylim([0,200])
for axis in ['top','bottom','left','right']:
ax.spines[axis].set_linewidth(1)
resid=rate/y_fit
resid_interp=rate_interp/y_fit_interp
#smoothed_resid = gaussian_filter1d(resid, sigma=2)
outbursts = detect_outbursts(year_sim, resid_interp, threshold=threshold, min_duration=1)
plt.plot(tm, resid, color="black", linewidth=1, linestyle='solid',label="Residuals")
#plt.plot(tm, smoothed_resid, color="red", linewidth=1, linestyle='solid',label="Residuals")
plt.axhline(y = threshold, color = 'b', linewidth=1 , linestyle='dashed', label = 'Threshold')
plt.ylabel('Ratio',fontsize=14, fontweight='normal')
plt.xlabel('Year',fontsize=14, fontweight='normal')
fig.savefig(products_dir+"resid.png", bbox_inches='tight')
# Testing
"""
for start,end,peak,peak_flux in outbursts:
print(start,end,peak,peak_flux)
plt.axvline(x = start, color = 'r', linewidth=1 , linestyle='solid')
plt.axvline(x = end, color = 'g', linewidth=1 , linestyle='solid')
plt.axvline(x = peak, color = 'b', linewidth=1 , linestyle='solid')
"""
plt.show()
save_tex_table(outbursts,output=products_dir+'flares.tex')
tstart=[tm[0]]
tstop=[]
for start,end,peak,peak_flux in outbursts:
if end != tm[-1]:
tstop.append(start)
tstart.append(end)
else:
tstop.append(start)
if outbursts[-1][1] != tm[-1]:
tstop.append(tm[-1])
df = pd.DataFrame({'tstart': tstart,'tstop': tstop})
df.to_csv(products_dir+'gti_dyear.csv', index=False)
tstart_obj = Time(tstart, format='decimalyear')
tstop_obj = Time(tstop,format='decimalyear')
tstart_sec=(tstart_obj.mjd-51543.75)*86400
tstop_sec=(tstop_obj.mjd-51543.75)*86400
df = pd.DataFrame({'tstart': tstart_sec,'tstop': tstop_sec})
df.to_csv(products_dir+'gti_sec.csv', index=False)