%matplotlib inline
#stazeni souboru
import sys,os
import pyfits
import numpy as np
resp=pyfits.open("/home/data/CALDB/data/swift/xrt/cpf/rmf/swxwt0s6_20010101v014.rmf")
popis formatu resp. matice http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/docs/memos/cal_gen_92_002/cal_gen_92_002.html
organizovana do "channel subsets" (zapis ridke resp. opakujici se matice)
resp[1].columns
# soucet hodnot v radcich - normalizace rozdeleni prandepodobnosti
sums=np.array([sum(a) for a in resp[1].data['MATRIX']])
from matplotlib import pyplot as pl
pl.plot(resp[1].data['ENERG_LO'],sums)
# pocty nenulovych prvku ridke matice
lens=np.array([len(a) for a in resp[1].data['MATRIX']])
pl.plot(resp[1].data['ENERG_LO'],lens)
#rekonstrukce jednoho radku [zvolena energie]
q=resp[1].data[810]
smat1=np.concatenate([np.arange(a,a+b) for a,b in np.r_[[q['F_CHAN'],q['N_CHAN']]].T])
emat=np.zeros(1024)
emat[smat1]=q['MATRIX']
pl.semilogy(emat)
print("energie %.2f keV"%q["ENERG_LO"])
#rekonstrukce cele matice
gmat=[]
for i in range(0,2400,10):
q=resp[1].data[i]
if q['N_GRP']==0: continue
if q['N_GRP']>1:
smat=np.concatenate([np.arange(a,a+b) for a,b in np.r_[[q['F_CHAN'],q['N_CHAN']]].T])
else:
smat=np.arange(q['F_CHAN'][0],q['F_CHAN'][0]+q['N_CHAN'][0])
emat[:]=0
emat[smat]=np.log(q['MATRIX'])
gmat.append(emat.copy())
gmat=np.array(gmat)
pl.imshow(gmat,aspect='auto',extent=[0,1024,resp[1].data[0]['ENERG_LO'],resp[1].data[-1]['ENERG_HI']],origin='lower')
pl.colorbar()
#vertikalni rez - jeden kanal prekladan do energii
b=np.exp(gmat[:,500])
b[gmat[:,500]==0]=0
pl.plot(resp[1].data['ENERG_LO'][10:-10:10],b)
pl.xlabel('keV')
sum(b)
ridka matice prevedena na hustou bude zjednodusena (zprumerovana) na 46 energetickych a 64 instrumentalnich binu (kanalu)
femat=np.exp(gmat)
femat[femat==1]=0
eemat=femat[:230].reshape(23*2,5,64,16).mean(1).sum(2)
pl.imshow(np.log(eemat))
import pickle
#pickle.dump(eemat,open("rebin.rsp","wb"))
eemat=pickle.load(open("rebin.rsp","rb"))
# puvodne 1024 kanalu x 2400 energ. binu
# analogie prvniho obrazku po rebinovani
eemat[eemat==1]=0
pl.plot(eemat.sum(1))
kalibrace pozorovani AGN 3C 273 pomoci PN kamery druzice XMM
nastroji specificke analyzy dat (XMM SAS) se vytvori kalibracni matice pro konkretni polohu zdroje a natoceni dalekohledu (attitude)
myspec="/home/limu/data/agn/3C273/0159960101/pn/agn_grpspec.pha"
sp1=pyfits.open(myspec)[1].data['COUNTS']
#sp1=sp1.reshape(len(sp1)//2,2).mean(1)
pl.semilogy(sp1)
pl.xlabel("energy[keV]")
pl.ylabel("counts")
ene=pyfits.open(myspec)[1].header
#data obsahuji take regrupovani, zde ho nepouzijeme
mydat.columns
resp2=pyfits.open("/home/limu/data/agn/3C273/0159960101/pn/spec.rmf")
lens=np.array([len(a) for a in resp2[1].data['MATRIX']])
pl.plot(resp2[1].data['ENERG_LO'],lens)
pl.ylim(0,900)
resp2[1].columns
# new response matrix
#resp2=pyfits.open("/home/limu/data/agn/3C273/0159960101/pn/spec.rmf")
print(resp2[1].columns)
llen=800
emat=np.zeros(llen)
gmat2=[]
for i in range(0,2000,5):
q=resp2[1].data[i]
if q['N_GRP']==0: continue
if q['N_GRP']>1:
smat=np.concatenate([np.arange(a,a+b) for a,b in np.r_[[q['F_CHAN'],q['N_CHAN']]].T])
else:
smat=np.arange(q['F_CHAN'][0],q['F_CHAN'][0]+q['N_CHAN'][0])
emat[:]=0
emat[smat]=np.log(q['MATRIX'])
gmat2.append(emat.copy())
gmat2=np.array(gmat2)
pl.imshow(gmat2,aspect='auto',extent=[0,llen,resp2[1].data[0]['ENERG_LO'],resp2[1].data[i]['ENERG_HI']],origin='lower')
pl.colorbar()
gmat2.shape
diagonalni tvar je tady vyrazne deformovan - duvodem je ve skutecnosti nepravidelne rozdeleni energet. binu, jak je videt z ARF matice nize (srovnani s polohami binu u "velke" matice v uvodu)
arf2=pyfits.open("/home/limu/data/agn/3C273/0159960101/pn/spec.arf")
pl.plot(resp[1].data['ENERG_LO'])
pl.plot(resp2[1].data['ENERG_LO'])
pl.xlabel("channel")
pl.ylabel("energy")
pl.legend(["fullmat","rebinned"],loc=2)
arf2[1].data['ENERG_LO'].shape,resp2[1].data['ENERG_LO'].shape
model 1: $p_0\ x^{p_1}\ e^{-x/p_2}$
# defining absorbed PL - 3 parameters
model1=lambda x,p:p[0]*pow(x,p[1])*np.exp(-x/p[2])
x1=resp2[1].data['ENERG_LO'][2:2000:5][:400]
pl.loglog(x1,model1(x1,[2,-1.3,3.]))
smat=np.exp(gmat2)
smat[gmat2==0]=0 #pri logaritmovani jsme upravili nulove body
pl.imshow(smat,origin="lower")
pl.colorbar()
#sum(gmat2==1)
v nezlogaritmovanem tvaru vidime vyrazne dominujici prvky kolem "diagonaly"
vyhledanim maximalniho prvku pro dany kanal muzeme priblizne prepocitavat instrumentalni kanaly na energii (fce argmax
o nekolik poli nize)...
#aplikace response matice na model
pix1=np.dot(model1(x1,[2,-1.3,10]),smat)
pl.semilogy(pix1)
llen=800
ematff=np.zeros(llen)
gmat2ff=[]
for i in range(0,2000):
q=resp2[1].data[i]
if q['N_GRP']==0: continue
if q['N_GRP']>1:
smat=np.concatenate([np.arange(a,a+b) for a,b in np.r_[[q['F_CHAN'],q['N_CHAN']]].T])
else:
smat=np.arange(q['F_CHAN'][0],q['F_CHAN'][0]+q['N_CHAN'][0])
ematff[:]=0
ematff[smat]=np.log(q['MATRIX'])
gmat2ff.append(ematff.copy())
gmat2ff=np.array(gmat2ff)
#spocteno jeste jednou bez prumerovani po 5ti binech
x1b=(resp2[1].data['ENERG_LO'][:2000]+resp2[1].data['ENERG_HI'][:2000])/2.
smatff=np.exp(gmat2ff)
smatff[gmat2ff==0]=0
pix1b=np.dot(model1(x1b,[2,-1.3,10]),smatff)
pl.semilogy(pix1b)
muzeme pouzit uz rebinovanou matici z analyzy
pl.plot(resp[1].data['ENERG_LO'])
pl.plot(resp2[1].data['ENERG_LO'])
x1=resp2[1].data['ENERG_LO'][2:2000:5][:400]
#ene2=resp2[1].data['ENERG_LO'][2:2000:5] #kazdy 5. prvek
pl.plot(x1[smat.argmax(0)])
np.polyfit(np.r_[:800],x1[smat.argmax(0)],1)
argmax
)conv2=0.0150*np.r_[:800]+0.0256
wid=resp2[1].data['ENERG_HI'][2:2000:5][:400]-x1
widb=(resp2[1].data['ENERG_HI'][:2000:]-x1b)*2
x1=x1+wid/2.
pix2=np.dot(model1(x1,[2,-1.3,10])*wid,smat)
pl.semilogy(conv2,pix2)
pl.xlabel("energy")
pl.plot(x1,wid)
pl.plot(arf2[1].data['ENERG_LO'],arf2[1].data['SPECRESP'])
pl.xlabel("energy")
pl.title("ARF matice")
pl.semilogx(arf2[1].data['ENERG_LO'],arf2[1].data['SPECRESP'])
pl.xlabel("energy")
arpl=arf2[1].data['SPECRESP'][:2000].reshape(400,5).mean(1) #rebinovani ARF matice po 5 energ. binech
pix2b=np.dot(model1(x1,[1,-1.3,10])*wid*arpl,smat)
pl.semilogy(conv2,sp1)
norm=sp1[10:].sum()/pix2b[10:].sum()
pix2b=np.dot(model1(x1,[norm,-1.3,10])*wid*arpl,smat)
pl.semilogy(conv2,pix2b)
pl.xlabel("energy")
norm
arplb=arf2[1].data['SPECRESP'][:2000]
pix2bb=np.dot(model1(x1b,[1,-1.3,10])*widb*arplb,smatff)
normb=sp1[10:].sum()/pix2bb[10:].sum()
pix2bb=np.dot(model1(x1b,[normb,-1.3,10])*widb*arplb,smatff)
#pl.semilogy(conv2,pix2bb)
pl.semilogy(conv2,abs(pix2bb-pix2b))
bez prumerovani nejsou problemy s "vlnkami" ve vyslednem spektru (ale je to lehce vypocetne narocnejsi)
pl.semilogy(conv2,pix2bb)
sel=(conv2>0.7)*(conv2<10)
#dif=lambda p:((np.dot(model1(x1,p)*wid*arpl,smat)[sel]-sp1[sel])**2/sp1[sel]).sum()
dif=lambda p:((np.dot(model1(x1b,p)*widb*arplb,smatff)[sel]-sp1[sel])**2/sp1[sel]).sum()
dif([normb,-1.3,10])
from scipy import optimize as op
bst1=op.fmin(dif,[normb,-1.3,10])
bst1,dif(bst1)
pl.semilogy(conv2[sel],sp1[sel])
val1=np.dot(model1(x1b,bst1)*widb*arplb,smatff)
pl.semilogy(conv2[sel],val1[sel])
pl.grid()
pl.plot(conv2[sel],(sp1[sel]-val1[sel])/np.sqrt(sp1[sel]))
pl.ylim(-6,6)
pl.ylabel('residuum')
pl.xlabel('energy')
pl.grid()
model2=lambda x,p:p[0]*np.concatenate([pow(x[x<p[2]]/p[2],p[1]),pow(x[x>=p[2]]/p[2],p[3])])
pl.loglog(x1,model2(x1,[5,-1.,3,-2.]))
pl.grid()
cst0=[bst1[0],bst1[1]+.5,2.,bst1[1]]
#difarr=lambda p:(np.dot(model2(x1,p)*wid*arpl,smat)[sel]-sp1[sel])/np.sqrt(sp1[sel])
difarr=lambda p:(np.dot(model2(x1b,p)*widb*arplb,smatff)[sel]-sp1[sel])/np.sqrt(sp1[sel])
#cst1=op.fmin(lambda p:sum(difarr(p)**2),cst0)
zmin=lambda p:sum(difarr(p)**2)
#zmin(cst0)
cst1=op.fmin(zmin,cst0)
pl.semilogy(conv2[sel],sp1[sel])
val2=np.dot(model2(x1b,cst1)*widb*arplb,smatff)
pl.semilogy(conv2[sel],val2[sel])
pl.grid()
pl.plot(conv2[sel],(val2[sel]-sp1[sel])/np.sqrt(sp1[sel]))
pl.grid()
potrebujeme znat nejistoty predpovedi modelu v jednotlivych binech
zavisi take na nejistotach parametru
T.B.D. (stay tuned)
pocitame profil chi2 v zavislosti na 4 parametrech
s0=(difarr(cst1)**2).sum()
s0/sum(sel)
npt=21
zgrid=np.mgrid[-5:5:1j*npt,-5:5:1j*npt,-5:5:1j*npt,-5:5:1j*npt]
zgrid[:,12,12,12,12]
alpars=np.array([cst1[i]*(1+0.01*zgrid[i].ravel()) for i in range(len(cst1))]).T
alchis=np.array([(difarr(c)**2).sum() for c in alpars]).reshape(npt,npt,npt,npt)
pl.imshow(alchis[10,10]/s0*sum(sel))
pl.colorbar()
pl.imshow(alchis[10,:,10,:]/s0*sum(sel))
pl.colorbar()
pl.imshow(alchis.mean(2).mean(0)/s0*sum(sel))
pl.colorbar()
xp=np.r_[1-0.05:1.05:npt*1j]
pl.plot(xp,alchis[10,10,10,:])
pl.plot(xp,alchis[10,10,8,:])
pl.plot(xp,alchis[10,14,10,:])
pl.xlabel("relat. p4")
#der2=lambda p:p[0]
print(1/np.polyfit(xp-1,alchis[11,11,11,:]/s0,2)[0]/2.)
print(1/np.polyfit(xp[5:16]-1,alchis[11,11,11,5:16]/s0,2)[0]/2.)
print(1/np.polyfit(xp[5:16]-1,alchis[11,11,8,5:16]/s0,2)[0]/2.)
print(1/np.polyfit(xp[5:16]-1,alchis[11,14,11,5:16]/s0,2)[0]/2.)
print(1/np.sqrt(np.polyfit(xp[5:17]-1,alchis[5:17,11,11,11]/s0,2)[0]/2.))
print(1/np.sqrt(np.polyfit(xp[5:17]-1,alchis[11,5:17,11,11]/s0,2)[0]/2.))
print(1/np.sqrt(np.polyfit(xp[5:17]-1,alchis[11,11,5:17,11]/s0,2)[0]/2.))
print(1/np.sqrt(np.polyfit(xp[5:17]-1,alchis[11,11,11,5:17]/s0,2)[0]/2.))
pl.plot(xp,alchis[10,:,10,10]/s0,label="p2")
pl.plot(xp,alchis[10,10,10,:]/s0,label="p4")
pl.legend()
#4D matice zazalohovana
import pickle
pickle.dump(alchis,open("chi2_bknpow.npy","wb"))