pulphi.py
1 |
#! /usr/bin/env python
|
---|---|
2 |
# ==========================================================================
|
3 |
# Reimplements COMPASS taks PULPHI
|
4 |
#
|
5 |
# Copyright (C) 2022 Juergen Knoedlseder
|
6 |
#
|
7 |
# This program is free software: you can redistribute it and/or modify
|
8 |
# it under the terms of the GNU General Public License as published by
|
9 |
# the Free Software Foundation, either version 3 of the License, or
|
10 |
# (at your option) any later version.
|
11 |
#
|
12 |
# This program is distributed in the hope that it will be useful,
|
13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
# GNU General Public License for more details.
|
16 |
#
|
17 |
# You should have received a copy of the GNU General Public License
|
18 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19 |
#
|
20 |
# ==========================================================================
|
21 |
import math |
22 |
import gammalib |
23 |
|
24 |
|
25 |
# Static stuff for bvceph
|
26 |
jdch0 = 0
|
27 |
earth = [] |
28 |
sun = [] |
29 |
tdbtdt = [] |
30 |
tdtut = [] |
31 |
tdbdot = [] |
32 |
|
33 |
|
34 |
# ======================================================= #
|
35 |
# Extrapolate pulsar frequency, derivative and zero phase #
|
36 |
# ======================================================= #
|
37 |
def pula32(f0, fdot, f2dot, zphas, t0, tm): |
38 |
"""
|
39 |
Implement AL-032 to extapolate the pulsar frequency, derivative and
|
40 |
zero phase to the center of the epoch
|
41 |
"""
|
42 |
# Set constants
|
43 |
pow2 = 2147483647.0
|
44 |
|
45 |
# Calculate time difference in seconds
|
46 |
tdif = float(tm[0] - t0[0]) * 86400.0 + float(tm[1] - t0[1]) / 8000.0 |
47 |
|
48 |
# Extrapolate frequency, all times are in seconds
|
49 |
f0e = f0 + tdif * fdot + (tdif*tdif * f2dot) / 2.0
|
50 |
|
51 |
# Extrapolate frequency derivative
|
52 |
fdote = fdot + tdif * f2dot |
53 |
|
54 |
# Extrapolate the zero phase
|
55 |
x = zphas + f0*tdif + ((fdot * math.pow(tdif,2)) / 2.0) + \ |
56 |
((f2dot * math.pow(tdif,3)) / 6.0) |
57 |
|
58 |
# Accuracy checks
|
59 |
if x > pow2:
|
60 |
npow = int(x / pow2)
|
61 |
x = x - (float(npow)*pow2)
|
62 |
|
63 |
# Calculate the residual by removing the integer part
|
64 |
zphasp = x - float(int(x)) |
65 |
|
66 |
# Fix if < 0
|
67 |
if zphasp < 0.0: |
68 |
zphasp = 1.0 + zphasp
|
69 |
|
70 |
# Return
|
71 |
return (f0e, fdote, zphasp)
|
72 |
|
73 |
|
74 |
# =================== #
|
75 |
# Get BVC information #
|
76 |
# =================== #
|
77 |
def pbvcrr(bvc, irow): |
78 |
"""
|
79 |
Get BVC information
|
80 |
"""
|
81 |
# Extract information for row irow
|
82 |
time = [bvc['TJD'].integer(irow), bvc['TICS'].integer(irow)] |
83 |
ssb = [bvc['SSB_X'].real(irow), bvc['SSB_Y'].real(irow), bvc['SSB_Z'].real(irow)] |
84 |
etut = bvc['TDELTA'].real(irow)
|
85 |
|
86 |
# Return information
|
87 |
return (time, ssb, etut)
|
88 |
|
89 |
|
90 |
# =================== #
|
91 |
# Get EVP information #
|
92 |
# =================== #
|
93 |
def pevpsr(evp, irow): |
94 |
"""
|
95 |
Get EVP information
|
96 |
"""
|
97 |
# Extract information for row irow
|
98 |
time = [evp['TJD'].integer(irow), evp['TICS'].integer(irow)] |
99 |
|
100 |
# Return information
|
101 |
return (time)
|
102 |
|
103 |
|
104 |
# ========================== #
|
105 |
# Evaluates the GRO position #
|
106 |
# ========================== #
|
107 |
def pulbvc(evtime, tag1, tag2, y1, y2): |
108 |
"""
|
109 |
Evaluates the GRO position at the time of the event by interpolating the
|
110 |
positions supplied every 16 sec. by BVC. The interpolating function is
|
111 |
a 1st order curve : Y = A * X + B
|
112 |
"""
|
113 |
# Compute times
|
114 |
xtime1 = float(tag1[0]) * 86400.0 + float(tag1[1]) / 8000.0 |
115 |
xtime2 = float(tag2[0]) * 86400.0 + float(tag2[1]) / 8000.0 |
116 |
etime = float(evtime[0]) * 86400.0 + float(evtime[1]) / 8000.0 |
117 |
dt = xtime2 - xtime1 |
118 |
|
119 |
#
|
120 |
a = [(y2[0] - y1[0])/dt, |
121 |
(y2[1] - y1[1])/dt, |
122 |
(y2[2] - y1[2])/dt] |
123 |
|
124 |
#
|
125 |
ssb = [a[0] * (etime - xtime1) + y1[0], |
126 |
a[1] * (etime - xtime1) + y1[1], |
127 |
a[2] * (etime - xtime1) + y1[2]] |
128 |
|
129 |
# Return
|
130 |
return ssb
|
131 |
|
132 |
|
133 |
# ============================================= #
|
134 |
# Convert event time to solar system Barycentre #
|
135 |
# ============================================= #
|
136 |
def pula04(ftime, ssb, pos1, pos2, pos3, etut): |
137 |
"""
|
138 |
This routine implements the algorithm PUL-AL-004 to calculate the arrival times of
|
139 |
detected photons at the Solar System Barycentre (SSB)
|
140 |
"""
|
141 |
# Set constants
|
142 |
radius = 0.49254909e-5
|
143 |
|
144 |
# Find the light travel time from the satellite to SSB along the pulsar direction
|
145 |
travt = (pos1*ssb[0] + pos2*ssb[1] + pos3*ssb[2]) * 1.e-6 |
146 |
|
147 |
# Find the relativistic delay due to the sun
|
148 |
r = 1.e-6 * (math.sqrt((ssb[0]*ssb[0] + ssb[1]*ssb[1] + ssb[2]*ssb[2]))) |
149 |
relat = -2.0 * radius * math.log(1.0 + (travt / r)) |
150 |
|
151 |
# For debugging
|
152 |
tdelta = travt - relat + etut |
153 |
|
154 |
# Find the time at SSB
|
155 |
ssbtim = [ftime[0], ftime[1]+int(((travt - relat + etut) * 8000.0) + 0.5)] |
156 |
|
157 |
# Handle overflow and underflow
|
158 |
if ssbtim[1] >= 691200000: |
159 |
ssbtim[1] = ssbtim[1] - 691200000 |
160 |
ssbtim[0] = ssbtim[0] + 1 |
161 |
elif ssbtim[1] < 0: |
162 |
ssbtim[1] = ssbtim[1] + 691200000 |
163 |
ssbtim[0] = ssbtim[0] - 1 |
164 |
|
165 |
# Return
|
166 |
return ssbtim, tdelta
|
167 |
|
168 |
|
169 |
# ====================== #
|
170 |
# Compute residual phase #
|
171 |
# ====================== #
|
172 |
def pula05(ctime, f, fdot, f2dot, dm, fobs, zphas, tm): |
173 |
"""
|
174 |
This routine implements the algorithm PUL-AL-005 to calculate the residual phase
|
175 |
corresponding to each photon arrival time at SSB.
|
176 |
"""
|
177 |
# Set constants
|
178 |
pow2 = 2147483647.0
|
179 |
|
180 |
# Make all in double precision
|
181 |
dmd = float(dm)
|
182 |
fobsd = float(fobs)
|
183 |
|
184 |
# Apply dispersion measure
|
185 |
if fobsd > 1.0e-6: |
186 |
the0 = (-dmd * 10000.0) / (2.41 * fobsd*fobsd) |
187 |
else:
|
188 |
the0 = 0.0
|
189 |
|
190 |
#
|
191 |
dt = float(ctime[0] - tm[0]) * 86400.0 + float(ctime[1] - tm[1]) / 8000.0 |
192 |
|
193 |
# Theta is the decimal residual of the formula below
|
194 |
x = the0 + (f * dt) + (fdot * dt*dt / 2.0) + (f2dot * dt*dt*dt / 6.0) + zphas |
195 |
|
196 |
# Accuracy checks
|
197 |
if abs(x) > pow2: |
198 |
npow = int(x / pow2)
|
199 |
x = x - (float(npow)*pow2)
|
200 |
|
201 |
# Calculate the residual by removing the integer part
|
202 |
resid = x - float(int(x)) |
203 |
|
204 |
# Fix if < 0
|
205 |
if resid < 0.0: |
206 |
resid = 1.0 + resid
|
207 |
|
208 |
# Return
|
209 |
return resid
|
210 |
|
211 |
|
212 |
# ===================== #
|
213 |
# Returns JPL ephemeris #
|
214 |
# ===================== #
|
215 |
def bvceph(jdutc, frc, nleap, filename='de200_new.fits'): |
216 |
"""
|
217 |
Reads and interpolates ephemeris files created from JPL data by the CONVERT
|
218 |
program, returning positions of the Earth and Sun with respect to the Solar
|
219 |
System barycenter (SSBC) and the difference between Ephemeris Time (TDB)
|
220 |
and Universal Time (UTC) at the same epoch.
|
221 |
"""
|
222 |
# Declare global variables
|
223 |
global jdch0
|
224 |
global earth
|
225 |
global sun
|
226 |
global tdbtdt
|
227 |
global tdtut
|
228 |
global tdbdot
|
229 |
|
230 |
# Set constants
|
231 |
ndaych = 16
|
232 |
daysec = 1.0 / 86400.0 |
233 |
xxx = 10.0343817
|
234 |
etatc = 32.184 - 0.0343817 |
235 |
|
236 |
# Choose set of coefficents to use; if out of range, read new chunk
|
237 |
nset = 1 + jdutc - jdch0
|
238 |
if nset > ndaych or nset < 1: |
239 |
|
240 |
# Open table
|
241 |
fits = gammalib.GFits(filename) |
242 |
ephem = fits.table('EPHEM')
|
243 |
|
244 |
# If this is the first call, open the file for direct access and
|
245 |
if jdch0 == 0: |
246 |
jd0 = int(ephem.real('TSTART')) |
247 |
jd1 = int(ephem.real('TSTOP')) |
248 |
|
249 |
# Read earth and sun positions and tdb-tdt from the ephemeris
|
250 |
# Get at-ut from the leap second table in a1utcf
|
251 |
jdch1 = min([jdutc+(ndaych-1),jd1]) |
252 |
jdch0 = jdch1 - (ndaych-1)
|
253 |
earth = [] |
254 |
sun = [] |
255 |
tdbtst = [] |
256 |
tdtut = [] |
257 |
tdbdot = [] |
258 |
for nset in range(ndaych): |
259 |
|
260 |
# Get record index (starting from 0)
|
261 |
nrec = nset + (jdch0-jd0) |
262 |
#print(nrec)
|
263 |
|
264 |
# Read information for one row
|
265 |
earth.append({'earth_x' : ephem['EARTH'][nrec,0], |
266 |
'earth_y' : ephem['EARTH'][nrec,1], |
267 |
'earth_z' : ephem['EARTH'][nrec,2], |
268 |
'earth_dx' : ephem['EARTH'][nrec,3], |
269 |
'earth_dy' : ephem['EARTH'][nrec,4], |
270 |
'earth_dz' : ephem['EARTH'][nrec,5], |
271 |
'earth_d2x' : ephem['EARTH'][nrec,6], |
272 |
'earth_d2y' : ephem['EARTH'][nrec,7], |
273 |
'earth_d2z' : ephem['EARTH'][nrec,8], |
274 |
'earth_d3x' : ephem['EARTH'][nrec,9], |
275 |
'earth_d3y' : ephem['EARTH'][nrec,10], |
276 |
'earth_d3z' : ephem['EARTH'][nrec,11]}) |
277 |
sun.append({'sun_x' : ephem['SUN'][nrec,0], |
278 |
'sun_y' : ephem['SUN'][nrec,1], |
279 |
'sun_z' : ephem['SUN'][nrec,2]}) |
280 |
tdbtdt.append(ephem['TIMEDIFF'][nrec])
|
281 |
|
282 |
# Compute tdtut
|
283 |
tdtut.append(etatc + nleap + xxx) |
284 |
|
285 |
# Close FITS file
|
286 |
fits.close() |
287 |
|
288 |
# Make rough computation of time derivative of tdb-tdt
|
289 |
for nset in range(ndaych-1): |
290 |
tdbdot.append(tdbtdt[nset+1]-tdbtdt[nset])
|
291 |
tdbtdt[ndaych-1] = tdbtdt[ndaych-2] |
292 |
|
293 |
# Set nset (starting from 1)
|
294 |
nset = 1 + (jdutc - jdch0)
|
295 |
|
296 |
# DEBUG
|
297 |
#print(nset-1)
|
298 |
|
299 |
# Now use taylor series to get the coordinates at the desired time
|
300 |
dt = frc + tdtut[nset-1] * daysec
|
301 |
dt2 = dt * dt |
302 |
dt3 = dt2 * dt |
303 |
etut = tdbtdt[nset-1] + dt * tdbdot[nset-1] + tdtut[nset-1] |
304 |
rcs = [sun[nset-1]['sun_x'], sun[nset-1]['sun_y'], sun[nset-1]['sun_z']] |
305 |
rce = [earth[nset-1]['earth_x'] + \ |
306 |
earth[nset-1]['earth_dx'] * dt + \ |
307 |
earth[nset-1]['earth_d2x'] * 0.5 * dt2 + \ |
308 |
earth[nset-1]['earth_d3x'] * 1.0/6.0 * dt3, |
309 |
earth[nset-1]['earth_y'] + \ |
310 |
earth[nset-1]['earth_dy'] * dt + \ |
311 |
earth[nset-1]['earth_d2y'] * 0.5 * dt2 + \ |
312 |
earth[nset-1]['earth_d3y'] * 1.0/6.0 * dt3, |
313 |
earth[nset-1]['earth_z'] + \ |
314 |
earth[nset-1]['earth_dz'] * dt + \ |
315 |
earth[nset-1]['earth_d2z'] * 0.5 * dt2 + \ |
316 |
earth[nset-1]['earth_d3z'] * 1.0/6.0 * dt3] |
317 |
vce = [(earth[nset-1]['earth_dx'] + earth[nset-1]['earth_d2x'] * dt) * daysec, |
318 |
(earth[nset-1]['earth_dy'] + earth[nset-1]['earth_d2y'] * dt) * daysec, |
319 |
(earth[nset-1]['earth_dz'] + earth[nset-1]['earth_d2z'] * dt) * daysec] |
320 |
|
321 |
# DEBUG
|
322 |
#print(dt)
|
323 |
|
324 |
# Return
|
325 |
return rce, etut
|
326 |
|
327 |
|
328 |
# =========== #
|
329 |
# pulphi task #
|
330 |
# =========== #
|
331 |
def pulphi(pars, evpname, bvcname, maxevents=10000000): |
332 |
"""
|
333 |
Generates barycentric times and pulse phases for a given pulsar and
|
334 |
outputs events lying in the given phase windows.
|
335 |
"""
|
336 |
# Set constants
|
337 |
zztic = 691200000
|
338 |
pimath = 3.14159265358979
|
339 |
|
340 |
# Read parameters
|
341 |
# CALL PPPTRD ( TPAR, PUNAME, PPTUN, EPOCH, PPT0, PPT1, PPT2, RAPU,
|
342 |
#1 DECPU, FOBS, DM, DISPU, BIPE, BIPED, BIOE, SEMA,
|
343 |
#2 PERI, PERID, TPERI, ZPHAS, G, RETGP, RETNO )
|
344 |
|
345 |
# Derive some items for printing and write the contents of the PPT
|
346 |
# and derived items in log file
|
347 |
timejd = float(pars['epoch'][0]) + float(pars['epoch'][1]) / (8000.0 * 86400.0) + 2440000.5 |
348 |
timemj = timejd - 2400000.5
|
349 |
print('%s%d.%d' % (gammalib.parformat('Pulsar epoch'), pars['epoch'][0], pars['epoch'][1])) |
350 |
print('%s%f' % (gammalib.parformat('Pulsar epoch JD'), timejd)) |
351 |
print('%s%f' % (gammalib.parformat('Pulsar epoch MJD'), timemj)) |
352 |
|
353 |
# Convert frequency to true units
|
354 |
f0 = pars['ppt0']
|
355 |
fdot = pars['ppt1'] * 1.0e-12 |
356 |
f2dot = pars['ppt2'] * 1.0e-20 |
357 |
print('%s%f' % (gammalib.parformat('Frequency'), f0)) |
358 |
print('%s%e' % (gammalib.parformat('Frequency derivative'), fdot)) |
359 |
print('%s%e' % (gammalib.parformat('Second freq. derivative'), f2dot)) |
360 |
|
361 |
# Write rest to log file
|
362 |
print('%s%f' % (gammalib.parformat('Right Ascension'), pars['rapu'])) |
363 |
print('%s%f' % (gammalib.parformat('Declination'), pars['decpu'])) |
364 |
print('%s%f' % (gammalib.parformat('Radio frequency'), pars['fobs'])) |
365 |
print('%s%f' % (gammalib.parformat('Dispersion measure'), pars['dm'])) |
366 |
print('%s%f' % (gammalib.parformat('Pulsar distance'), pars['dispu'])) |
367 |
print('%s%f' % (gammalib.parformat('Radio phase'), pars['zphas'])) |
368 |
|
369 |
# Open EVP dataset
|
370 |
evpfile = gammalib.GFits(evpname) |
371 |
evp = evpfile.table('COMPTEL_EVP')
|
372 |
#print(evp.header())
|
373 |
|
374 |
# Calculate the centre time of the current observation
|
375 |
intsta = [evp.integer('VISDAY'), evp.integer('VISTIM')] |
376 |
intend = [evp.integer('VIEDAY'), evp.integer('VIETIM')] |
377 |
tm = [int(intsta[0]+intend[0]/2), int(intsta[1]+intend[1]/2)] |
378 |
|
379 |
# Check to make sure half a day is not lost
|
380 |
if 2*tm[0] == (intsta[0] + intend[0] - 1): |
381 |
tm[1] = tm[1] + 345600000 |
382 |
if tm[1] >= zztic: |
383 |
tm[1] = tm[1] - zztic |
384 |
tm[0] = tm[0] + 1 |
385 |
|
386 |
# Centre in JD
|
387 |
tmjd = float(tm[0]) + float(tm[1]) / (8000.0 * 86400.0) + 2440000.5 |
388 |
|
389 |
# Centre in MJD
|
390 |
tmmj = tmjd - 2400000.0
|
391 |
|
392 |
# Calculate the length of the current observation
|
393 |
dt = (float(intend[0] - intsta[0]) * 86400.0) + (float(intend[1] - intsta[1]) / 8000.0) |
394 |
|
395 |
# Use AL-032 to extapolate the pulsar frequency, derivative and zero phase to the
|
396 |
# center of the epoch
|
397 |
f0e, fdote, zphasp = pula32(f0, fdot, f2dot, pars['zphas'], pars['epoch'], tm) |
398 |
|
399 |
# Calculate the cosinus of the pulsar direction
|
400 |
ra = pars['rapu'] * (pimath/180.0) |
401 |
d = pars['decpu'] * (pimath/180.0) |
402 |
pos1 = math.cos(d) * math.cos(ra) |
403 |
pos2 = math.cos(d) * math.sin(ra) |
404 |
pos3 = math.sin(d) |
405 |
|
406 |
# Open the BVC dataset for SSB vectors
|
407 |
bvcfile = gammalib.GFits(bvcname) |
408 |
bvc = bvcfile.table('COMPTEL_BVC')
|
409 |
#print(bvc.header())
|
410 |
|
411 |
# Get the first 2 vectors
|
412 |
start, ssb1, etut = pbvcrr(bvc, 0)
|
413 |
endt, ssb2, etut = pbvcrr(bvc, 1)
|
414 |
|
415 |
# Open ASCII result file
|
416 |
f = open('pulphi.dat', 'w') |
417 |
|
418 |
# Main event processing loop
|
419 |
ievp = 0
|
420 |
ibvc = 2
|
421 |
nevin = 0
|
422 |
nevout = 0
|
423 |
scan = True
|
424 |
while scan:
|
425 |
|
426 |
# Read event time
|
427 |
fftime = pevpsr(evp, ievp) |
428 |
ievp += 1
|
429 |
|
430 |
# Increment number of input events
|
431 |
nevin = nevin + 1
|
432 |
|
433 |
# Make time correction if necessary
|
434 |
if (fftime[0] < 8798) or ((fftime[0] == 8798) and (fftime[1] < .28800000)): |
435 |
ftime = [fftime[0], fftime[1] - (2.042144 * 8000.0)] |
436 |
if ftime[1] < 0.0: |
437 |
ftime[0] = ftime[0] - 1 |
438 |
ftime[1] = ftime[1] + zztic |
439 |
else:
|
440 |
ftime = [fftime[0], fftime[1]] |
441 |
|
442 |
# While the event time is after the end of validity of the current
|
443 |
# SSB vector get the next one.
|
444 |
while True: |
445 |
|
446 |
# If arrival time is < first time in BVC
|
447 |
if (ftime[0] < start[0]) or ((ftime[0] == start[0]) and (ftime[1] < start[1])): |
448 |
tdif = float(ftime[0] - start[0]) * 86400.0 + float(ftime[1] - start[1]) / 8000.0 |
449 |
print('<<< %d:%d %e %d:%d' % (ftime[0],ftime[1],tdif,start[0],start[1])) |
450 |
ssb = [ssb1[0],ssb1[1],ssb1[2]] |
451 |
break
|
452 |
|
453 |
# If arrival time is within the interval supplied (START < t < ENDT)
|
454 |
elif ((ftime[0] > start[0]) or ((ftime[0] == start[0]) and (ftime[1] > start[1]))) and \ |
455 |
((ftime[0] < endt[0]) or ((ftime[0] == endt[0]) and (ftime[1] <= endt[1]))) : |
456 |
tdif = float(endt[0] - start[0]) * 86400.0 + float(endt[1] - start[1]) / 8000.0 |
457 |
if tdif > 900.0: |
458 |
print('=== %d:%d %e' % (ftime[0],ftime[1],tdif,start[0],start[1])) |
459 |
ssb = pulbvc(ftime, start, endt, ssb1, ssb2) |
460 |
break
|
461 |
|
462 |
# If arrival time is > ENDT
|
463 |
elif (ftime[0] > endt[0]) or ((ftime[0] == endt[0]) and (ftime[1] > endt[1])): |
464 |
|
465 |
# Replace start by endt
|
466 |
start[0] = endt[0] |
467 |
start[1] = endt[1] |
468 |
ssb1[0] = ssb2[0] |
469 |
ssb1[1] = ssb2[1] |
470 |
ssb1[2] = ssb2[2] |
471 |
|
472 |
# Was end of BVC file reached?
|
473 |
if ibvc >= bvc.nrows():
|
474 |
print('*** End of BVC file reached. Stop')
|
475 |
scan = False
|
476 |
break
|
477 |
|
478 |
# Read new BVC vector
|
479 |
endt, ssb2, etut = pbvcrr(bvc, ibvc) |
480 |
ibvc += 1
|
481 |
|
482 |
# Was end of BVC file reached?
|
483 |
if not scan: |
484 |
break
|
485 |
|
486 |
# Correct the photon arrival time using SSB vector 1
|
487 |
ssbtim, tdelta = pula04(ftime, ssb, pos1, pos2, pos3, etut) |
488 |
|
489 |
# Do not consider binary
|
490 |
ctime = [ssbtim[0],ssbtim[1]] |
491 |
|
492 |
# Calculate phase residuals
|
493 |
resid = pula05(ctime, f0e, fdote, f2dot, pars['dm'], pars['fobs'], zphasp, tm) |
494 |
|
495 |
# Write result in ASCII file
|
496 |
f.write('%8d %4.4d:%9.9d %4.4d:%9.9d %4.4d:%9.9d %14.8f %10.8f\n' %
|
497 |
(ievp-1, fftime[0], fftime[1], ftime[0], ftime[1], ctime[0], ctime[1], tdelta, resid)) |
498 |
|
499 |
# Was end of EVP file reached?
|
500 |
if ievp >= evp.nrows():
|
501 |
print('*** End of EVP file reached. Stop')
|
502 |
scan = False
|
503 |
break
|
504 |
|
505 |
# Was maximum number of events reached?
|
506 |
if ievp >= maxevents:
|
507 |
print('*** Maximum number of events reached. Stop')
|
508 |
scan = False
|
509 |
break
|
510 |
|
511 |
# Close ASCII file
|
512 |
f.close() |
513 |
|
514 |
# Return
|
515 |
return
|
516 |
|
517 |
|
518 |
# ================================ #
|
519 |
# Convert parameters into PPT file #
|
520 |
# ================================ #
|
521 |
def pulcpp(pars): |
522 |
"""
|
523 |
Convert parameters into PPT file
|
524 |
"""
|
525 |
# Set constants
|
526 |
mj1968 = 2400000
|
527 |
daysec = 24.0 * 3600.0 |
528 |
convd = 4.0 * math.atan(1.0) / 180.0 |
529 |
rsw = 0.49254909e-5
|
530 |
factor = [1.0, 0.5, 1.0/6.0] |
531 |
|
532 |
# Convert EPOCH(1) from TJD to MJD
|
533 |
epoch = [int(pars['t0geo']) - 40000.0, 0] |
534 |
#tgeoin = int(pars['epoch'][0] + 40000)
|
535 |
tgeoin = int(pars['t0geo']) |
536 |
print('%s%d' % (gammalib.parformat('Integer part Tgeo (MJD)'), tgeoin)) |
537 |
|
538 |
#
|
539 |
#dgeofr = pars['tgeofr']
|
540 |
dgeofr = pars['t0geo'] - tgeoin
|
541 |
print('%s%e' % (gammalib.parformat('Fraction part Tgeo (MJD)'), dgeofr)) |
542 |
|
543 |
#
|
544 |
tpkcor = pars['tpkcor']
|
545 |
print('%s%f' % (gammalib.parformat('Correction to Tgeo (ms)'), tpkcor)) |
546 |
tpkcr8 = float(tpkcor) * 1.0e-3 / daysec |
547 |
print('%s%f' % (gammalib.parformat('Correction to Tgeo (days)'), tpkcr8)) |
548 |
|
549 |
#
|
550 |
jd = int(tgeoin + mj1968 + 1) |
551 |
|
552 |
#
|
553 |
aid1 = dgeofr |
554 |
aid2 = tpkcr8 |
555 |
aid3 = 0.5
|
556 |
|
557 |
#
|
558 |
frc = aid1 + aid2 - aid3 |
559 |
print('%s%d' % (gammalib.parformat('Calculated JD (int)'), jd)) |
560 |
print('%s%f' % (gammalib.parformat('Calculated JD (frac)'), frc)) |
561 |
|
562 |
#
|
563 |
f = pars['ppt0']
|
564 |
fdot = pars['ppt1'] * 1.0e-12 |
565 |
fddot = pars['ppt2'] * 1.0e-20 |
566 |
|
567 |
# Compute number of leap seconds (-10)
|
568 |
nleap = pars['nleap']
|
569 |
print('%s%d' % (gammalib.parformat('Number of Leap seconds'), nleap)) |
570 |
|
571 |
#
|
572 |
freqt = [f, fdot, fddot] |
573 |
print('%s%f' % (gammalib.parformat('Frequency'), freqt[0])) |
574 |
print('%s%e' % (gammalib.parformat('Frequency derivative'), freqt[1])) |
575 |
print('%s%e' % (gammalib.parformat('Second freq. derivative'), freqt[2])) |
576 |
|
577 |
#
|
578 |
decdp = pars['decpu'] * convd
|
579 |
radp = pars['rapu'] * convd
|
580 |
|
581 |
#
|
582 |
pos1 = math.cos(decdp) * math.cos(radp) |
583 |
pos2 = math.cos(decdp) * math.sin(radp) |
584 |
pos3 = math.sin(decdp) |
585 |
print('%s%f' % (gammalib.parformat('Pos1'), pos1)) |
586 |
print('%s%f' % (gammalib.parformat('Pos2'), pos2)) |
587 |
print('%s%f' % (gammalib.parformat('Pos3'), pos3)) |
588 |
|
589 |
#
|
590 |
print('%s%f' % (gammalib.parformat('Pulsar position RA 2000'), radp/convd)) |
591 |
print('%s%f' % (gammalib.parformat('Pulsar position DEC2000'), decdp/convd)) |
592 |
|
593 |
#
|
594 |
rce, etut0 = bvceph(jd, frc, nleap) |
595 |
|
596 |
#
|
597 |
ctest = nleap + 10 + 32.184 |
598 |
etut = etut0 |
599 |
dtest = etut - ctest |
600 |
|
601 |
#
|
602 |
ssb = [rce[0], rce[1], rce[2]] |
603 |
|
604 |
# Calculate traveltime from SSB to site (0,0,0) for source at (POSX,POSY,POSZ)
|
605 |
bclt = ssb[0]*pos1 + ssb[1]*pos2 + ssb[2]*pos3 |
606 |
ssbnrm = math.sqrt(ssb[0]*ssb[0] + ssb[1]*ssb[1] + ssb[2]*ssb[2]) |
607 |
|
608 |
# Relativistic delay
|
609 |
relat = -2.0 * rsw * math.log(1.0 + bclt / ssbnrm) |
610 |
|
611 |
# Time difference (in sec) between Arrival at SSB and nominal epoch
|
612 |
delay = bclt - relat + etut |
613 |
|
614 |
# Log
|
615 |
print('%s%f sec' % (gammalib.parformat('UTC--> TDT'), ctest)) |
616 |
print('%s%f sec' % (gammalib.parformat('TDT--> TDB'), dtest)) |
617 |
print('%s%f sec' % (gammalib.parformat('UTC--> TDB'), etut0)) |
618 |
print('%s%f sec' % (gammalib.parformat('Traveltime difference'), bclt)) |
619 |
print('%s%f sec' % (gammalib.parformat('Relativistic delay'), relat)) |
620 |
print('%s%f sec' % (gammalib.parformat('Total delay'), delay)) |
621 |
|
622 |
#
|
623 |
difsec = (dgeofr + tpkcr8) * daysec + delay |
624 |
print('%s%f sec' % (gammalib.parformat('Time diff. to nom. epoch'), difsec)) |
625 |
|
626 |
#
|
627 |
radiof = 0.0
|
628 |
dlyaid = 1.0
|
629 |
for i in range(3): |
630 |
dlyaid = dlyaid * difsec |
631 |
radiof = radiof + factor[i] * freqt[i] * dlyaid |
632 |
|
633 |
#
|
634 |
radiof = radiof - int(radiof)
|
635 |
|
636 |
#
|
637 |
if radiof < 0.0: |
638 |
radiof = radiof + 1.0
|
639 |
|
640 |
#
|
641 |
zphas = radiof |
642 |
print('%s%f' % (gammalib.parformat('Radio-phase 0 at nom.epoch'), zphas)) |
643 |
|
644 |
#
|
645 |
zphas = -zphas |
646 |
|
647 |
# Set parameters
|
648 |
pars['epoch'] = epoch
|
649 |
pars['zphas'] = zphas
|
650 |
|
651 |
# Return
|
652 |
return pars
|
653 |
|
654 |
|
655 |
# ======================== #
|
656 |
# Main routine entry point #
|
657 |
# ======================== #
|
658 |
if __name__ == '__main__': |
659 |
|
660 |
# Line 53 of psrtime file
|
661 |
#0531+21 05 34 31.972 22 00 52.07 48377 48407 48392.000000224 29.9485663280898 -3.77641D-10 0.00D+00 1.5 J
|
662 |
|
663 |
# Set pulsar parameters
|
664 |
#pars = {'epoch': [48392, 0],
|
665 |
# 'tgeofr': 0.000000224,
|
666 |
pars = {'t0geo' : 48392.000000224, |
667 |
'tpkcor' : 0.0, |
668 |
'ppt0' : 29.9485663280898, |
669 |
'ppt1' : -377.641, |
670 |
'ppt2' : 0.0, |
671 |
'rapu' : 83.6331, |
672 |
'decpu' : 22.0145, |
673 |
'fobs' : 0.0, |
674 |
'dm' : 0.0, |
675 |
'dispu' : 0.0, |
676 |
'nleap' : 16} # valid between 1990-12-31 and 1992-06-30 |
677 |
|
678 |
# Set filenames
|
679 |
evpname = '$COMDATA/phase01/vp0001_0/m28511_evp.fits'
|
680 |
bvcname = '$COMDATA/phase01/vp0001_0/s10150_bvc.fits'
|
681 |
|
682 |
# Compute zphas using the pulcpp task
|
683 |
pars = pulcpp(pars) |
684 |
|
685 |
# Run task
|
686 |
pulphi(pars, evpname, bvcname, maxevents=100)
|