-
Notifications
You must be signed in to change notification settings - Fork 24
/
desi_purge_tilenight
executable file
·151 lines (127 loc) · 5.9 KB
/
desi_purge_tilenight
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python
# coding: utf-8
import argparse
from desispec.io.meta import findfile
from desispec.workflow.exptable import get_exposure_table_pathname
from desispec.workflow.proctable import get_processing_table_pathname
from desispec.workflow.tableio import load_table, write_table
import os
import glob
import shutil
import sys
import numpy as np
import time
def get_parser():
"""
Creates an arguments parser for the desi_purge_tilenight script
"""
parser = argparse.ArgumentParser(usage = "{prog} [options]")
parser.add_argument("-n", "--night", type=int, required=True,
help="Night that the tile was observed.")
parser.add_argument("-t", "--tiles", type=str, required=True,
help="Tiles to remove from current prod. (comma separated)")
parser.add_argument("--not-dry-run", action="store_true",
help="set to actually perform action rather than print actions")
return parser
def remove_directory(dirname, dry_run=True):
"""
Remove the given directory from the file system
Args:
dirname, str. Full pathname to the directory you want to remove
dru_run, bool. True if you want to print actions instead of performing them.
False to actually perform them.
"""
if os.path.exists(dirname):
print(f"Identified directory {dirname} as existing.")
print(f"Dir has contents: {os.listdir(dirname)}")
if dry_run:
print(f"Dry_run set, so not performing action.")
else:
print(f"Removing: {dirname}")
shutil.rmtree(dirname)
else:
print(f"Directory {dirname} doesn't exist, so no action required.")
def purge_tilenight(tiles, night, dry_run=True):
"""
Removes all files assosciated with tiles on a given night.
Removes preproc files, exposures files including frames, redrock files
for perexp and pernight, and cumulative redshifts for nights on or
after the night in question. Only exposures assosciated with the tile
on the given night are removed.
Args:
tiles, list of int. Tile to remove from current prod.
night, int. Night that tiles were observed.
dry_run, bool. If True, only prints actions it would take
Note: does not yet remove healpix redshifts touching this tile
"""
if night is None:
raise ValueError("Must specify night.")
if tiles is None:
raise ValueError("Must specify list of tiles.")
epathname = get_exposure_table_pathname(night=str(night), usespecprod=True)
etable = load_table(tablename=epathname, tabletype='exptable')
print(f'Purging night {night} tiles {tiles}')
for tile in tiles:
print(f'Purging tile {tile}')
exptable = etable[etable['TILEID'] == tile]
## Per exposure: remove preproc, exposure, and perexp redshift dirs
for row in exptable:
expid = int(row['EXPID'])
for ftype in ['preproc', 'frame']:
dirname = os.path.dirname(findfile(filetype=ftype, night=night,
expid=expid, camera='b0',
spectrograph=0, tile=tile))
remove_directory(dirname, dry_run)
groupname = 'perexp'
ftype = 'redrock_tile'
dirname = os.path.dirname(findfile(filetype=ftype, night=night,
expid=expid, camera='b0',
spectrograph=0, tile=tile,
groupname=groupname))
remove_directory(dirname, dry_run)
## Remove the pernight redshift directory if it exists
groupname = 'pernight'
ftype = 'redrock_tile'
dirname = os.path.dirname(findfile(filetype=ftype, night=night,
camera='b0', spectrograph=0,
tile=tile, groupname=groupname))
remove_directory(dirname, dry_run)
## Look at all cumulative redshifts and remove any that would include the
## give tile-night data (any THRUNIGHT on or after the night given)
groupname = 'cumulative'
ftype = 'redrock_tile'
tiledirname = os.path.dirname(os.path.dirname(
findfile(filetype=ftype, night=night, camera='b0', spectrograph=0,
tile=tile, groupname=groupname)))
if os.path.exists(tiledirname):
thrunights = os.listdir(tiledirname)
for thrunight in thrunights:
if int(thrunight) >= night:
dirname = os.path.join(tiledirname,thrunight)
remove_directory(dirname, dry_run)
## Load old processing table
timestamp = time.strftime('%Y%m%d_%Hh%Mm')
ppathname = get_processing_table_pathname(prodmod=str(night))
ptable = load_table(tablename=ppathname, tabletype='proctable')
## Now let's remove the tiles from the processing table
keep = np.isin(ptable['TILEID'], tiles, invert=True)
print('Removing {}/{} processing table entries'.format(
len(keep)-np.sum(keep), len(keep)))
ptable = ptable[keep]
if dry_run:
print(f'dry_run: not changing {ppathname}')
else:
print(f'Archiving old processing table (timestamp {timestamp}) and saving trimmed one')
## move old processing table out of the way
os.rename(ppathname,ppathname.replace('.csv',f".csv.{timestamp}"))
## save new trimmed processing table
write_table(ptable,tablename=ppathname)
if __name__ == '__main__':
parser = get_parser()
args = parser.parse_args()
args.tiles = [int(t) for t in args.tiles.split(',')]
purge_tilenight(args.tiles, args.night,
dry_run=(not args.not_dry_run))
if not args.not_dry_run:
print('\nThat was a dry run; if you really want to do those actions,')
print('rerun with --not-dry-run')