Skip to content

Commit 7bc307b

Browse files
Merge remote-tracking branch 'upstream/develop' into develop
2 parents 4d98d03 + a67c889 commit 7bc307b

19 files changed

Lines changed: 669 additions & 84 deletions

cs_util/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""cs_util PACKAGE.
42
53
Provide a basic description of what your package contains.

cs_util/canfar.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
"""CANFAR TOOLS.
2+
3+
This module defines methods for managing CANFAR specific actions.
4+
5+
:Author: Samuel Farrens <samuel.farrens@cea.fr>
6+
Martin Kilbinger <martin.kilbinger@cea.fr>
7+
8+
"""
9+
10+
import os
11+
import sys
12+
from contextlib import redirect_stdout
13+
from io import StringIO
14+
15+
import vos.commands as vosc
16+
17+
18+
class vosError(Exception):
19+
"""VOS Error.
20+
21+
Generic error that is raised by the vosHandler.
22+
23+
"""
24+
25+
pass
26+
27+
28+
class vosHandler:
29+
"""VOS Handler.
30+
31+
This class manages the use of VOS commands.
32+
33+
Parameters
34+
----------
35+
command : str
36+
VOS command name
37+
38+
"""
39+
40+
def __init__(self, command):
41+
42+
self._check_vos_install()
43+
self._avail_commands = tuple(vosc.__all__)
44+
self.command = command
45+
46+
@staticmethod
47+
def _check_vos_install():
48+
"""Check VOS Install.
49+
50+
Check if VOS is correctly installed.
51+
52+
Raises
53+
------
54+
ImportError
55+
if vos package cannot be imported
56+
57+
"""
58+
if import_fail:
59+
raise ImportError('vos package not found')
60+
61+
@property
62+
def command(self):
63+
"""Set Command.
64+
65+
This method sets the VOS command property.
66+
67+
Raises
68+
------
69+
ValueError
70+
if value is not valid vos command
71+
72+
"""
73+
return self._command
74+
75+
@command.setter
76+
def command(self, value):
77+
78+
if value not in self._avail_commands:
79+
raise ValueError(
80+
f'vos command must be one of {self._avail_commands}'
81+
)
82+
83+
self._command = getattr(vosc, value)
84+
85+
def __call__(self, *args, **kwargs):
86+
"""Call Method.
87+
88+
This method allows class instances to be called as functions.
89+
90+
Raises
91+
------
92+
vosError
93+
if error in vos command occurs
94+
95+
"""
96+
try:
97+
self._command()
98+
99+
except Exception:
100+
raise vosError(
101+
f'Error in VOs command: {self._command.__name__}'
102+
)
103+
104+
105+
def download(source, target, verbose=False):
106+
"""Download.
107+
108+
Download file from vos.
109+
110+
Parameters
111+
----------
112+
source : str
113+
source path on vos
114+
target : str
115+
target path
116+
verbose : bool, optional, default=False
117+
verbose output if True
118+
119+
Returns
120+
-------
121+
status : bool
122+
status, True/False or success/failure
123+
124+
"""
125+
cmd = 'vcp'
126+
127+
if not os.path.exists(target):
128+
sys.argv = [cmd, source, target]
129+
if verbose:
130+
print(f'Downloading file {source} to {target}...')
131+
vcp = vosHandler(cmd)
132+
133+
vcp()
134+
if verbose:
135+
print('Download finished.')
136+
else:
137+
if verbose:
138+
print(f'Target file {target} exists, skipping download.')
139+
140+
141+
def dir_list(path, verbose=False):
142+
"""Set Directory List.
143+
144+
List content of path on vos.
145+
146+
Parameters
147+
----------
148+
path : str
149+
path on vos, starts with 'vos:cfis/...'
150+
verbose : bool, optional, default=False
151+
verbose output if True
152+
153+
Raises
154+
------
155+
HTTPError, KeyError
156+
if error occurs during vos command
157+
158+
Returns
159+
-------
160+
list
161+
file or directory at path, type is str
162+
163+
"""
164+
cmd = 'vls'
165+
sys.argv = [cmd, path]
166+
vls = vosHandler(cmd)
167+
168+
if verbose:
169+
print('Getting vos directory content from vls...')
170+
171+
f = StringIO()
172+
173+
try:
174+
with redirect_stdout(f):
175+
vls()
176+
except Exception:
177+
print('Error during vls command')
178+
raise
179+
180+
vls_out = f.getvalue()
181+
182+
return vls_out.split('\n')

cs_util/cat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
:Description: This script contains methods to read and write galaxy catalogues.
66
7-
:Author: Martin Kilbinger
7+
:Author: Martin Kilbinger <martin.kilbinger@cea.fr>
88
99
"""
1010

cs_util/cfis.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
"""CFIS.
2+
3+
:Name: cfis.py
4+
5+
:Description: This script contains CFIS-specific methods.
6+
7+
:Author: Martin Kilbinger <martin.kilbinger@cea.fr>
8+
9+
"""
10+
11+
12+
import re
13+
import numpy as np
14+
from astropy import units
15+
from astropy import coordinates as coords
16+
17+
18+
class Cfis(object):
19+
"""Cfis
20+
21+
Class for CFIS image properties.
22+
23+
"""
24+
size = {'tile' : 0.5 * units.deg}
25+
26+
27+
def get_tile_number(tile_name):
28+
"""Get Tile Number.
29+
30+
Return tile number of given image tile name.
31+
32+
Parameters
33+
----------
34+
tile_name : str
35+
tile name
36+
37+
Raises
38+
------
39+
ValueError
40+
if tile name does not match expected pipeline numbering scheme
41+
42+
Returns
43+
-------
44+
tuple
45+
tile number for x and tile number for y
46+
47+
"""
48+
m = re.search(r'(\d{3})[\.-](\d{3})', tile_name)
49+
if m is None or len(m.groups()) != 2:
50+
raise ValueError(
51+
f'Image name \'{tile_name}\' does not match tile name syntax'
52+
)
53+
54+
nix = m.groups()[0]
55+
niy = m.groups()[1]
56+
57+
return nix, niy
58+
59+
60+
def get_tile_coord_from_nixy(nix, niy):
61+
"""Get Tile Coord From Nixy.
62+
63+
Return coordinates corresponding to tile with number (nix,niy).
64+
65+
Parameters
66+
----------
67+
nix : str or list
68+
tile number(s) for x coordinate(s);
69+
niy : str or list
70+
tile number(s) for y coordinate(s)
71+
72+
See also
73+
--------
74+
get_tile_number_from_coord
75+
76+
Returns
77+
-------
78+
tuple
79+
right ascension and declination
80+
81+
"""
82+
number_pattern = re.compile(r'\d{3}')
83+
84+
# Transform from str to int
85+
if not np.isscalar(nix):
86+
# Check input numbers
87+
if not all(
88+
[bool(number_pattern.fullmatch(number)) for number in nix + niy]
89+
):
90+
raise ValueError('Input needs to be three-digit numbers')
91+
92+
# Transform to list
93+
xi = np.array(nix).astype(int)
94+
yi = np.array(niy).astype(int)
95+
else:
96+
if not all(
97+
[bool(number_pattern.fullmatch(number)) for number in [nix, niy]]
98+
):
99+
raise ValueError('Input needs to be three-digit numbers')
100+
101+
xi = int(nix)
102+
yi = int(niy)
103+
104+
# Declination
105+
d = yi / 2 - 90
106+
dec = coords.Angle(d, unit='deg')
107+
108+
# Right ascension
109+
r = xi / 2 / np.cos(dec.radian)
110+
ra = coords.Angle(r, unit='deg')
111+
112+
return ra, dec

0 commit comments

Comments
 (0)