野辺山宇宙電波観測所の LST を計算する

# これは何か

[野辺山宇宙電波観測所](https://www.nro.nao.ac.jp/) の LST を計算する python スクリプトです。観測時間に遅れないようにしましょう。

# ソース
```python
import dateutil
import dateutil.rrule
import astropy.coordinates
import astropy.time

from astropy.units import deg
from astropy.units import m

def calc_lst(location, datetime_):
    localtime = astropy.time.Time(datetime_, format='datetime', location=location)
    return localtime.sidereal_time('apparent')

def daily_timeseries(date, timezone, interval):
    tzdate = dateutil.parser.parse(
        '{date} 00:00:00 TZ'.format(**locals()), 
        tzinfos = {'TZ': dateutil.tz.gettz(timezone)},
    )

    series = list(dateutil.rrule.rrule(
        freq = dateutil.rrule.MINUTELY, 
        interval = interval, 
        dtstart = tzdate,
        until = tzdate + dateutil.relativedelta.relativedelta(hours=+24),
    ))
    
    return series[:-1]


def daily_lst(location, date, timezone, interval=10):
    timeseriese = daily_timeseries(date, timezone, interval)
    lst = calc_lst(location, timeseriese)
    return timeseriese, lst

def print_lst(location, date, timezone, interval=10):
    localtime, lst = daily_lst(location, date, timezone, interval)
    
    sep = '-'*18
    print('{date} ({timezone})'.format(**locals()))
    print()
    print('Time    --    LST')
    hour0 = None
    for _lt, _lst in zip(localtime, lst):
        _lt_ = _lt.strftime('%H:%M')
        _lst_h = int(_lst.hour)
        _lst_m = int((_lst.hour - _lst_h) * 60)
        _lst_ = '{_lst_h:02d}:{_lst_m:02d}'.format(**locals())
        
        if hour0 != _lst_h:
            print(sep)
            hour0 = _lst_h
            pass
        
        print('{_lt_}  --  {_lst_}'.format(**locals()))
        continue
```

## 実行例
```python
# 観測地点を定義します
nro45 = astropy.coordinates.EarthLocation(
    lon = (138 + 28/60 + 21.2/3600) * deg,
    lat = (35 + 56/60 + 40.9/3600)  * deg,
    height = 1350 * m,
)

# 観測地点、日付とタイムゾーンを指定します
print_lst(nro45, '2019/1/4', 'Asia/Tokyo')
```

## 出力
```
2019/1/4 (Asia/Tokyo)

Time    --    LST
------------------
00:00  --  07:05
00:10  --  07:15
00:20  --  07:25
00:30  --  07:35
00:40  --  07:45
00:50  --  07:55
------------------
01:00  --  08:05
01:10  --  08:15
...
22:40  --  05:49
22:50  --  05:59
------------------
23:00  --  06:09
23:10  --  06:19
23:20  --  06:29
23:30  --  06:39
23:40  --  06:49
23:50  --  06:59
```


# 端末 / jupyter でリアルタイムに更新される時計

```python
import sys
import time
import datetime
import dateutil
import dateutil.parser
import astropy.coordinates

from astropy.units import deg
from astropy.units import m

def calc_lst(location, datetime_):
    localtime = astropy.time.Time(datetime_, format='datetime', location=location)
    return localtime.sidereal_time('apparent')

def now(timezone):
    _now = datetime.datetime.now()
    tzdate = dateutil.parser.parse(
        '{_now} TZ'.format(**locals()), 
        tzinfos = {'TZ': dateutil.tz.gettz(timezone)},
    )
    return tzdate

def print_lst(location, timezone, interval=0.2):
    t0 = 0
    try:
        while True:
            t1 = time.time()
            if (t1 - t0) < interval: 
                time.sleep(0.01)
                continue
            t0 = t1
            localtime = now(timezone)
            lst = calc_lst(location, localtime)
            lst_h = int(lst.hour)
            lst_m = int((lst.hour - lst_h) * 60)
            lst_s = int((lst.hour - lst_h - lst_m/60) * 3600)
            lst_ = '{lst_h:02d}:{lst_m:02d}:{lst_s:02d}'.format(**locals())
            msg = '{localtime:%Y.%m.%d} {localtime:%H:%M:%S} - LST {lst_}'.format(**locals())
            sys.stdout.write('\r' + msg)
            sys.stdout.flush()
            continue
    except KeyboardInterrupt:
        pass

nro45 = astropy.coordinates.EarthLocation(
    lon = (138 + 28/60 + 21.2/3600) * deg,
    lat = (35 + 56/60 + 40.9/3600)  * deg,
    height = 1350 * m,
)

print_lst(nro45, 'Asia/Tokyo')
```