This repository has been archived by the owner on Oct 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathjson_parse.py
113 lines (90 loc) · 4.48 KB
/
json_parse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#! /usr/bin/env python2
# Copyright (c) 2012 Victor Terron. All rights reserved.
# Institute of Astrophysics of Andalusia, IAA-CSIC
#
# This file is part of LEMON.
#
# LEMON is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import collections
import copy
import json
import operator
# LEMON modules
import passband
typename = "CandidateAnnuli"
field_names = "aperture, annulus, dannulus, stdev"
class CandidateAnnuli(collections.namedtuple(typename, field_names)):
"""Encapsulate the quality of a set of photometric parameters.
How do we determine how good a set of parameters for aperture photometry
is? In order to compare them, we need to identify the most constant stars
(or, by extension, any other astronomical object) in the field and compute
their light curves. The better the aperture, annulus and dannulus that we
use are, the lower the standard deviation of the resulting curves.
This class simply encapsulates these four values, mapping the parameters
for aperture photometry (aperture, annulus and dannulus) to the standard
deviation of the light curves of the most constant astronomical objects.
Fields:
aperture - the aperture radius, in pixels.
annulus - the inner radius of the sky annulus, in pixels.
dannulus - the width of the sky annulus, in pixels.
stdev - the median, arithmetic mean or a similar statistical measure of the
standard deviation of the light curves of the astronomical objects
when photometry is done using these aperture, annulus and dannulus
values.
"""
@staticmethod
def dump(annuli, path):
"""Save a series of CadidateAnnuli objects to a JSON file.
Serialize 'annuli' to a JSON file. It must be a dictionary which maps
each photometric filter (a Passband object) to a sequence of the
corresponding CandidateAnnuli objects -- i.e., the different aperture
photometric parameters that were evaluated for that filter. The output
file will be mercilessly overwritten if it already exists.
"""
# Being a subclass of tuple, JSON serializes namedtuples as lists. We
# need to convert them to ordered dictionaries (namedtuple._asdict())
# first, so that the field names are not lost in the serialization.
data = copy.deepcopy(annuli)
for values in data.itervalues():
for index in xrange(len(values)):
values[index] = values[index]._asdict()
values.sort(key=operator.itemgetter("stdev"))
# Use strings, not Passband objects, as keys
for pfilter in data.keys():
data[str(pfilter)] = data.pop(pfilter)
with open(path, "wt") as fd:
kwargs = dict(indent=2, sort_keys=True)
json.dump(data, fd, **kwargs)
@classmethod
def load(cls, path):
"""Load a series of CandidateAnnuli objects from a JSON file.
Deserialize a JSON file created with CandidateAnnuli.dump(), returning
a dictionary which maps each photometric filter (a Passband object) to
a list of the corresponding CandidateAnnuli objects. These lists are
sorted in increasing order by the standard deviation ('stdev' attribute
of the namedtuples), so that the one with the lowest standard deviation
(and therefore the optimal for aperture photometry) is returned first.
"""
with open(path, "rt") as fd:
data = json.load(fd)
# Convert the dictionaries back to namedtuples, and then sort them by
# their standard deviation, in increasing order.
for values in data.itervalues():
for index in xrange(len(values)):
values[index] = cls(**values[index])
values.sort(key=operator.attrgetter("stdev"))
# Use Passband objects as keys
for pfilter in data.keys():
data[passband.Passband(pfilter)] = data.pop(pfilter)
return data