Skip to content

Commit

Permalink
Merge pull request DarkEnergySurvey#103 from kadrlica/dev
Browse files Browse the repository at this point in the history
Fixes for Running at Fermilab
  • Loading branch information
kadrlica authored Sep 11, 2024
2 parents e4f0a62 + 38756d6 commit fa5ea4f
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
max-parallel: 3
matrix:
python-version: ["3.7", "3.8", "3.9"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion ugali/analysis/farm.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def submit(self, pixels, queue=None, debug=False, configfile=None):
logger.info('=== Submit Likelihood ===')
for ii,pix in enumerate(pixels):
msg = ' (%i/%i) pixel=%i nside=%i; (lon, lat) = (%.2f, %.2f)'
msg = msg%(ii+1,len(pixels),pix, self.nside_likelihood,lon[ii],lat[ii])
msg = msg%(ii,len(pixels),pix, self.nside_likelihood,lon[ii],lat[ii])
logger.info(msg)

# Create outfile name
Expand Down
11 changes: 11 additions & 0 deletions ugali/analysis/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ def estimate_position_angle(self,param='position_angle',burn=None,clip=10.0,alph
return ret

def bayes_factor(self,param,burn=None,clip=10.0,bins=50):
"""This is a very simplistic calculation of the Bayes Factor from the
posterior samples of a single parameter at the specific
parameter value of x=0 using the Savage-Dickey method for
nested hypothesis. It is currently assumping a flat prior
since the prior is not being passed in explicitly.
More information can be found here:
https://www.sciencedirect.com/science/article/abs/pii/S0022249611000666
ADW 2024-09-06: This should be moved to stats.
"""
# CAREFUL: Assumes a flat prior...
try:
data = self.samples.get(param,burn=burn,clip=clip)
Expand Down
4 changes: 2 additions & 2 deletions ugali/analysis/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,11 +382,11 @@ def finalizeObjects(self, objects):

coordsys = self.config['coords']['coordsys']
if coordsys.lower() == 'gal':
print("GAL coordintes")
print("GAL coordinates")
objs['GLON'],objs['GLAT'] = lon,lat
objs['RA'],objs['DEC'] = gal2cel(lon,lat)
else:
print("CEL coordintes")
print("CEL coordinates")
objs['RA'],objs['DEC'] = lon,lat
objs['GLON'],objs['GLAT'] = cel2gal(lon,lat)

Expand Down
8 changes: 4 additions & 4 deletions ugali/isochrone/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ def sample(self, mode='data', mass_steps=1000, mass_min=0.1, full_data_range=Fal
mass_init_min = self.mass_init[self.stage==self.hb_stage].min()
mass_init_max = self.mass_init[self.stage==self.hb_stage].max()
cut = (mass_init_array>mass_init_min)&(mass_init_array<mass_init_max)
if isinstance(self.hb_spread,collections.Iterable):
try:
# Explicit dispersion spacing
dispersion_array = self.hb_spread
n = len(dispersion_array)
else:
except TypeError:
# Default dispersion spacing
dispersion = self.hb_spread
spacing = 0.025
Expand Down Expand Up @@ -280,8 +280,8 @@ def stellar_mass(self, mass_min=0.1, steps=10000):

d_log_mass = (np.log10(mass_max) - np.log10(mass_min)) / float(steps)
log_mass = np.linspace(np.log10(mass_min), np.log10(mass_max), steps)
mass = 10.**log_mass

mass = np.clip(10.**log_mass, mass_min, mass_max)
if mass_min < np.min(self.mass_init):
mass_act_interpolation = scipy.interpolate.interp1d(np.insert(self.mass_init, 0, mass_min),
np.insert(self.mass_act, 0, mass_min))
Expand Down
2 changes: 1 addition & 1 deletion ugali/observation/roi.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def plot(self, value=None, pixel=None):

# ADW: Maybe these should be associated with the PixelRegion objects
def inPixels(self,lon,lat,pixels):
""" Function for testing if coordintes in set of ROI pixels. """
""" Function for testing if coordinates in set of ROI pixels. """
nside = self.config.params['coords']['nside_pixel']
return ugali.utils.healpix.in_pixels(lon,lat,pixels,nside)

Expand Down
34 changes: 26 additions & 8 deletions ugali/pipeline/run_03.0_likelihood.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ def run(self):
farm.submit_all(coords=self.opts.coords,queue=self.opts.queue,debug=self.opts.debug)

if 'merge' in self.opts.run:
import numpy as np

logger.info("Running 'merge'...")
mergefile = self.config.mergefile
roifile = self.config.roifile
Expand All @@ -42,13 +44,13 @@ def run(self):
for pix in np.unique(superpixel):
outfile = mergefile%pix
if exists(outfile) and not self.opts.force:
logger.warn(" Found %s; skipping..."%outfile)
logger.warning(" Found %s; skipping..."%outfile)
else:
healpix.merge_partial_maps(infiles[superpixel == pix],
outfile,multiproc=8)

if exists(roifile) and not self.opts.force:
logger.warn(" Found %s; skipping..."%roifile)
logger.warning(" Found %s; skipping..."%roifile)
else:
logger.info(" Merging likelihood headers...")
healpix.merge_likelihood_headers(infiles,roifile)
Expand All @@ -64,7 +66,7 @@ def run(self):
logfile = os.path.join(logdir,'scan_tar.log')
cmd = 'tar --remove-files -cvzf %s %s'%(tarfile,scanfile)
if exists(tarfile) and not self.opts.force:
logger.warn(" Found %s; skipping..."%tarfile)
logger.warning(" Found %s; skipping..."%tarfile)
else:
logger.info(" Tarring likelihood files...")
logger.info(cmd)
Expand All @@ -73,17 +75,33 @@ def run(self):
if 'plot' in self.opts.run:
# WARNING: Loading the full 3D healpix map is memory intensive.
logger.info("Running 'plot'...")
import numpy as np
# Should do this in environment variable
import matplotlib
matplotlib.use('Agg')
import pylab as plt
import ugali.utils.plotting as plotting
skymap = ugali.utils.skymap.readSparseHealpixMap(self.config.mergefile,'LOG_LIKELIHOOD')[1]
plotting.plotSkymap(skymap)
from skymap import DESSkymap

filenames = self.config.mergefile.split('_%')[0]+'_*.fits'
infiles = np.array(sorted(glob.glob(filenames)))
hpxmaps = ugali.utils.healpix.read_partial_map(infiles,'LOG_LIKELIHOOD',fullsky=True)[2]

outdir = mkdir(self.config['output']['plotdir'])
basename = os.path.basename(self.config.mergefile.replace('.fits','.png'))
outfile = os.path.join(outdir,basename)
plt.savefig(outfile)
basename = os.path.basename(self.config.mergefile.split('_%')[0])
for i,hpxmap in enumerate(hpxmaps):
#plotting.plotSkymap(hpxmap)
smap = DESSkymap()
smap.draw_hpxmap(hpxmap, cmap='gray_r', vmax=3.5)
smap.draw_inset_colorbar()
outfile = os.path.join(outdir,basename+'_%02d.png'%i)
print("Writing %s..."%outfile)
plt.savefig(outfile)
# Make the movie
import subprocess
cmd = "convert -delay 30 -loop 0 %s/*.png %s.gif"%(outdir,basename)
print(cmd)
subprocess.check_call(cmd,shell=True)

if 'check' in self.opts.run:
# Check the completion fraction
Expand Down
33 changes: 28 additions & 5 deletions ugali/utils/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
('lsf' ,['express','short','medium','long','xlong','xxl',
'kipac-ibq','bulletmpi']),
('slurm' ,[]),
('condor',['local','vanilla','universe','grid']),
('condor',['local','vanilla']),
])

# https://confluence.slac.stanford.edu/x/OaUlCw
Expand Down Expand Up @@ -80,9 +80,7 @@ def factory(queue,**kwargs):
elif name in CLUSTERS['slurm']+QUEUES['slurm']:
batch = Slurm(**kwargs)
elif name in CLUSTERS['condor']+QUEUES['condor']:
# Need to learn how to use condor first...
batch = Condor(**kwargs)
raise Exception("Condor cluster not implemented")
else:
raise TypeError('Unexpected queue name: %s'%name)

Expand All @@ -105,9 +103,17 @@ def __init__(self, **kwargs):
self.submit_cmd = "submit %(opts)s %(command)s"
self.jobs_cmd = "jobs"

def parse_options(self, **opts):
""" Parse command line options. """

# Default options for the cluster
options = odict(self.default_opts)
options.update(opts)
return ''.join('--%s %s '%(k,v) for k,v in options.items())

def jobs(self):
out = self.popen(self.jobs_cmd)
stdout = out.communicate()[0]
stdout = out.communicate()[0].decode()
return stdout

def njobs(self):
Expand Down Expand Up @@ -312,13 +318,30 @@ def parse_options(self, **opts):

class Condor(Batch):
""" Not implemented yet... """

_defaults = odict([
('n', '50'),
])

_mapping = odict([
('jobname','J'),
('logfile','o'),
('njobs','n'),
])

def __init__(self, **kwargs):
super(Condor,self).__init__(**kwargs)
logger.warning('Condor cluster is untested')

self.jobs_cmd = 'condor_q -u %s'%self.username
self.jobs_cmd = "cjobs -u %s"%(self.username)
self.submit_cmd = "csub %(opts)s %(command)s"

def parse_options(self, **opts):
# Default options for the cluster
options = odict(self.default_opts)
options.update(opts)
return ''.join('-%s %s '%(k,v) for k,v in options.items())

if __name__ == "__main__":
import argparse
description = __doc__
Expand Down
2 changes: 1 addition & 1 deletion ugali/utils/fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def load_headers(filenames,multiproc=False,**kwargs):
out = [load_header(kw) for kw in kwargs]

logger.debug('Concatenating headers...')
return np.rec.fromrecords([o.values() for o in out],names=out[0].keys())
return np.rec.fromrecords([list(o.values()) for o in out], names=list(out[0].keys()))


def load_file(kwargs):
Expand Down
2 changes: 1 addition & 1 deletion ugali/utils/healpix.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ def merge_likelihood_headers(filenames, outfile, **kwargs):
data_dict = fileio.load_headers(filenames,ext=ext,keys=keys,mulitproc=8)
names = data_dict.dtype.names
data_dict.dtype.names = ['PIXEL' if n=='LKDPIX' else n for n in names]

write_partial_map(outfile, data_dict, nside)
return data_dict

Expand Down
5 changes: 5 additions & 0 deletions ugali/utils/mlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ def isstring(obj):
"""Python 2/3 compatible string check"""
return isinstance(obj, six.string_types)

def asscalar(a):
"""Python 2/3 compatible scalar conversion"""
try: return np.asscalar(a)
except AttributeError: return a.item()

def rec_append_fields(rec, names, arrs, dtypes=None):
"""
Return a new record array with field names populated with data
Expand Down
5 changes: 2 additions & 3 deletions ugali/utils/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import ugali.utils.config
import ugali.observation.roi
import ugali.observation.catalog
import ugali.utils.skymap
import ugali.utils.projector
import ugali.utils.healpix
import ugali.isochrone
Expand Down Expand Up @@ -153,7 +152,7 @@ def sparseHealpixFiles(title, infiles, field='MAGLIM',**kwargs):
Inputs: field
"""
#map = ugali.utils.skymap.readSparseHealpixMaps(infiles,field)
map = ugali.utils.skymap.read_partial_map(infiles,field)
nside,pixels,hpxmap = ugali.utils.healpix.read_partial_map(infiles,field,fullsky=True)
ax = hp.mollview(map=map, title=title, **kwargs)
return ax, map

Expand Down Expand Up @@ -602,7 +601,7 @@ def drawMembership(self, ax=None, radius=None, zidx=0, mc_source_id=1):


pix = ang2pix(self.nside, self.lon, self.lat)
likelihood_pix = ugali.utils.skymap.superpixel(pix,self.nside,self.config.params['coords']['nside_likelihood'])
likelihood_pix = ugali.utils.healpix.superpixel(pix,self.nside,self.config.params['coords']['nside_likelihood'])
config = self.config
scan = ugali.analysis.scan.Scan(self.config,likelihood_pix)
likelihood = scan.likelihood
Expand Down
6 changes: 3 additions & 3 deletions ugali/utils/projector.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import numpy as np

from ugali.utils.logger import logger
from ugali.utils.mlab import isstring
from ugali.utils.mlab import isstring, asscalar

############################################################

Expand Down Expand Up @@ -117,7 +117,7 @@ def sphereToImage(self, lon, lat):
lon_rotated, lat_rotated = self.rotator.rotate(lon.flat, lat.flat)
x, y = self.sphere_to_image_func(lon_rotated, lat_rotated)

if scalar: return np.asscalar(x), np.asscalar(y)
if scalar: return asscalar(x), asscalar(y)
else: return x.reshape(lon.shape), y.reshape(lat.shape)

sphere2image = sphereToImage
Expand All @@ -129,7 +129,7 @@ def imageToSphere(self, x, y):
lon_rotated, lat_rotated = self.image_to_sphere_func(x.flat, y.flat)
lon, lat = self.rotator.rotate(lon_rotated, lat_rotated, invert = True)

if scalar: return np.asscalar(lon), np.asscalar(lat)
if scalar: return asscalar(lon), asscalar(lat)
else: return lon.reshape(x.shape), lat.reshape(y.shape)

image2sphere = imageToSphere
Expand Down
3 changes: 2 additions & 1 deletion ugali/utils/skymap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import healpy as hp

import ugali.utils.projector
from ugali.utils.healpix import superpixel,subpixel,ang2pix,pix2ang,query_disc
from ugali.utils.healpix import superpixel,subpixel
from ugali.utils.healpix import ang2pix,pix2ang,query_disc
from ugali.utils.healpix import read_partial_map
from ugali.utils.logger import logger
from ugali.utils.config import Config
Expand Down

0 comments on commit fa5ea4f

Please sign in to comment.