renamed src to source

This commit is contained in:
Paul M. Sutter 2024-05-22 16:15:14 -04:00
parent 4dcaf3959b
commit 4d9c5ab2c1
71 changed files with 7 additions and 3 deletions

View file

@ -0,0 +1,54 @@
#!/usr/bin/env python
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/misc_util/figureOutMask.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
# build a low-resolution mask given the actual galaxy positions
import numpy as np
import healpy as hp
import os
import shutil
import glob
import sys
galFile = "path/to/galaxy/file"
outMaskFile = "path/to/output/mask"
nside = 128
npix = hp.nside2npix(nside)
mask = np.zeros((npix))
for line in open(galFile):
line = line.split()
RA = np.float(line[3])
Dec = np.float(line[4])
z = np.float(line[5])
phi = np.pi/180.*RA
theta = Dec*np.pi/180.
theta = np.pi/2. - Dec*np.pi/180.
pos = np.zeros((3))
pix = hp.ang2pix(nside, theta, phi)
mask[pix] = 1.
print "Sky Fraction:", 1.0*len(mask[mask>0])/len(mask)
hp.write_map(outMaskFile, mask)

View file

@ -0,0 +1,116 @@
#+
# VIDE -- Void IDentification and Examination -- ./build_tools/gather_sources.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
import shutil
import tempfile
import re
from git import Repo,Tree,Blob
def apply_license(license, relimit, filename):
header = re.sub(r'@FILENAME@', filename, license)
with open(filename) as f:
lines = f.read()
lines = re.sub(relimit, lambda x: (("" if x.group(1) is None else x.group(1)) + header), lines)
with tempfile.NamedTemporaryFile(delete=False, mode="wt", encoding="UTF-8") as tmp_sources:
tmp_sources.write(lines)
shutil.move(tmp_sources.name, filename)
def apply_python_license(filename):
license="""#+
# VIDE -- Void IDentification and Examination -- @FILENAME@
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
"""
print("Shell/Python file: %s" % filename)
relimit=r'^(#!.*\n)?#\+\n(#.*\n)*#\+\n'
apply_license(license, relimit, filename)
def apply_cpp_license(filename):
license="""/*+
VIDE -- Void IDentification and Examination -- @FILENAME@
Copyright (C) 2010-2014 Guilhem Lavaux
Copyright (C) 2011-2014 P. M. Sutter
This program 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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
"""
print("C++ file: %s" % filename)
relimit = r'(?s)^()/\*\+.*\+\*/\n'
apply_license(license, relimit, filename)
def analyze_tree(prefix, t):
for entry in t:
ename = entry.name
if ename == 'external' or ename == 'zobov':
continue
if type(entry) == Tree:
analyze_tree(prefix + "/" + ename, entry)
elif type(entry) == Blob:
if re.match(".*\.(sh|py|pyx)$",ename) != None:
fname=prefix+"/"+ename
apply_python_license(fname)
if re.match('.*\.(cpp|hpp|h)$', ename) != None:
fname=prefix+"/"+ename
apply_cpp_license(fname)
if __name__=="__main__":
import sys
if len(sys.argv) >= 2:
apply_python_license(sys.argv[1])
sys.exit(0)
repo = Repo(".")
assert repo.bare == False
t = repo.tree()
analyze_tree(".", t)

View file

@ -0,0 +1,150 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/pipeline_source/defaults.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
import os
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# DEFAULT CONFIGURATION
datasetName = ""
startCatalogStage = 1
endCatalogStage = 3
continueRun = True
# directory for the input simulation/observational particle files
catalogDir = os.getenv("HOME")+"/workspace/Voids/catalog/"
# path to HOD code
hodPath = os.getenv("HOME")+"/projects/Voids/hod/HOD.x"
# where to put the final void catalog, figures, and output logs
voidOutputDir = os.getenv("HOME")+"/workspace/Voids//"
figDir = os.getenv("PWD")+"/../figs/"
logDir = os.getenv("PWD")+"/../logs/"
# where to place the pipeline scripts
scriptDir = os.getenv("PWD")+"/scripts//"
# simulation or observation?
dataType = "simulation"
# available formats for simulation: gadget, mergertree
dataFormat = "sdf"
dataUnit = 1 # as multiple of Mpc/h
# place particles on the lightcone?
useLightCone = False
# also do peculiar velocities?
doPecVel = False
# common filename of particle files
# use a placeholder (such as NNNNN as shown below) to select the different
# filenames. For example, if we have partFile01, partFile02, etc.,
# then particleFileBase = 'partFileNN'
# particleFileDummy = 'NN'
# fileNums = ["01", "02"]
particleFileBase = "mf_4s_1G_512_NNNNN"
particleFileDummy = 'NNNNN'
# list of file numbers for the particle files
# to get particle file name, we replace particleFileDummy with fileNum
fileNums = ["0.667", "0.500"]
# redshift of each file in the above list
redshifts = ["0.5", "1.0"]
# how many independent slices along the z-axis?
numSlices = 1
# how many slices for analysis?
numAPSlices = 1
# how many subdivisions along the x- and y- axis?
# ( = 2 will make 4 subvolumes for each slice, = 3 will make 9, etc.)
numSubvolumes = 1
# prefix to give all outputs
prefix = "mt_"
# shift the z-coord of sims with redshift
shiftSimZ = False
# list of desired subsamples - see subSamplingMode parameter
subSamples = [1.0]
doSubSamplingInPrep = False # do the subsampling in preparation script?
# if False, generateMock will do the subsampling
# if 'absolute', subSamples are given in particles per cubic Mpc/h
# if 'relative', subSamples are given as a fraction of input particles
subSampleMode = "relative"
# common filename of halo files, leave blank to ignore halos
haloFileBase = "mf_4s_1G_512_bgc2_NNNNN.sdf"
haloFileDummy = 'NNNNN'
# minimum halo mass cuts to apply for the halo catalog
# use "none" to get all halos
minHaloMasses = []
# density threshold for halo catalogs
haloDenList = []
# locations of data in the halo catalog
haloFileMCol = 6
haloFileXCol = 0
haloFileYCol = 1
haloFileZCol = 2
haloFileVXCol = 3
haloFileVYCol = 4
haloFileVZCol = 5
haloFileColSep = ','
haloFileNumComLines = 0
haloFilePosRescale = 1.0 # rescaling necessary to get Mpc/h
# adjust these two parameters given the memory contraints on your system:
# numZobovDivisions: how many sub-volumes per dimension will zobov process
# numZobovThreads: how many sub-volumes to process at once?
numZobovDivisions = 2
numZobovThreads = 2
# simulation information
numPart = 512*512*512
lbox = 999.983 # Mpc/h
omegaM = 0.2847979853038958
hubble = 0.6962
hodParmList = [
{'name' : "dr9mid", #BOSS: Manera et al. 2012, eq. 26
'Mmin' : 0.0,
'M1' : 1.e14,
'sigma_logM' : 0.596,
'alpha' : 1.0127,
'Mcut' : 1.19399e13,
'galDens' : 0.0002, # density passed to HOD code
'galDensFinal' : 0.0002, # subsample galaxies to reach this density
},
]
# END CONFIGURATION
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------

File diff suppressed because it is too large Load diff

35
python_source/setup.py Normal file
View file

@ -0,0 +1,35 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/setup.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
import os
VOID_GSL=os.environ.get('VOID_GSL')
setup(
name='vide',
version='1.0',
# cmdclass = {'build_ext': build_ext},
include_dirs = [np.get_include()],
packages=
['vide','vide.backend','vide.voidUtil'],
)

View file

@ -0,0 +1,21 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/__init__.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
from .backend import *
from .voidUtil import *

View file

@ -0,0 +1,22 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/backend/__init__.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
from .classes import *
from .launchers import *
from .cosmologyTools import *

View file

@ -0,0 +1,225 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/backend/classes.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
# classes and routines used to support scripts
import os
from numpy import abs
import matplotlib as mpl
mpl.use('Agg')
LIGHT_SPEED = 299792.458
class Stack:
zMin = 0.0
zMax = 0.1
rMin = 5
rMax = 15
zMinPlot = 0.0
zMaxPlot = 0.1
includeInHubble = True
partOfCombo = False
needProfile = True
rescaleMode = "rmax" # options: "rmax" to scale to largest void in stack
# "rv" normalize each void
maxVoids = -1 # maximum number of voids to allow in the stack
def __init__(self, zMin, zMax, rMin, rMax, includeInHubble, partOfCombo,
zMinPlot=None, needProfile=True, rescaleMode="rmax",
maxVoids=-1, fittingMode="mcmc"):
self.zMin = zMin
self.zMax = zMax
self.rMin = rMin
self.rMax = rMax
self.zMaxPlot = zMax
self.includeInHubble = includeInHubble
self.partOfCombo = partOfCombo
self.needProfile = needProfile
self.rescaleMode = rescaleMode
self.maxVoids = maxVoids
self.fittingMode = fittingMode
if zMinPlot == None:
self.zMinPlot = self.zMin
else:
self.zMinPlot = zMinPlot
class Sample:
dataType = "observation"
dataFormat = "sdss"
dataFile = "lss.dr72dim.dat"
dataUnit = 1
fullName = "lss.dr72dim.dat"
nickName = "dim"
zobovDir = ""
maskFile = "rast_window_512.fits"
selFunFile = "czselfunc.all.dr72dim.dat"
zBoundary = (0.0, 0.1)
zBoundaryMpc = (0., 300)
shiftSimZ = False
zRange = (0.0, 0.1)
omegaM = 0.27
minVoidRadius = -1
fakeDensity = 0.01
profileBinSize = 2 # Mpc
autoNumInStack = -1 # set to >0 to automatically generate stacks of size N
autoPartInStack = -1 # set to >0 to automatically generate stacks with N particles
numAPSlices = 1
volumeLimited = True
includeInHubble = True
partOfCombo = False
isCombo = False
comboList = []
# applies to simulations only
boxLen = 1024 # Mpc/h
usePecVel = False
subsample = 1.0
numSubvolumes = 1
mySubvolume = 1
stacks = []
def __init__(self, dataFile="", fullName="", dataUnit=1,
nickName="", maskFile="", selFunFile="",
zBoundary=(), zRange=(), zBoundaryMpc=(), shiftSimZ=False,
minVoidRadius=-1, fakeDensity=0.01, volumeLimited=True,
numAPSlices=1,
includeInHubble=True, partOfCombo=False, isCombo=False,
comboList=(), profileBinSize=2.0,
boxLen=1024, usePecVel=False, omegaM=0.27,
numSubvolumes=1, mySubvolume=1, dataFormat="sdss",
useComoving=True,
dataType="observation",
subsample=1.0, useLightCone=False, autoNumInStack=-1,
autoPartInStack=-1):
self.dataFile = dataFile
self.fullName = fullName
self.nickName = nickName
self.maskFile = maskFile
self.selFunFile = selFunFile
self.zBoundary = zBoundary
self.zBoundaryMpc = zBoundaryMpc
self.shiftSimZ = shiftSimZ
self.zRange = zRange
self.minVoidRadius = minVoidRadius
self.fakeDensity = fakeDensity
self.volumeLimited = volumeLimited
self.includeInHubble = includeInHubble
self.partOfCombo = partOfCombo
self.isCombo = isCombo
self.comboList = comboList
self.numAPSlices = numAPSlices
self.zobovDir = None
self.profileBinSize = profileBinSize
self.dataType = dataType
self.boxLen = boxLen
self.usePecVel = usePecVel
self.omegaM = omegaM
self.numSubvolumes = numSubvolumes
self.mySubvolume = mySubvolume
self.dataFormat = dataFormat
self.subsample = subsample
self.useLightCone = useLightCone
self.dataUnit = dataUnit
self.useComoving = useComoving
self.autoNumInStack = autoNumInStack
self.autoPartInStack = autoPartInStack
self.stacks = []
def addStack(self, zMin, zMax, rMin, rMax,
includeInHubble, partOfCombo,zMinPlot=None,
needProfile=True, rescaleMode="rmax",
maxVoids=-1, fittingMode="mcmc"):
self.stacks.append(Stack(zMin, zMax, rMin, rMax,
includeInHubble, partOfCombo,
zMinPlot=zMinPlot, needProfile=needProfile,
rescaleMode=rescaleMode,
maxVoids=maxVoids,
fittingMode=fittingMode))
def getHubbleStacks(self):
stacksForHubble = []
for stack in self.stacks:
if stack.includeInHubble:
stacksForHubble.append(stack)
return stacksForHubble
def getUniqueRBins(self):
uniqueRStacks = []
for stack in self.stacks:
if not stack.includeInHubble:
continue
alreadyHere = False
for stackCheck in uniqueRStacks:
if stack.rMin == stackCheck.rMin and stack.rMax == stackCheck.rMax:
alreadyHere = True
break
if not alreadyHere:
uniqueRStacks.append(stack)
return uniqueRStacks
def getUniqueZBins(self):
uniqueZStacks = []
for stack in self.stacks:
if not stack.includeInHubble:
continue
alreadyHere = False
for stackCheck in uniqueZStacks:
if stack.zMin == stackCheck.zMin and stack.zMax == stackCheck.zMax:
alreadyHere = True
break
if not alreadyHere:
uniqueZStacks.append(stack)
return uniqueZStacks
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
def jobSuccessful(logFile, doneString):
jobDone = False
checkLine = ""
if os.access(logFile, os.F_OK):
#filelines = file(logFile, "r").readlines()
#if len(filelines) >= 1:
# checkLine = filelines[-1]
for line in open(logFile, 'r'):
if doneString in line: jobDone = True
return jobDone
def getStackSuffix(zMin, zMax, rMin, rMax, dataPortion, customLine=""):
return "z"+str(zMin)+"-"+str(zMax)+"_"+str(rMin)+"-"+str(rMax)+\
"Mpc"+customLine+"_"+dataPortion
def getPeriodic(sample):
periodicLine = ""
if sample.dataType != "observation":
if sample.numSubvolumes == 1: periodicLine += "xy"
if abs(sample.zBoundaryMpc[1] - sample.zBoundaryMpc[0] - \
sample.boxLen) <= 1.e-1:
periodicLine += "z"
return periodicLine
def my_import(name):
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod

View file

@ -0,0 +1,112 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/apTools/chi2/cosmologyTools.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
# a suite of functions to compute expansion rates, angular diameter
# distances, and expected void stretching
import numpy as np
import scipy.integrate as integrate
import healpy as healpy
import os
from vide.backend import *
__all__=['expansion', 'angularDiameter', 'aveExpansion', 'getSurveyProps']
# returns 1/E(z) for the given cosmology
def expansion(z, Om = 0.27, Ot = 1.0, w0 = -1.0, wa = 0.0):
ez = Om * (1+z)**3 + (Ot-Om)# * (1+z)**(3.+3*wz)
#ez = Om * (1+z)**3 + (Ot-Om)# * integrade.quad(eosDE, 0.0, z, args=(w0,wa))[0]
ez = 1./np.sqrt(ez)
return ez
# returns DE value at redshift z
def eosDE(z, w0 = -1.0, wa = 0.0):
return w0 + wa*z/(1+z)
# returns D_A(z) for the given cosmology
def angularDiameter(z, Om = 0.27, Ot = 1.0, w0 = -1.0, wa = 0.0):
da = integrate.quad(expansion, 0.0, z, args=(Om, Ot, w0, wa))[0]
return da
# -----------------------------------------------------------------------------
# returns average expected expansion for a given redshift range
def aveExpansion(zStart, zEnd, Om = 0.27, Ot = 1.0, w0 = -1.0, wa = 0.0):
if zStart == 0.0: zStart = 1.e-6
ave = integrate.quad(expansion, zStart, zEnd, args=(Om, Ot, w0, wa))[0]
ave = (zEnd-zStart)/ave
return ave
# -----------------------------------------------------------------------------
# returns the volume and galaxy density for a given redshit slice
def getSurveyProps(maskFile, zmin, zmax, selFunMin, selFunMax, portion, selectionFuncFile=None, useComoving=False):
LIGHT_SPEED = 299792.458
mask = healpy.read_map(maskFile)
area = (1.*np.size(np.where(mask > 0)) / np.size(mask)) * 4.*np.pi
if useComoving:
zmin = LIGHT_SPEED/100.*angularDiameter(zmin, Om=0.27)
zmax = LIGHT_SPEED/100.*angularDiameter(zmax, Om=0.27)
selFunMin = LIGHT_SPEED/100.*angularDiameter(selFunMin, Om=0.27)
selFunMax = LIGHT_SPEED/100.*angularDiameter(selFunMax, Om=0.27)
else:
zmin = zmin * 3000
zmax = zmax * 3000
selFunMin *= 3000
selFunMax *= 3000
volume = area * (zmax**3 - zmin**3) / 3
if selectionFuncFile == None:
nbar = 1.0
elif not os.access(selectionFuncFile, os.F_OK):
print(" Warning, selection function file %s not found, using default of uniform selection." % selectionFuncFile)
nbar = 1.0
else:
selfunc = np.genfromtxt(selectionFuncFile)
selfunc = np.array(selfunc)
selfunc[:,0] = selfunc[:,0]/100.
selfuncUnity = selfunc
selfuncUnity[:,1] = 1.0
selfuncMin = selfunc[0,0]
selfuncMax = selfunc[-1,0]
selfuncDx = selfunc[1,0] - selfunc[0,0]
selfuncN = np.size(selfunc[:,0])
selFunMin = max(selFunMin, selfuncMin)
selFunMax = min(selFunMax, selfuncMax)
def f(z): return selfunc[np.ceil((z-selfuncMin)/selfuncDx), 1]*z**2
def fTotal(z): return selfuncUnity[np.ceil((z-selfuncMin)/selfuncDx), 1]*z**2
zrange = np.linspace(selFunMin, selFunMax)
nbar = scipy.integrate.quad(f, selFunMin, selFunMax)
nbar = nbar[0]
ntotal = scipy.integrate.quad(fTotal, 0.0, max(selfuncUnity[:,0]))
ntotal = ntotal[0]
nbar = ntotal / area / nbar
return (volume, nbar)

View file

@ -0,0 +1,670 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/backend/launchers.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# routines which communicate with individual data analysis portions -
# they make the main script easier to read
import os
import glob
from . import classes
import numpy as np
import numpy.ma as ma
import os
import shutil
import glob
import subprocess
import sys
from pylab import figure
from netCDF4 import Dataset
from vide.backend.classes import *
from vide.backend.cosmologyTools import *
import pickle
import vide.apTools as vp
import scipy.interpolate as interpolate
NetCDFFile = Dataset
ncFloat = 'f8' # Double precision
LIGHT_SPEED = 299792.458
# -----------------------------------------------------------------------------
def launchPrep(sample, binPath, workDir=None, inputDataDir=None,
zobovDir=None, figDir=None, logFile=None, useComoving=False,
continueRun=None,regenerate=False):
if sample.dataType == "observation":
sampleName = sample.fullName
if regenerate:
inputParameterFlag = "inputParameter " + zobovDir+"/zobov_slice_"+sampleName+".par"
outputFile = zobovDir+"/regenerated_zobov_slice_" + sampleName
else:
inputParameterFlag = ""
outputFile = zobovDir+"/zobov_slice_" + sampleName
if sample.dataFile == "":
datafile = inputDataDir+"/"+sampleName
else:
datafile = inputDataDir+"/"+sample.dataFile
maskFile = sample.maskFile
if useComoving:
useComovingFlag = "useComoving"
else:
useComovingFlag = ""
conf="""
catalog %s
mask %s
output %s
params %s
zMin %g
zMax %g
density_fake %g
%s
%s
omegaM %g
""" % (datafile, maskFile, outputFile,
zobovDir+"/zobov_slice_"+sampleName+".par",
sample.zBoundary[0], sample.zBoundary[1], sample.fakeDensity,
useComovingFlag, inputParameterFlag, sample.omegaM)
parmFile = os.getcwd()+"/generate_"+sample.fullName+".par"
if regenerate or not (continueRun and jobSuccessful(logFile, "Done!\n")):
with open(parmFile, mode="wt") as f:
f.write(conf)
arg1 = "--configFile=%s" % parmFile
with open(logFile, 'wt') as log:
subprocess.call([binPath, arg1], stdout=log, stderr=log)
if jobSuccessful(logFile, "Done!\n"):
print("done")
else:
print("FAILED!")
exit(-1)
else:
print("already done!")
if os.access(parmFile, os.F_OK): os.unlink(parmFile)
if os.access("contour_map.fits", os.F_OK):
os.system("mv %s %s" % ("contour_map.fits", zobovDir))
os.system("mv %s %s" % ("mask_map.fits", zobovDir))
if os.access("comoving_distance.txt", os.F_OK):
os.system("mv %s %s" % ("comoving_distance.txt", zobovDir))
if os.access("mask_index.txt", os.F_OK):
os.system("mv %s %s" % ("mask_index.txt", zobovDir))
os.system("mv %s %s" % ("total_particles.txt", zobovDir))
if os.access("galaxies.txt", os.F_OK):
os.system("mv %s %s" % ("galaxies.txt", zobovDir))
os.system("mv %s %s" % ("mock_galaxies.txt", zobovDir))
os.system("mv %s %s" % ("mock_boundary.txt", zobovDir))
os.system("mv %s %s" % ("mock_sphere.txt", zobovDir))
else: # simulation
sampleName = sample.fullName
datafile = inputDataDir+"/"+sample.dataFile
# check if the final subsampling is done
lastSample = sample.subsample.split(', ')[-1]
doneLine = "Done! %5.2e\n" % float(lastSample)
if (continueRun and jobSuccessful(logFile, doneLine)):
print("already done!")
return
prevSubSample = -1
firstSubSample = -1
for thisSubSample in sample.subsample.split(', '):
if prevSubSample == -1:
inputParameterFlag = ""
outputFile = zobovDir+"/zobov_slice_" + sampleName + "_ss" + \
thisSubSample
keepFraction = float(thisSubSample)
subSampleLine = "subsample %g" % keepFraction
resubSampleLine = ""
firstSubSample = keepFraction
else:
inputParameterFlag = "inputParameter " + zobovDir+"/zobov_slice_"+\
sampleName+"_ss"+prevSubSample+".par"
outputFile = zobovDir+"/zobov_slice_" + sampleName + "_ss" + \
thisSubSample
keepFraction = float(thisSubSample)/float(prevSubSample)
subSampleLine = "subsample %s" % firstSubSample
resubSampleLine = "resubsample %g" % keepFraction
includePecVelString = ""
if sample.usePecVel: includePecVelString = "peculiarVelocities"
useLightConeString = ""
if sample.useLightCone: useLightConeString = "cosmo"
if sample.dataFormat == "multidark" or sample.dataFormat == "random":
dataFileLine = "multidark " + datafile
elif sample.dataFormat == "gadget":
dataFileLine = "gadget " + datafile
elif sample.dataFormat == "gadget2":
dataFileLine = "gadget2 " + datafile
elif sample.dataFormat == "ahf":
dataFileLine = "gadget " + datafile
elif sample.dataFormat == "sdf":
dataFileLine = "sdf " + datafile
elif sample.dataFormat == "ramses":
ramsesId = int(os.path.split(datafile)[1][-5:len(datafile)]) # picks out the particle file (should be the output_NNNNN, then extracts the output id "NNNNN" as an integer)
dataFileLine = "ramses " + datafile + "/"
else:
raise ValueError("unknown dataFormat '%s'" % sample.dataFormat)
iX = float(sample.mySubvolume[0])
iY = float(sample.mySubvolume[1])
xMin = iX/sample.numSubvolumes * sample.boxLen
yMin = iY/sample.numSubvolumes * sample.boxLen
xMax = (iX+1)/sample.numSubvolumes * sample.boxLen
yMax = (iY+1)/sample.numSubvolumes * sample.boxLen
reshiftFlag = ""
if not sample.shiftSimZ: reshiftFlag = "preReShift"
if sample.dataFormat == "ramses":
ramsesIdLine = "ramsesId " + str(ramsesId)
else:
ramsesIdLine = ""
conf="""
%s
output %s
outputParameter %s
%s
%s
gadgetUnit %g
%s
rangeX_min %g
rangeX_max %g
rangeY_min %g
rangeY_max %g
rangeZ_min %g
rangeZ_max %g
%s
%s
%s
%s
""" % (dataFileLine,
outputFile,
outputFile+".par",
includePecVelString,
useLightConeString,
sample.dataUnit,
ramsesIdLine,
xMin, xMax, yMin, yMax,
sample.zBoundaryMpc[0], sample.zBoundaryMpc[1],
subSampleLine,resubSampleLine,inputParameterFlag,reshiftFlag)
parmFile = os.getcwd()+"/generate_"+sample.fullName+".par"
with open(parmFile, mode="wt") as f:
f.write(conf)
if (prevSubSample == -1):
cmd = "%s --configFile=%s" % (binPath,parmFile)
log = open(logFile, 'w')
else:
cmd = "%s --configFile=%s" % (binPath,parmFile)
log = open(logFile, 'a')
arg1 = "--configFile=%s" % parmFile
subprocess.call(cmd, stdout=log, stderr=log, shell=True)
log.close()
# remove intermediate files
if (prevSubSample != -1):
os.unlink(zobovDir+"/zobov_slice_"+sampleName+"_ss"+prevSubSample+".par")
os.unlink(zobovDir+"/zobov_slice_"+sampleName+"_ss"+prevSubSample)
doneLine = "Done! %5.2e\n" % keepFraction
if not jobSuccessful(logFile, doneLine):
print("FAILED!") ### dies here for now
exit(-1)
prevSubSample = thisSubSample
if jobSuccessful(logFile, doneLine): print("done")
# place the final subsample
os.system("mv %s %s" % (zobovDir+"/zobov_slice_"+sampleName+"_ss"+\
prevSubSample, zobovDir+"/zobov_slice_"+sampleName))
os.system("mv %s %s" % (zobovDir+"/zobov_slice_"+sampleName+"_ss"+\
prevSubSample+".par", zobovDir+"/zobov_slice_"+sampleName+".par"))
if os.access("comoving_distance.txt", os.F_OK):
os.system("mv %s %s" % ("comoving_distance.txt", zobovDir))
if os.access(parmFile, os.F_OK):
os.unlink(parmFile)
if os.access("mask_index.txt", os.F_OK):
os.system("mv %s %s" % ("mask_index.txt", zobovDir))
os.system("mv %s %s" % ("total_particles.txt", zobovDir))
#os.system("mv %s %s" % ("sample_info.txt", zobovDir))
# add to sample info file
if sample.dataType == "observation":
(boxVol, nbar) = vp.getSurveyProps(sample.maskFile, sample.zRange[0],
sample.zRange[1], sample.zRange[0], sample.zRange[1], "all",
useComoving=useComoving)
else:
iX = float(sample.mySubvolume[0])
iY = float(sample.mySubvolume[1])
xMin = iX/sample.numSubvolumes * sample.boxLen
yMin = iY/sample.numSubvolumes * sample.boxLen
xMax = (iX+1)/sample.numSubvolumes * sample.boxLen
yMax = (iY+1)/sample.numSubvolumes * sample.boxLen
zMin = sample.zBoundaryMpc[0]
zMax = sample.zBoundaryMpc[1]
boxVol = (xMax-xMin)*(yMax-yMin)*(zMax-zMin)
nbar = 1.0
numTracers = int(open(zobovDir+"/mask_index.txt", "r").read())
numTotal = int(open(zobovDir+"/total_particles.txt", "r").read())
meanSep = (1.*numTracers/boxVol/nbar)**(-1/3.)
# save this sample's information
with open(zobovDir+"/sample_info.dat", mode='wb') as output:
pickle.dump(sample, output, pickle.HIGHEST_PROTOCOL)
fp = open(zobovDir+"/sample_info.txt", 'w')
fp.write("Sample name: %s\n" % sample.fullName)
fp.write("Sample nickname: %s\n" % sample.nickName)
fp.write("Data type: %s\n" % sample.dataType)
fp.write("Redshift range: %f - %f\n" %(sample.zBoundary[0],sample.zBoundary[1]))
if (sample.dataType == "simulation"):
fp.write("Particles placed on lightcone: %g\n" % sample.useLightCone)
fp.write("Peculiar velocities included: %g\n" % sample.usePecVel)
if (len(sample.subsample) == 1):
fp.write("Additional subsampling fraction: %s\n" % sample.subsample)
else:
fp.write("Additional subsampling fraction: %s\n" % sample.subsample[-1])
fp.write("Simulation box length (Mpc/h): %g\n" % sample.boxLen)
fp.write("Simulation Omega_M: %g\n" % sample.omegaM)
fp.write("Number of simulation subvolumes: %s\n" % sample.numSubvolumes)
fp.write("My subvolume index: %s\n" % sample.mySubvolume)
fp.write("Estimated volume (cubic Mpc/h): %g\n" % boxVol)
fp.write("Number of real (non-boundary) tracers: %d\n" % numTracers)
fp.write("Total number of tracers: %d\n" % numTotal)
fp.write("Estimated mean tracer separation (Mpc/h): %g\n" % meanSep)
fp.write("Minimum void size actually used (Mpc/h): %g\n" % sample.minVoidRadius)
fp.close()
# -----------------------------------------------------------------------------
def launchZobov(sample, binPath, zobovDir=None, logDir=None, continueRun=None,
numZobovDivisions=None, numZobovThreads=None, mergingThreshold=0.2):
sampleName = sample.fullName
datafile = zobovDir+"zobov_slice_"+sampleName
logFile = logDir+"/zobov_"+sampleName+".out"
vozScript = "./scr_"+sampleName
if os.access(vozScript, os.F_OK):
os.unlink(vozScript)
if sample.dataType == "observation":
maskIndex = open(zobovDir+"/mask_index.txt", "r").read()
totalPart = open(zobovDir+"/total_particles.txt", "r").read()
maxDen = mergingThreshold*float(maskIndex)/float(totalPart)
else:
maskIndex = -1
maxDen = mergingThreshold
if numZobovDivisions == 1:
print(" WARNING! You are using a single ZOBOV division with a simulation. Periodic boundaries will not be respected!")
if not (continueRun and jobSuccessful(logFile, "Done!\n")):
for fileName in glob.glob(zobovDir+"/part._"+sampleName+".*"):
os.unlink(fileName)
if os.access(zobovDir+"/adj_"+sampleName+".dat", os.F_OK):
os.unlink(zobovDir+"adj_"+sampleName+".dat")
if os.access(zobovDir+"/voidDesc_"+sampleName+".out", os.F_OK):
os.unlink(zobovDir+"/voidDesc_"+sampleName+".out")
cmd = [binPath+"/vozinit", datafile, "0.1", "1.0", str(numZobovDivisions), \
"_"+sampleName, str(numZobovThreads), \
binPath, zobovDir, str(maskIndex)]
log = open(logFile, 'w')
subprocess.call(cmd, stdout=log, stderr=log)
log.close()
cmd = ["./%s" % vozScript]
log = open(logFile, 'a')
subprocess.call(cmd, stdout=log, stderr=log)
log.close()
# re-weight the volumes based on selection function
if sample.dataType == "observation" and \
sample.selFunFile != None:
# load volumes
volFile = zobovDir+"/vol_"+sampleName+".dat"
with open(volFile, mode="rb") as File:
numPartTot = np.fromfile(File, dtype=np.int32,count=1)
vols = np.fromfile(File, dtype=np.float32,count=numPartTot)
# load redshifts
partFile = zobovDir+"/zobov_slice_"+sample.fullName
with open(partFile, mode="rb") as File:
chk = np.fromfile(File, dtype=np.int32,count=1)
Np = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
# x
chk = np.fromfile(File, dtype=np.int32,count=1)
redshifts = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
# y
chk = np.fromfile(File, dtype=np.int32,count=1)
redshifts = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
# z
chk = np.fromfile(File, dtype=np.int32,count=1)
redshifts = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
# RA
chk = np.fromfile(File, dtype=np.int32,count=1)
redshifts = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
# Dec
chk = np.fromfile(File, dtype=np.int32,count=1)
redshifts = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
# z
chk = np.fromfile(File, dtype=np.int32,count=1)
redshifts = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
# build selection function interpolation
selfuncData = np.genfromtxt(sample.selFunFile)
selfunc = interpolate.interp1d(selfuncData[:,0], selfuncData[:,1],
kind='cubic', bounds_error=False,
fill_value=1.0)
# re-weight and write
## TEST
#redshifts /= 10000.
for i in range(len(vols)):
vols[i] *= selfunc(redshifts[i])
volFile = zobovDir+"/vol_weighted_"+sampleName+".dat"
with open(volFile, mode='wb') as File:
numPartTot.astype(np.int32).tofile(File)
vols.astype(np.float32).tofile(File)
volFileToUse = zobovDir+"/vol_weighted_"+sampleName+".dat"
else:
volFileToUse = zobovDir+"/vol_"+sampleName+".dat"
cmd = [binPath+"/jozov2", \
zobovDir+"/adj_"+sampleName+".dat", \
volFileToUse, \
zobovDir+"/voidPart_"+sampleName+".dat", \
zobovDir+"/voidZone_"+sampleName+".dat", \
zobovDir+"/voidDesc_"+sampleName+".out", \
str(maxDen), str(maskIndex)]
log = open(logFile, 'a')
subprocess.call(cmd, stdout=log, stderr=log)
log.close()
# don't need the subbox files
for fileName in glob.glob(zobovDir+"/part._"+sampleName+".*"):
os.unlink(fileName)
if jobSuccessful(logFile, "Done!\n"):
print("done")
else:
print("FAILED!")
exit(-1)
else:
print("already done!")
if os.access(vozScript, os.F_OK):
os.unlink(vozScript)
# -----------------------------------------------------------------------------
def launchPrune(sample, binPath,
summaryFile=None, logFile=None, zobovDir=None,
continueRun=None, useComoving=False, mergingThreshold=0.2):
sampleName = sample.fullName
numVoids = sum(1 for line in \
open(zobovDir+"/voidDesc_"+sampleName+".out"))
numVoids -= 2
if sample.dataType == "observation":
mockIndex = open(zobovDir+"/mask_index.txt", "r").read()
totalPart = open(zobovDir+"/total_particles.txt", "r").read()
maxDen = mergingThreshold*float(mockIndex)/float(totalPart)
observationLine = " --isObservation"
#periodicLine = " --periodic=''"
else:
mockIndex = -1
maxDen = mergingThreshold
observationLine = ""
periodicLine = " --periodic='" + getPeriodic(sample) + "'"
if useComoving:
useComovingFlag = " --useComoving"
else:
useComovingFlag = ""
if sample.minVoidRadius == -1:
minRadius = -1
for line in open(zobovDir+"/sample_info.txt"):
if "Estimated mean tracer separation" in line:
minRadius = float(line.split()[5])
break
if minRadius == -1:
print("Could not grab mean tracer separation!?")
exit(-1)
else:
minRadius = sample.minVoidRadius
if not (continueRun and (jobSuccessful(logFile, "NetCDF: Not a valid ID\n") \
or jobSuccessful(logFile, "Done!\n"))):
cmd = binPath
cmd += " --partFile=" + zobovDir+"/zobov_slice_"+str(sampleName)
cmd += " --voidDesc=" + zobovDir+"/voidDesc_"+str(sampleName)+".out"
cmd += " --void2Zone="+zobovDir+"/voidZone_"+str(sampleName)+".dat"
cmd += " --zone2Part=" + zobovDir+"/voidPart_"+str(sampleName)+".dat"
cmd += " --partVol=" + zobovDir+"/vol_"+str(sampleName)+".dat"
cmd += " --partAdj=" + zobovDir+"/adj_"+str(sampleName)+".dat"
cmd += " --extraInfo=" + zobovDir+"/zobov_slice_"+str(sampleName)+\
".par"
cmd += " --tolerance=1.0"
cmd += " --mockIndex=" + str(mockIndex)
cmd += " --maxCentralDen=" + str(maxDen)
cmd += " --zMin=" + str(sample.zRange[0])
cmd += " --zMax=" + str(sample.zRange[1])
cmd += " --rMin=" + str(minRadius)
cmd += " --numVoids=" + str(numVoids)
cmd += observationLine
cmd += periodicLine
cmd += useComovingFlag
cmd += " --omegaM=" + str(sample.omegaM)
cmd += " --outputDir=" + zobovDir
cmd += " --sampleName=" + str(sampleName)
log = open(logFile, 'w')
log.write(f"Command is {cmd}\n")
subprocess.call(cmd, stdout=log, stderr=log, shell=True)
log.close()
if jobSuccessful(logFile, "NetCDF: Not a valid ID\n") or \
jobSuccessful(logFile, "Done!\n"):
print("done")
else:
print("FAILED!")
#exit(-1)
else:
print("already done!")
# -----------------------------------------------------------------------------
def launchVoidOverlap(sample1, sample2, sample1Dir, sample2Dir,
binPath, thisDataPortion=None,
logFile=None,
continueRun=None, outputFile=None,
overlapFrac=0.25,
matchMethod=None, strictMatch=False):
sampleName1 = sample1.fullName
sampleName2 = sample2.fullName
periodicLine = " --periodic='" + getPeriodic(sample1) + "' "
if strictMatch:
matchPrefix = ""
else:
matchPrefix = "trimmed_nodencut_"
if sample1.dataType == "observation" or sample2.dataType == "observation":
observationLine = " --isObservation"
else:
observationLine = ""
if not (continueRun and jobSuccessful(logFile, "Done!\n")):
cmd = binPath
cmd += " --partFile1=" + sample1Dir+"/zobov_slice_" + \
str(sampleName1)
cmd += " --volFile1=" + sample1Dir+"/vol_" + \
str(sampleName1)+".dat"
cmd += " --voidFile1=" + sample1Dir+"/voidDesc_" + \
thisDataPortion+"_"+str(sampleName1)+".out"
cmd += " --infoFile1=" + sample1Dir+"/zobov_slice_" + \
str(sampleName1)+".par"
cmd += " --centerFile1=" + sample1Dir + \
"/macrocenters_"+thisDataPortion+"_"+str(sampleName1)+".out"
cmd += " --shapeFile1=" + sample1Dir + \
"/shapes_"+thisDataPortion+"_"+str(sampleName1)+".out"
cmd += " --zoneFile1=" + sample1Dir+"/voidZone_" + \
str(sampleName1)+".dat"
cmd += " --zonePartFile1=" + sample1Dir+"/voidPart_" + \
str(sampleName1)+".dat"
cmd += " --partFile2=" + sample2Dir+"/zobov_slice_" + \
str(sampleName2)
cmd += " --volFile2=" + sample2Dir+"/vol_" + \
str(sampleName2)+".dat"
cmd += " --voidFile2=" + sample2Dir+"/"+matchPrefix+"voidDesc_" + \
thisDataPortion+"_"+str(sampleName2)+".out"
cmd += " --infoFile2=" + sample2Dir+"/zobov_slice_" + \
str(sampleName2)+".par"
cmd += " --centerFile2=" + sample2Dir + \
"/"+matchPrefix+"macrocenters_"+thisDataPortion+"_"+str(sampleName2)+".out"
cmd += " --shapeFile2=" + sample2Dir + \
"/"+matchPrefix+"shapes_"+thisDataPortion+"_"+str(sampleName2)+".out"
cmd += " --zoneFile2=" + sample2Dir+"/voidZone_" + \
str(sampleName2)+".dat"
cmd += " --zonePartFile2=" + sample2Dir+"/voidPart_" + \
str(sampleName2)+".dat"
cmd += " --overlapFrac=" + str(overlapFrac)
cmd += observationLine
if matchMethod == "useID": cmd += " --useID"
cmd += periodicLine
cmd += " --outfile=" + outputFile
#cmd += " &> " + logFile
#open("temp.par",'w').write(cmd)
#os.system(cmd)
log = open(logFile, 'w')
subprocess.call(cmd, stdout=log, stderr=log, shell=True)
log.close()
#if jobSuccessful(logFile, "Done!\n"):
print("done")
#else:
# print "FAILED!"
# exit(-1)
else:
print("already done!")
# -----------------------------------------------------------------------------
def launchVelocityStack(sample, stack, binPath,
velField_file,
thisDataPortion=None, logDir=None,
voidDir=None, runSuffix=None,
zobovDir=None,
summaryFile=None,
continueRun=None, dataType=None, prefixRun=""):
sampleName = sample.fullName
runSuffix = getStackSuffix(stack.zMin, stack.zMax, stack.rMin,
stack.rMax, thisDataPortion)
logFile = logDir+("/%svelocity_stack_"%prefixRun)+sampleName+"_"+runSuffix+".out"
voidCenters=voidDir+"/centers.txt"
# Rmax =
centralRadius = stack.rMin * 0.25
Rextracut = stack.rMax*3 + 1
Rcircular = stack.rMax*3 + 2
parameters="--velocityField=%s --voidCenters=%s --Rmax=%e --L0=%e --numBins=%d" % (velField_file, voidCenters, Rmax, Boxsize, numBins)
if not (continueRun and jobSuccessful(logFile, "Done!\n")):
#cmd = "%s %s &> %s" % (binPath,parameters,logFile)
#os.system(cmd)
cmd = "%s %s" % (binPath,parameters)
log = open(logFile, 'w')
subprocess.call(cmd, stdout=log, stderr=log, shell=True)
log.close()
if jobSuccessful(logFile, "Done!\n"):
print("done")
else:
print("FAILED!")
exit(-1)
else:
print("already done!")

View file

@ -0,0 +1,26 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/__init__.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
from .catalogUtil import *
from .plotDefs import *
from .plotUtil import *
from .matchUtil import *
from .xcorUtil import *
from .profileUtil import *

View file

@ -0,0 +1,586 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/catalogUtil.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
# Various utilities for loading and modifying particle datasets
import numpy as np
from netCDF4 import Dataset
import sys
from vide.backend import *
import vide.apTools as vp
import pickle
from .periodic_kdtree import PeriodicCKDTree
import os
NetCDFFile = Dataset
ncFloat = 'f8'
# -----------------------------------------------------------------------------
def loadPart(sampleDir):
print(" Loading particle data...")
sys.stdout.flush()
with open(sampleDir+"/sample_info.dat", 'rb') as input:
sample = pickle.load(input)
infoFile = sampleDir+"/zobov_slice_"+sample.fullName+".par"
File = NetCDFFile(infoFile, 'r')
ranges = np.zeros((3,2))
ranges[0][0] = getattr(File, 'range_x_min')
ranges[0][1] = getattr(File, 'range_x_max')
ranges[1][0] = getattr(File, 'range_y_min')
ranges[1][1] = getattr(File, 'range_y_max')
ranges[2][0] = getattr(File, 'range_z_min')
ranges[2][1] = getattr(File, 'range_z_max')
isObservation = getattr(File, 'is_observation')
maskIndex = getattr(File, 'mask_index')
File.close()
mul = np.zeros((3))
mul[:] = ranges[:,1] - ranges[:,0]
partFile = sampleDir+"/zobov_slice_"+sample.fullName
iLine = 0
partData = []
part = np.zeros((3))
with open(partFile, mode="rb") as File:
chk = np.fromfile(File, dtype=np.int32,count=1)
Np = np.fromfile(File, dtype=np.int32,count=1)[0]
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
x = np.fromfile(File, dtype=np.float32,count=Np)
x *= mul[0]
if isObservation != 1:
x += ranges[0][0]
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
y = np.fromfile(File, dtype=np.float32,count=Np)
y *= mul[1]
if isObservation != 1:
y += ranges[1][0]
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
z = np.fromfile(File, dtype=np.float32,count=Np)
z *= mul[2]
if isObservation != 1:
z += ranges[2][0]
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
RA = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
Dec = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
redshift = np.fromfile(File, dtype=np.float32,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
chk = np.fromfile(File, dtype=np.int32,count=1)
uniqueID = np.fromfile(File, dtype=np.int64,count=Np)
chk = np.fromfile(File, dtype=np.int32,count=1)
if isObservation == 1:
x = x[0:maskIndex]# * 100/300000
y = y[0:maskIndex]# * 100/300000
z = z[0:maskIndex]# * 100/300000
RA = RA[0:maskIndex]
Dec = Dec[0:maskIndex]
redshift = redshift[0:maskIndex]
uniqueID = uniqueID[0:maskIndex]
partData = np.column_stack((x,y,z))
extraData = np.column_stack((RA,Dec,redshift,uniqueID))
boxLen = mul
#if isObservation == 1:
# # look for the mask file
# if os.access(sample.maskFile, os.F_OK):
# maskFile = sample.maskFile
# else:
# maskFile = sampleDir+"/"+os.path.basename(sample.maskFile)
# print "Using maskfile found in:", maskFile
# props = vp.getSurveyProps(maskFile, sample.zBoundary[0],
# sample.zBoundary[1],
# sample.zBoundary[0],
# sample.zBoundary[1], "all",
# selectionFuncFile=sample.selFunFile,
# useComoving=sample.useComoving)
# boxVol = props[0]
# volNorm = maskIndex/boxVol
#else:
boxVol = np.prod(boxLen)
volNorm = len(x)/boxVol
isObservationData = isObservation == 1
return partData, boxLen, volNorm, isObservationData, ranges, extraData
# -----------------------------------------------------------------------------
def getVolNorm(sampleDir):
with open(sampleDir+"/sample_info.dat", 'rb') as input:
sample = pickle.load(input)
infoFile = sampleDir+"/zobov_slice_"+sample.fullName+".par"
File = NetCDFFile(infoFile, 'r')
ranges = np.zeros((3,2))
ranges[0][0] = getattr(File, 'range_x_min')
ranges[0][1] = getattr(File, 'range_x_max')
ranges[1][0] = getattr(File, 'range_y_min')
ranges[1][1] = getattr(File, 'range_y_max')
ranges[2][0] = getattr(File, 'range_z_min')
ranges[2][1] = getattr(File, 'range_z_max')
isObservation = getattr(File, 'is_observation')
maskIndex = getattr(File, 'mask_index')
File.close()
mul = np.zeros((3))
mul[:] = ranges[:,1] - ranges[:,0]
partFile = sampleDir+"/zobov_slice_"+sample.fullName
with open(partFile, mode="rb") as File:
chk = np.fromfile(File, dtype=np.int32,count=1)
Np = np.fromfile(File, dtype=np.int32,count=1)[0]
boxLen = mul
#if isObservation == 1:
# # look for the mask file
# if os.access(sample.maskFile, os.F_OK):
# maskFile = sample.maskFile
# else:
# maskFile = sampleDir+"/"+os.path.basename(sample.maskFile)
# print "Using maskfile found in:", maskFile
# props = vp.getSurveyProps(maskFile, sample.zBoundary[0],
# sample.zBoundary[1],
# sample.zBoundary[0],
# sample.zBoundary[1], "all",
# selectionFuncFile=sample.selFunFile,
# useComoving=sample.useComoving)
# boxVol = props[0]
# volNorm = maskIndex/boxVol
#else:
boxVol = np.prod(boxLen)
volNorm = Np/boxVol
return volNorm
# -----------------------------------------------------------------------------
def loadPartVel(sampleDir):
#print " Loading particle velocities..."
sys.stdout.flush()
with open(sampleDir+"/sample_info.dat", 'rb') as input:
sample = pickle.load(input)
infoFile = sampleDir+"/zobov_slice_"+sample.fullName+".par"
File = NetCDFFile(infoFile, 'r')
isObservation = getattr(File, 'is_observation')
if isObservation:
print("No velocities for observations!")
return -1
vx = File.variables['vel_x'][0:]
vy = File.variables['vel_y'][0:]
vz = File.variables['vel_z'][0:]
File.close()
partVel = np.column_stack((vx,vy,vz))
return partVel
# -----------------------------------------------------------------------------
def getPartTree(catalog):
sample = catalog.sampleInfo
partData = catalog.partPos
boxLen = catalog.boxLen
periodicLine = getPeriodic(sample)
periodic = 1.*boxLen
if not "x" in periodicLine: periodic[0] = -1
if not "y" in periodicLine: periodic[1] = -1
if not "z" in periodicLine: periodic[2] = -1
return PeriodicCKDTree(periodic, partData)
# -----------------------------------------------------------------------------
def getBall(partTree, center, radius):
return partTree.query_ball_point(center, r=radius)
# -----------------------------------------------------------------------------
def shiftPart(inPart, center, periodicLine, ranges):
part = inPart.copy()
newCenter = 1.*center;
boxLen = np.zeros((3))
boxLen[0] = ranges[0][1] - ranges[0][0]
boxLen[1] = ranges[1][1] - ranges[1][0]
boxLen[2] = ranges[2][1] - ranges[2][0]
# shift to box coordinates
part[:,0] -= ranges[0][0]
part[:,1] -= ranges[1][0]
part[:,2] -= ranges[2][0]
newCenter[:] -= ranges[:,0]
part[:,0] -= newCenter[0]
part[:,1] -= newCenter[1]
part[:,2] -= newCenter[2]
shiftUs = np.abs(part[:,0]) > boxLen[0]/2.
if ("x" in periodicLine): part[shiftUs,0] -= \
np.copysign(boxLen[0], part[shiftUs,0])
shiftUs = np.abs(part[:,1]) > boxLen[1]/2.
if ("y" in periodicLine): part[shiftUs,1] -= \
np.copysign(boxLen[1], part[shiftUs,1])
shiftUs = np.abs(part[:,2]) > boxLen[2]/2.
if ("z" in periodicLine): part[shiftUs,2] -= \
np.copysign(boxLen[2], part[shiftUs,2])
#part[:,0] += ranges[0][0]
#part[:,1] += ranges[1][0]
#part[:,2] += ranges[2][0]
return part
# -----------------------------------------------------------------------------
class Bunch:
def __init__(self, **kwds):
self.__dict__.update(kwds)
class Catalog:
numVoids = 0
numPartTot = 0
numZonesTot = 0
volNorm = 0
boxLen = np.zeros((3))
ranges = np.zeros((3,2))
part = None
zones2Parts = None
void2Zones = None
voids = None
sampleInfo = None
# -----------------------------------------------------------------------------
def loadVoidCatalog(sampleDir, dataPortion="central", loadParticles=True,
untrimmed=False):
# loads a void catalog
# by default, loads parent-level voids with central densities greater than 0.2*mean
# sampleDir: path to VIDE output directory
# dataPortion: "central" or "all"
# loadParticles: if True, also load particle information
# untrimmed: if True, catalog contains all voids, regardless of density or hierarchy level
sys.stdout.flush()
catalog = Catalog()
with open(sampleDir+"/sample_info.dat", 'rb') as input:
sample = pickle.load(input)
catalog.sampleInfo = sample
print("Loading info...")
infoFile = sampleDir+"/zobov_slice_"+sample.fullName+".par"
File = NetCDFFile(infoFile, 'r')
ranges = np.zeros((3,2))
ranges[0][0] = getattr(File, 'range_x_min')
ranges[0][1] = getattr(File, 'range_x_max')
ranges[1][0] = getattr(File, 'range_y_min')
ranges[1][1] = getattr(File, 'range_y_max')
ranges[2][0] = getattr(File, 'range_z_min')
ranges[2][1] = getattr(File, 'range_z_max')
catalog.boxLen[0] = ranges[0][1] - ranges[0][0]
catalog.boxLen[1] = ranges[1][1] - ranges[1][0]
catalog.boxLen[2] = ranges[2][1] - ranges[2][0]
catalog.ranges = ranges
File.close()
volNorm = getVolNorm(sampleDir)
catalog.volNorm = volNorm
if untrimmed:
prefix = "untrimmed_"
else:
prefix = ""
print("Loading voids...")
fileName = sampleDir+"/"+prefix+"voidDesc_"+dataPortion+"_"+sample.fullName+".out"
catData = np.loadtxt(fileName, comments="#", skiprows=2)
catalog.voids = []
for line in catData:
catalog.voids.append(Bunch(iVoid = int(line[0]),
voidID = int(line[1]),
coreParticle = line[2],
coreDens = line[3],
zoneVol = line[4],
zoneNumPart = line[5],
numZones = int(line[6]),
voidVol = line[7],
numPart = int(line[8]),
densCon = line[9],
voidProb = line[10],
radius = 0., # this is read in later
macrocenter = np.zeros((3)),
redshift = 0,
RA = 0,
Dec = 0,
parentID = 0,
treeLevel = 0,
numChildren = 0,
centralDen = 0.,
ellipticity = 0.,
eigenVals = np.zeros((3)),
eigenVecs = np.zeros((3,3)),
))
catalog.numVoids = len(catalog.voids)
print("Read %d voids" % catalog.numVoids)
print("Loading macrocenters...")
iLine = 0
for line in open(sampleDir+"/"+prefix+"macrocenters_"+dataPortion+"_"+sample.fullName+".out"):
line = line.split()
catalog.voids[iLine].macrocenter[0] = float(line[1])
catalog.voids[iLine].macrocenter[1] = float(line[2])
catalog.voids[iLine].macrocenter[2] = float(line[3])
iLine += 1
iLine = 0
fileName = sampleDir+"/"+prefix+"sky_positions_"+dataPortion+"_"+sample.fullName+".out"
catData = np.loadtxt(fileName, comments="#")
for line in catData:
catalog.voids[iLine].RA = float(line[0])
catalog.voids[iLine].Dec = float(line[1])
iLine += 1
print("Loading derived void information...")
fileName = sampleDir+"/"+prefix+"centers_"+dataPortion+"_"+sample.fullName+".out"
catData = np.loadtxt(fileName, comments="#")
for (iLine,line) in enumerate(catData):
catalog.voids[iLine].volume = float(line[6])
catalog.voids[iLine].radius = float(line[4])
catalog.voids[iLine].redshift = float(line[5])
catalog.voids[iLine].parentID = float(line[10])
catalog.voids[iLine].treeLevel = float(line[11])
catalog.voids[iLine].numChildren = float(line[12])
catalog.voids[iLine].centralDen = float(line[13])
iLine += 1
fileName = sampleDir+"/"+prefix+"shapes_"+dataPortion+"_"+sample.fullName+".out"
catData = np.loadtxt(fileName, comments="#")
for (iLine,line) in enumerate(catData):
catalog.voids[iLine].ellipticity = float(line[1])
catalog.voids[iLine].eigenVals[0] = float(line[2])
catalog.voids[iLine].eigenVals[1] = float(line[3])
catalog.voids[iLine].eigenVals[2] = float(line[4])
catalog.voids[iLine].eigenVecs[0][0] = float(line[5])
catalog.voids[iLine].eigenVecs[0][1] = float(line[6])
catalog.voids[iLine].eigenVecs[0][2] = float(line[7])
catalog.voids[iLine].eigenVecs[1][0] = float(line[8])
catalog.voids[iLine].eigenVecs[1][1] = float(line[9])
catalog.voids[iLine].eigenVecs[1][2] = float(line[10])
catalog.voids[iLine].eigenVecs[2][0] = float(line[11])
catalog.voids[iLine].eigenVecs[2][1] = float(line[12])
catalog.voids[iLine].eigenVecs[2][2] = float(line[13])
iLine += 1
if loadParticles:
print("Loading all particles...")
partData, boxLen, volNorm, isObservationData, ranges, extraData = loadPart(sampleDir)
numPartTot = len(partData)
catalog.numPartTot = numPartTot
catalog.partPos = partData
catalog.part = []
for i in range(len(partData)):
catalog.part.append(Bunch(x = partData[i][0],
y = partData[i][1],
z = partData[i][2],
volume = 0,
ra = extraData[i][0],
dec = extraData[i][1],
redshift = extraData[i][2],
uniqueID = extraData[i][3]))
print("Loading volumes...")
volFile = sampleDir+"/vol_"+sample.fullName+".dat"
with open(volFile, mode="rb") as File:
chk = np.fromfile(File, dtype=np.int32,count=1)
vols = np.fromfile(File, dtype=np.float32,count=numPartTot)
for ivol in range(len(vols)):
catalog.part[ivol].volume = vols[ivol] / volNorm
print("Loading zone-void membership info...")
zoneFile = sampleDir+"/voidZone_"+sample.fullName+".dat"
catalog.void2Zones = []
with open(zoneFile, mode="rb") as File:
numZonesTot = np.fromfile(File, dtype=np.int32,count=1)[0]
catalog.numZonesTot = numZonesTot
for iZ in range(numZonesTot):
numZones = np.fromfile(File, dtype=np.int32,count=1)[0]
catalog.void2Zones.append(Bunch(numZones = numZones,
zoneIDs = []))
for p in range(numZones):
zoneID = np.fromfile(File, dtype=np.int32,count=1)[0]
catalog.void2Zones[iZ].zoneIDs.append(zoneID)
print("Loading particle-zone membership info...")
zonePartFile = sampleDir+"/voidPart_"+sample.fullName+".dat"
catalog.zones2Parts = []
with open(zonePartFile) as File:
chk = np.fromfile(File, dtype=np.int32,count=1)
numZonesTot = np.fromfile(File, dtype=np.int32,count=1)[0]
for iZ in range(numZonesTot):
numPart = np.fromfile(File, dtype=np.int32,count=1)[0]
catalog.zones2Parts.append(Bunch(numPart = numPart,
partIDs = []))
for p in range(numPart):
partID = np.fromfile(File, dtype=np.int32,count=1)[0]
catalog.zones2Parts[iZ].partIDs.append(partID)
return catalog
# -----------------------------------------------------------------------------
def getArray(objectList, attr):
if hasattr(objectList[0], attr):
ndim = np.shape( np.atleast_1d( getattr(objectList[0], attr) ) )[0]
attrArr = np.zeros(( len(objectList), ndim ))
for idim in range(ndim):
attrArr[:,idim] = np.fromiter((np.atleast_1d(getattr(v, attr))[idim] \
for v in objectList), float )
if ndim == 1: attrArr = attrArr[:,0]
return attrArr
else:
print(" Attribute", attr, "not found!")
return -1
# -----------------------------------------------------------------------------
def getVoidPart(catalog, voidID):
partOut = []
for iZ in range(catalog.void2Zones[voidID].numZones):
zoneID = catalog.void2Zones[voidID].zoneIDs[iZ]
for p in range(catalog.zones2Parts[zoneID].numPart):
partID = catalog.zones2Parts[zoneID].partIDs[p]
partOut.append(catalog.part[partID])
return partOut
# -----------------------------------------------------------------------------
def filterVoidsOnSize(catalog, rMin):
catalog.voids = [v for v in catalog.voids if v.radius >= rMin]
catalog.numVoids = len(catalog.voids)
return catalog
# -----------------------------------------------------------------------------
def filterVoidsOnTreeLevel(catalog, level):
catalog.voids = [v for v in catalog.voids if v.treeLevel == level]
if level == -1:
catalog.voids = [v for v in catalog.voids if v.numChildren == 0]
catalog.numVoids = len(catalog.voids)
return catalog
# -----------------------------------------------------------------------------
def filterVoidsOnCentralDen(catalog, maxCentralDen):
catalog.voids = [v for v in catalog.voids if v.centralDen <= maxCentralDen]
catalog.numVoids = len(catalog.voids)
return catalog
# -----------------------------------------------------------------------------
def filterVoidsOnCoreDen(catalog, maxCoreDen):
catalog.voids = [v for v in catalog.voids if v.coreDens <= maxCoreDen]
catalog.numVoids = len(catalog.voids)
return catalog
# -----------------------------------------------------------------------------
def filterVoidsOnDenCon(catalog, minDenCon):
catalog.voids = [v for v in catalog.voids if v.densCon >= minDenCon]
return catalog
# -----------------------------------------------------------------------------
def stackVoids(catalog, stackMode = "ball"):
# builds a stack of voids from the given catalog
# catalog: void catalog
# stackMode:
# "ball": spherical cut
# "voronoi": only void member particles
#
# returns:
# stackedPart: array of relative particle positions in the stack
rMax = 100.
periodicLine = getPeriodic(catalog.sampleInfo)
if stackMode == "ball":
partTree = getPartTree(catalog)
stackedPart = []
for void in catalog.voids:
center = void.macrocenter
if stackMode == "ball":
localPart = catalog.partPos[ getBall(partTree, center, rMax) ]
else:
voidPart = getVoidPart(catalog, void.voidID)
localPart = np.zeros((len(voidPart),3))
localPart[:,0] = getArray(voidPart, 'x')
localPart[:,1] = getArray(voidPart, 'y')
localPart[:,2] = getArray(voidPart, 'z')
shiftedPart = shiftPart(localPart, center, periodicLine, catalog.ranges)
stackedPart.extend(shiftedPart)
return stackedPart

View file

@ -0,0 +1,83 @@
#!/usr/bin/env python
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/matchUtil.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
__all__=['compareCatalogs',]
from vide.backend import *
import imp
import pickle
import os
import matplotlib.pyplot as plt
import numpy as np
import argparse
def compareCatalogs(baseCatalogDir, compareCatalogDir,
outputDir="./", logDir="./",
matchMethod="useID", dataPortion="central",
strictMatch=True,
overlapFrac=0.25,
pathToCTools="../../../c_tools"):
# reports the overlap between two void catalogs
# baseCatalogDir: directory of catalog 1
# compareCatagDir: directory of catalog 2
# outputDir: directory to place outputs
# logDir: directory to place log files
# matchMethod: "useID" to use unique IDs, "prox" to use overlap of Voronoi cells
# dataPortion: "central" or "all"
# strictMatch: if True, only attempt to match to trimmed catalog
# overlapFrac: threshold fraction of Voronoi radius to count as matched
# pathToCTools: path to location of VIDE c_tools directory
if not os.access(outputDir, os.F_OK):
os.makedirs(outputDir)
if not os.access(logDir, os.F_OK):
os.makedirs(logDir)
outFileName = outputDir + "/" + "voidOverlap" #+ ".dat"
with open(baseCatalogDir+"/sample_info.dat", 'rb') as input:
baseSample = pickle.load(input)
with open(compareCatalogDir+"/sample_info.dat", 'rb') as input:
sample = pickle.load(input)
print(" Comparing", baseSample.fullName, "to", sample.fullName, "...", end=' ')
sys.stdout.flush()
sampleName = sample.fullName
binPath = pathToCTools+"/analysis/voidOverlap"
logFile = logDir+"/compare_"+baseSample.fullName+"_"+sampleName+".out"
stepOutputFileName = outFileName + "_" + baseSample.fullName + "_" + \
sampleName + "_"
launchVoidOverlap(baseSample, sample, baseCatalogDir,
compareCatalogDir, binPath,
thisDataPortion=dataPortion, logFile=logFile,
continueRun=False,
outputFile=stepOutputFileName,
matchMethod=matchMethod,
overlapFrac=overlapFrac,
strictMatch=strictMatch)
print(" Done!")
return

View file

@ -0,0 +1,394 @@
# periodic_kdtree.py
#
# A wrapper around scipy.spatial.kdtree to implement periodic boundary
# conditions
#
# Written by Patrick Varilly, 6 Jul 2012
# Released under the scipy license
import numpy as np
from scipy.spatial import KDTree, cKDTree
import itertools
import heapq
def _gen_relevant_images(x, bounds, distance_upper_bound):
# Map x onto the canonical unit cell, then produce the relevant
# mirror images
real_x = x - np.where(bounds > 0.0,
np.floor(x / bounds) * bounds, 0.0)
m = len(x)
xs_to_try = [real_x]
for i in range(m):
if bounds[i] > 0.0:
disp = np.zeros(m)
disp[i] = bounds[i]
if distance_upper_bound == np.inf:
xs_to_try = list(
itertools.chain.from_iterable(
(_ + disp, _, _ - disp) for _ in xs_to_try))
else:
extra_xs = []
# Point near lower boundary, include image on upper side
if abs(real_x[i]) < distance_upper_bound:
extra_xs.extend(_ + disp for _ in xs_to_try)
# Point near upper boundary, include image on lower side
if abs(bounds[i] - real_x[i]) < distance_upper_bound:
extra_xs.extend(_ - disp for _ in xs_to_try)
xs_to_try.extend(extra_xs)
return xs_to_try
class PeriodicKDTree(KDTree):
"""
kd-tree for quick nearest-neighbor lookup with periodic boundaries
See scipy.spatial.kdtree for details on kd-trees.
Searches with periodic boundaries are implemented by mapping all
initial data points to one canonical periodic image, building an
ordinary kd-tree with these points, then querying this kd-tree multiple
times, if necessary, with all the relevant periodic images of the
query point.
Note that to ensure that no two distinct images of the same point
appear in the results, it is essential to restrict the maximum
distance between a query point and a data point to half the smallest
box dimension.
"""
def __init__(self, bounds, data, leafsize=10):
"""Construct a kd-tree.
Parameters
----------
bounds : array_like, shape (k,)
Size of the periodic box along each spatial dimension. A
negative or zero size for dimension k means that space is not
periodic along k.
data : array_like, shape (n,k)
The data points to be indexed. This array is not copied, and
so modifying this data will result in bogus results.
leafsize : positive int
The number of points at which the algorithm switches over to
brute-force.
"""
# Map all points to canonical periodic image
self.bounds = np.array(bounds)
self.real_data = np.asarray(data)
wrapped_data = (
self.real_data - np.where(bounds > 0.0,
(np.floor(self.real_data / bounds) * bounds), 0.0))
# Calculate maximum distance_upper_bound
self.max_distance_upper_bound = np.min(
np.where(self.bounds > 0, 0.5 * self.bounds, np.inf))
# Set up underlying kd-tree
super(PeriodicKDTree, self).__init__(wrapped_data, leafsize)
# The following name is a kludge to override KDTree's private method
def _KDTree__query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
# This is the internal query method, which guarantees that x
# is a single point, not an array of points
#
# A slight complication: k could be "None", which means "return
# all neighbors within the given distance_upper_bound".
# Cap distance_upper_bound
distance_upper_bound = min([distance_upper_bound,
self.max_distance_upper_bound])
# Run queries over all relevant images of x
hits_list = []
for real_x in _gen_relevant_images(x, self.bounds, distance_upper_bound):
hits_list.append(
super(PeriodicKDTree, self)._KDTree__query(
real_x, k, eps, p, distance_upper_bound))
# Now merge results
if k is None:
return list(heapq.merge(*hits_list))
elif k > 1:
return heapq.nsmallest(k, itertools.chain(*hits_list))
elif k == 1:
return [min(itertools.chain(*hits_list))]
else:
raise ValueError("Invalid k in periodic_kdtree._KDTree__query")
# The following name is a kludge to override KDTree's private method
def _KDTree__query_ball_point(self, x, r, p=2., eps=0):
# This is the internal query method, which guarantees that x
# is a single point, not an array of points
# Cap r
r = min(r, self.max_distance_upper_bound)
# Run queries over all relevant images of x
results = []
for real_x in _gen_relevant_images(x, self.bounds, r):
results.extend(
super(PeriodicKDTree, self)._KDTree__query_ball_point(
real_x, r, p, eps))
return results
def query_ball_tree(self, other, r, p=2., eps=0):
raise NotImplementedError()
def query_pairs(self, r, p=2., eps=0):
raise NotImplementedError()
def count_neighbors(self, other, r, p=2.):
raise NotImplementedError()
def sparse_distance_matrix(self, other, max_distance, p=2.):
raise NotImplementedError()
class PeriodicCKDTree(cKDTree):
"""
Cython kd-tree for quick nearest-neighbor lookup with periodic boundaries
See scipy.spatial.ckdtree for details on kd-trees.
Searches with periodic boundaries are implemented by mapping all
initial data points to one canonical periodic image, building an
ordinary kd-tree with these points, then querying this kd-tree multiple
times, if necessary, with all the relevant periodic images of the
query point.
Note that to ensure that no two distinct images of the same point
appear in the results, it is essential to restrict the maximum
distance between a query point and a data point to half the smallest
box dimension.
"""
def __init__(self, bounds, data, leafsize=10):
"""Construct a kd-tree.
Parameters
----------
bounds : array_like, shape (k,)
Size of the periodic box along each spatial dimension. A
negative or zero size for dimension k means that space is not
periodic along k.
data : array-like, shape (n,m)
The n data points of dimension mto be indexed. This array is
not copied unless this is necessary to produce a contiguous
array of doubles, and so modifying this data will result in
bogus results.
leafsize : positive integer
The number of points at which the algorithm switches over to
brute-force.
"""
# Map all points to canonical periodic image
self.bounds = np.array(bounds)
self.real_data = np.asarray(data)
wrapped_data = (
self.real_data - np.where(bounds > 0.0,
(np.floor(self.real_data / bounds) * bounds), 0.0))
# Calculate maximum distance_upper_bound
self.max_distance_upper_bound = np.min(
np.where(self.bounds > 0, 0.5 * self.bounds, np.inf))
# Set up underlying kd-tree
super(PeriodicCKDTree, self).__init__(wrapped_data, leafsize)
# Ideally, KDTree and cKDTree would expose identical query and __query
# interfaces. But they don't, and cKDTree.__query is also inaccessible
# from Python. We do our best here to cope.
def __query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
# This is the internal query method, which guarantees that x
# is a single point, not an array of points
#
# A slight complication: k could be "None", which means "return
# all neighbors within the given distance_upper_bound".
# Cap distance_upper_bound
distance_upper_bound = np.min([distance_upper_bound,
self.max_distance_upper_bound])
# Run queries over all relevant images of x
hits_list = []
for real_x in _gen_relevant_images(x, self.bounds, distance_upper_bound):
d, i = super(PeriodicCKDTree, self).query(
real_x, k, eps, p, distance_upper_bound)
if k > 1:
hits_list.append(list(zip(d, i)))
else:
hits_list.append([(d, i)])
# Now merge results
if k > 1:
return heapq.nsmallest(k, itertools.chain(*hits_list))
elif k == 1:
return [min(itertools.chain(*hits_list))]
else:
raise ValueError("Invalid k in periodic_kdtree._KDTree__query")
def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
"""
Query the kd-tree for nearest neighbors
Parameters
----------
x : array_like, last dimension self.m
An array of points to query.
k : integer
The number of nearest neighbors to return.
eps : non-negative float
Return approximate nearest neighbors; the kth returned value
is guaranteed to be no further than (1+eps) times the
distance to the real k-th nearest neighbor.
p : float, 1<=p<=infinity
Which Minkowski p-norm to use.
1 is the sum-of-absolute-values "Manhattan" distance
2 is the usual Euclidean distance
infinity is the maximum-coordinate-difference distance
distance_upper_bound : nonnegative float
Return only neighbors within this distance. This is used to prune
tree searches, so if you are doing a series of nearest-neighbor
queries, it may help to supply the distance to the nearest neighbor
of the most recent point.
Returns
-------
d : array of floats
The distances to the nearest neighbors.
If x has shape tuple+(self.m,), then d has shape tuple+(k,).
Missing neighbors are indicated with infinite distances.
i : ndarray of ints
The locations of the neighbors in self.data.
If `x` has shape tuple+(self.m,), then `i` has shape tuple+(k,).
Missing neighbors are indicated with self.n.
"""
x = np.asarray(x)
if np.shape(x)[-1] != self.m:
raise ValueError("x must consist of vectors of length %d but has shape %s" % (self.m, np.shape(x)))
if p<1:
raise ValueError("Only p-norms with 1<=p<=infinity permitted")
retshape = np.shape(x)[:-1]
if retshape!=():
if k>1:
dd = np.empty(retshape+(k,),dtype=np.float)
dd.fill(np.inf)
ii = np.empty(retshape+(k,),dtype=np.int)
ii.fill(self.n)
elif k==1:
dd = np.empty(retshape,dtype=np.float)
dd.fill(np.inf)
ii = np.empty(retshape,dtype=np.int)
ii.fill(self.n)
else:
raise ValueError("Requested %s nearest neighbors; acceptable numbers are integers greater than or equal to one, or None")
for c in np.ndindex(retshape):
hits = self.__query(x[c], k=k, eps=eps, p=p, distance_upper_bound=distance_upper_bound)
if k>1:
for j in range(len(hits)):
dd[c+(j,)], ii[c+(j,)] = hits[j]
elif k==1:
if len(hits)>0:
dd[c], ii[c] = hits[0]
else:
dd[c] = np.inf
ii[c] = self.n
return dd, ii
else:
hits = self.__query(x, k=k, eps=eps, p=p, distance_upper_bound=distance_upper_bound)
if k==1:
if len(hits)>0:
return hits[0]
else:
return np.inf, self.n
elif k>1:
dd = np.empty(k,dtype=np.float)
dd.fill(np.inf)
ii = np.empty(k,dtype=np.int)
ii.fill(self.n)
for j in range(len(hits)):
dd[j], ii[j] = hits[j]
return dd, ii
else:
raise ValueError("Requested %s nearest neighbors; acceptable numbers are integers greater than or equal to one, or None")
# Ideally, KDTree and cKDTree would expose identical __query_ball_point
# interfaces. But they don't, and cKDTree.__query_ball_point is also
# inaccessible from Python. We do our best here to cope.
def __query_ball_point(self, x, r, p=2., eps=0):
# This is the internal query method, which guarantees that x
# is a single point, not an array of points
# Cap r
r = min(r, self.max_distance_upper_bound)
# Run queries over all relevant images of x
results = []
for real_x in _gen_relevant_images(x, self.bounds, r):
results.extend(super(PeriodicCKDTree, self).query_ball_point(
real_x, r, p, eps))
return results
def query_ball_point(self, x, r, p=2., eps=0):
"""
Find all points within distance r of point(s) x.
Parameters
----------
x : array_like, shape tuple + (self.m,)
The point or points to search for neighbors of.
r : positive float
The radius of points to return.
p : float, optional
Which Minkowski p-norm to use. Should be in the range [1, inf].
eps : nonnegative float, optional
Approximate search. Branches of the tree are not explored if their
nearest points are further than ``r / (1 + eps)``, and branches are
added in bulk if their furthest points are nearer than
``r * (1 + eps)``.
Returns
-------
results : list or array of lists
If `x` is a single point, returns a list of the indices of the
neighbors of `x`. If `x` is an array of points, returns an object
array of shape tuple containing lists of neighbors.
Notes
-----
If you have many points whose neighbors you want to find, you may
save substantial amounts of time by putting them in a
PeriodicCKDTree and using query_ball_tree.
"""
x = np.asarray(x).astype(np.float)
if x.shape[-1] != self.m:
raise ValueError("Searching for a %d-dimensional point in a " \
"%d-dimensional KDTree" % (x.shape[-1], self.m))
if len(x.shape) == 1:
return self.__query_ball_point(x, r, p, eps)
else:
retshape = x.shape[:-1]
result = np.empty(retshape, dtype=np.object)
for c in np.ndindex(retshape):
result[c] = self.__query_ball_point(x[c], r, p, eps)
return result
def query_ball_tree(self, other, r, p=2., eps=0):
raise NotImplementedError()
def query_pairs(self, r, p=2., eps=0):
raise NotImplementedError()
def count_neighbors(self, other, r, p=2.):
raise NotImplementedError()
def sparse_distance_matrix(self, other, max_distance, p=2.):
raise NotImplementedError()

View file

@ -0,0 +1,33 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/plotDefs.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
LIGHT_SPEED = 299792.458
colorList = ['r', 'b', 'g', 'y', 'c', 'm',
'darkred', 'grey',
'orange', 'darkblue',
'indigo', 'lightseagreen', 'maroon', 'olive',
'royalblue', 'palevioletred', 'seagreen', 'tomato',
'aquamarine', 'darkslateblue',
'khaki', 'lawngreen', 'mediumorchid',
'orangered', 'thistle'
'yellowgreen']
linewidth = 4
fontsize = 12

View file

@ -0,0 +1,298 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/plotUtil.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
__all__=['plotNumberFunction','plotEllipDist','plotVoidCells']
from vide.backend.classes import *
from .plotDefs import *
import numpy as np
import os
import pylab as plt
import vide.backend.cosmologyTools as vp
from vide.voidUtil import getArray, shiftPart, getVoidPart
def fill_between(x, y1, y2=0, ax=None, **kwargs):
"""Plot filled region between `y1` and `y2`.
This function works exactly the same as matplotlib's fill_between, except
that it also plots a proxy artist (specifically, a rectangle of 0 size)
so that it can be added it appears on a legend.
"""
ax = ax if ax is not None else plt.gca()
ax.fill_between(x, y1, y2, interpolate=True, **kwargs)
p = plt.Rectangle((0, 0), 0, 0, **kwargs)
ax.add_patch(p)
# -----------------------------------------------------------------------------
def plotNumberFunction(catalogList,
figDir="./",
plotName="numberfunc",
cumulative=True,
binWidth=1):
# plots a cumulative number function
# catalogList: list of void catalogs to plot
# figDir: output directory for figures
# plotName: name to prefix to all outputs
# cumulative: if True, plots cumulative number function
# binWidth: width of histogram bins in Mpc/h
# returns:
# ellipDistList: array of len(catalogList),
# each element has array of size bins, number, +/- 1 sigma
print("Plotting number function")
catalogList = np.atleast_1d(catalogList)
plt.clf()
plt.xlabel("$R_{eff}$ [$h^{-1}Mpc$]", fontsize=14)
if cumulative:
plt.ylabel(r"log ($n$ (> R) [$h^3$ Gpc$^{-3}$])", fontsize=14)
else:
plt.ylabel(r"log ($dn/dR$ [$h^3$ Gpc$^{-3}$])", fontsize=14)
ellipDistList = []
for (iSample,catalog) in enumerate(catalogList):
sample = catalog.sampleInfo
data = getArray(catalog.voids, 'radius')
if sample.dataType == "observation":
maskFile = sample.maskFile
boxVol = vp.getSurveyProps(maskFile,
sample.zBoundary[0], sample.zBoundary[1],
sample.zRange[0], sample.zRange[1], "all",
selectionFuncFile=sample.selFunFile)[0]
else:
boxVol = sample.boxLen*sample.boxLen*(sample.zBoundaryMpc[1] -
sample.zBoundaryMpc[0])
boxVol *= 1.e-9 # Mpc->Gpc
bins = 100./binWidth
hist, binEdges = np.histogram(data, bins=bins, range=(0., 100.))
binCenters = 0.5*(binEdges[1:] + binEdges[:-1])
if cumulative:
foundStart = False
for iBin in range(len(hist)):
if not foundStart and hist[iBin] == 0:
continue
foundStart = True
hist[iBin] = np.sum(hist[iBin:])
nvoids = len(data)
var = hist * (1. - hist/nvoids)
sig = np.sqrt(var)
lowerbound = hist - sig
upperbound = hist + sig
mean = np.log10(hist/boxVol)
lowerbound = np.log10(lowerbound/boxVol)
upperbound = np.log10(upperbound/boxVol)
lineColor = colorList[iSample]
lineTitle = sample.fullName
trim = (lowerbound > .01)
mean = mean[trim]
binCentersToUse = binCenters[trim]
lower = lowerbound[trim]
upper = upperbound[trim]
alpha = 0.55
fill_between(binCentersToUse, lower, upper,
label=lineTitle, color=lineColor,
alpha=alpha,
)
lineStyle = '-'
plt.plot(binCentersToUse, mean, lineStyle,
color=lineColor,
linewidth=3)
ellipDistList.append((binCentersToUse, mean, lower, upper))
plt.legend(loc = "upper right", fancybox=True, prop={'size':14})
plt.savefig(figDir+"/fig_"+plotName+".pdf", bbox_inches="tight")
plt.savefig(figDir+"/fig_"+plotName+".eps", bbox_inches="tight")
plt.savefig(figDir+"/fig_"+plotName+".png", bbox_inches="tight")
return ellipDistList
# -----------------------------------------------------------------------------
def plotEllipDist(catalogList,
figDir="./",
plotName="ellipdist"):
# plots ellipticity distributions
# catalogList: list of void catalogs to plot
# figDir: output directory for figures
# plotName: name to prefix to all outputs
# returns:
# ellipDistList: array of len(catalogList),
# each element has array of ellipticity distributions
print("Plotting ellipticity distributions")
plt.clf()
plt.xlabel(r"Ellipticity $\epsilon$", fontsize=14)
plt.ylabel(r"P($\epsilon$)", fontsize=14)
ellipDistList = []
catalogList = np.atleast_1d(catalogList)
for (iSample,catalog) in enumerate(catalogList):
sample = catalog.sampleInfo
data = getArray(catalog.voids, 'ellipticity')
dataWeights = np.ones_like(data)/len(data)
dataHist, dataBins = np.histogram(data, bins=10, weights=dataWeights,
range=(0.0,0.35))
binCenters = 0.5*(dataBins[1:] + dataBins[:-1])
plt.plot(binCenters, dataHist, label=sample.fullName,
color=colorList[iSample])
ellipDistList.append((dataBins, dataHist,))
plt.legend(loc = "upper right", fancybox=True, prop={'size':14})
plt.savefig(figDir+"/fig_"+plotName+".pdf", bbox_inches="tight")
plt.savefig(figDir+"/fig_"+plotName+".eps", bbox_inches="tight")
plt.savefig(figDir+"/fig_"+plotName+".png", bbox_inches="tight")
return
# -----------------------------------------------------------------------------
def plotVoidCells(catalog,
voidID,
figDir="./",
plotName="cells",
plotDensity=True,
sliceWidth=250):
# plots the particles belonging to a void
# catalog: void catalog
# voidID: ID of void to plot
# figDir: output directory for figures
# plotName: name to prefix to all outputs
# sliceWidth: width of slice in Mpc/h
sample = catalog.sampleInfo
periodicLine = getPeriodic(sample)
plt.clf()
iVoid = -1
for i in range(len(catalog.voids)):
if catalog.voids[i].voidID == voidID:
iVoid = i
break
if iVoid == -1:
print("Void ID %d not found!" % voidID)
return
sliceCenter = catalog.voids[iVoid].macrocenter
xwidth = sliceWidth
ywidth = sliceWidth
zwidth = max(sliceWidth/4., 50)
xmin = -xwidth/2.
xmax = xwidth/2.
ymin = -ywidth/2.
ymax = ywidth/2.
zmin = -zwidth/2.
zmax = zwidth/2.
#Slice Particles
if plotDensity:
part = catalog.partPos
part = shiftPart(part, sliceCenter, periodicLine, catalog.ranges)
filter = (part[:,0] > xmin) & (part[:,0] < xmax) & \
(part[:,1] > ymin) & (part[:,1] < ymax) & \
(part[:,2] > zmin) & (part[:,2] < zmax)
part = part[filter]
extent = [xmin, xmax, ymin, ymax]
hist, xedges, yedges = np.histogram2d(part[:,0], part[:,1], normed=False,
bins=64)
hist = np.log10(hist+1)
plt.imshow(hist,
aspect='equal',
extent=extent,
interpolation='gaussian',
cmap='YlGnBu_r')
# overlay voids as circles
fig = plt.gcf()
voidPart = getVoidPart(catalog, voidID)
newpart = np.zeros((len(voidPart),3))
volume=np.zeros(len(voidPart))
radius=np.zeros(len(voidPart))
newpart[:,0] = getArray(voidPart, 'x')
newpart[:,1] = getArray(voidPart, 'y')
newpart[:,2] = getArray(voidPart, 'z')
volume = getArray(voidPart, 'volume')
radius = (3.*volume/(4.*np.pi))**(1./3.)
shiftedPartVoid =shiftPart(newpart,sliceCenter, periodicLine, catalog.ranges)
#Limiting plotted cells to cells into the slice
#Possibility to only plot bigger cells (through cellsradiuslim)
cellsMinlimz = zmin
cellsMaxlimz = zmax
cellsradiuslim = 0.0
for p in range(len(volume)):
if (shiftedPartVoid[p,2]>(cellsMinlimz) and \
shiftedPartVoid[p,2]<(cellsMaxlimz) and \
radius[p]>cellsradiuslim):
color = 'blue'
circle = plt.Circle((shiftedPartVoid[p,0], \
shiftedPartVoid[p,1]), \
radius[p],
alpha =.2, fc=color,edgecolor=None,linewidth=1)
fig.gca().add_artist(circle)
title="cells"+str(voidID)
plt.title(title, fontsize=20)
plotName="cells"+str(voidID)
plt.savefig(figDir+"/fig_"+plotName+".pdf", bbox_inches="tight")
plt.savefig(figDir+"/fig_"+plotName+".eps", bbox_inches="tight")
plt.savefig(figDir+"/fig_"+plotName+".png", bbox_inches="tight")
return

View file

@ -0,0 +1,213 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/profileUtil.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
__all__=['buildProfile','fitHSWProfile','getHSWProfile',]
from vide.backend.classes import *
from vide.voidUtil import *
from .plotDefs import *
import numpy as np
import os
import vide.apTools as vp
from scipy.optimize import curve_fit
from scipy.interpolate import interp1d
def HSWProfile(r, rs, dc):
alpha = -2.0*rs + 4.0
if rs < 0.91:
beta = 17.5*rs - 6.5
else:
beta = -9.8*rs + 18.4
return dc * (1 - (r/rs)**alpha) / (1+ (r)**beta) + 1
# -----------------------------------------------------------------------------
def buildProfile(catalog, rMin, rMax, nBins=10):
# builds a stacked radial density profile from the given catalog
# catalog: void catalog
# rMin: minimum void radius, in Mpc/h
# rMax: maximum void radius, in Mpc/h
# nBins: number of bins in profile (detaulf 10)
#
# returns:
# binCenters: array of radii in binned profile
# stackedProfile: the stacked density profile
# sigmas: 1-sigma uncertainty in each bin
rMaxProfile = rMin*3 + 2
periodicLine = getPeriodic(catalog.sampleInfo)
print(" Building particle tree...")
partTree = getPartTree(catalog)
print(" Selecting voids to stack...")
voidsToStack = [v for v in catalog.voids if (v.radius > rMin and v.radius < rMax)]
if len(voidsToStack) == 0:
print(" No voids to stack!")
return -1, -1, -1
print(" Stacking voids...")
allProfiles = []
for void in voidsToStack:
center = void.macrocenter
localPart = catalog.partPos[ getBall(partTree, center, rMaxProfile) ]
shiftedPart = shiftPart(localPart, center, periodicLine, catalog.ranges)
dist = np.sqrt(np.sum(shiftedPart[:,:]**2, axis=1))
thisProfile, radii = np.histogram(dist, bins=nBins, range=(0,rMaxProfile))
deltaV = 4*np.pi/3*(radii[1:]**3-radii[0:(radii.size-1)]**3)
thisProfile = np.float32(thisProfile)
thisProfile /= deltaV
thisProfile /= catalog.volNorm
allProfiles.append(thisProfile)
binCenters = 0.5*(radii[1:] + radii[:-1])
nVoids = len(voidsToStack)
stackedProfile = np.mean(allProfiles, axis=0)
sigmas = np.std(allProfiles, axis=0) / np.sqrt(nVoids)
return binCenters, stackedProfile, sigmas
# -----------------------------------------------------------------------------
def fitHSWProfile(radii, densities, sigmas, rV):
# fits the given density profile to the HSW function
# radii: array of radii
# densities: array of densities in units of mean density
# sigmas: array of uncertainties
# rV: mean effective void radius
#
# returns:
# popt: best-fit values of rs and dc
# pcov: covariance matrix
# rVals: array of radii for best-fit curve
# hswProfile: array of densities for best-fit curve in units of mean density
popt, pcov = curve_fit(HSWProfile, radii/rV, densities,
sigma=sigmas,
maxfev=10000, xtol=5.e-3,
p0=[1.0,-1.0])
# return best-fits
rVals = np.linspace(0.0, radii[-1], 100) / rV
return popt, pcov, rVals*rV, HSWProfile(rVals,popt[0],popt[1])
# -----------------------------------------------------------------------------
def getHSWProfile(density, radius):
# returns the HSW profile for the given sample density and void size
# will interpolate/extrapole the radius
# density: choice of sample (see arXiv:1309.5087):
# maxDM: DM at 1 particles per cubic Mpc/h
# fullDM: DM at 0.01 particles per cubic Mpc/h
# denseDM: DM at 4.e-3 particles per cubic Mpc/h
# sparseDM: DM at 3.e-4 particles per cubic Mpc/h
#
# denseHalos: halos at 4.e-3 particles per cubic Mpc/h
# sparseHalos: halos at 3.e-4 particles per cubic Mpc/h
#
# denseGal: galaxies at 4.e-3 particles per cubic Mpc/h
# sparseGal: galaxies at 3.e-4 particles per cubic Mpc/h
#
# radius: void size in Mpc/h
# returns:
# (rs, dc): best-fit values
# binCenters: array of radii in binned profile
# stackedProfile: the density profile
samples = [
{'name': 'maxDM',
'rv': [8.74041095, 11.65557095, 15.54746657, 20.94913774, 28.41063131, 38.61523696, 51.85944898, 69.42297033],
'rs': [0.74958738, 0.79650829, 0.86245251, 0.93960051, 1.01595177, 1.13159483, 1.31457096, 1.65611709],
'dc': [-0.95353184, -0.94861939, -0.91888455, -0.84480086, -0.73431544, -0.62614422, -0.54908132, -0.4912146],
},
{'name': 'fullDM',
'rv': [10, 15, 20, 25, 30, 35],
'rs': [ 0.76986779, 0.80980775, 0.86590177, 0.93732629, 1.02643542,
1.12875503],
'dc': [-0.81021 , -0.78115474, -0.78326026, -0.78670109, -0.76626508,
-0.72531084],
},
{'name': 'denseDM',
'rv': [10, 15, 20, 25, 30, 35, 40],
'rs': [0.7477462 , 0.79932797, 0.84369297, 0.90309363, 0.92990401,
1.06970842, 1.16393474],
'dc': [-0.78333107, -0.75780925, -0.71586397, -0.74669512, -0.74902649,
-0.75342964, -0.76598043],
},
{'name': 'sparseDM',
'rv': [25, 30, 35, 40, 45, 50, 55, 60],
'rs': [0.78351117, 0.79751047, 0.8225573 , 0.83751894, 0.85443167,
0.86346031, 0.85692501, 0.91470448],
'dc': [-0.67407548, -0.62389586, -0.59125414, -0.55341724, -0.54659457,
-0.5297821 , -0.534683 , -0.51055946],
},
{'name': 'denseHalos',
'rv': [15, 20, 25, 30, 35, 40, 45, 50, 55],
'rs': [0.75393528, 0.7758442 , 0.79720886, 0.81560553, 0.83797299,
0.84377082, 0.84900783, 0.8709897 , 0.86886687],
'dc': [-0.81348968, -0.77362777, -0.74336192, -0.72571135, -0.67928029,
-0.6279349 , -0.6313316 , -0.55188564, -0.48096026],
},
{'name': 'sparseHalos',
'rv': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70],
'rs': [0.76420703, 0.78939067, 0.80480265, 0.82315275, 0.8158607 ,
0.82553517, 0.83843323, 0.85759226, 0.8471268 , 0.89286939],
'dc': [-0.79317192, -0.81661415, -0.76770778, -0.7151494 , -0.718561 ,
-0.70858856, -0.68995608, -0.67415305, -0.63706798, -0.5303759],
},
{'name': 'denseGal',
'rv': [10, 15, 20, 25, 30, 35, 40, 45],
'rs': [0.70048139, 0.73717884, 0.75338516, 0.76782043, 0.79292536,
0.80157122, 0.8207239 , 0.8091386],
'dc': [-0.83166549, -0.86505329, -0.81066899, -0.7662453 , -0.72840363,
-0.65163607, -0.57937656, -0.57125164],
},
{'name': 'sparseGal',
'rv': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75],
'rs': [0.75928922, 0.76622648, 0.77695425, 0.79963152, 0.8045125 ,
0.81892965, 0.83439691, 0.86600085, 0.83166875, 0.85283258,
0.83971344],
'dc': [-0.82413212, -0.87483536, -0.8221596 , -0.78459706, -0.75290061,
-0.77513988, -0.70012913, -0.67487994, -0.69903308, -0.65811992,
-0.57929526],
},
]
mySample = next((item for item in samples if item['name'] == density), None)
if mySample == None:
print("Sample", density," not found! Use one of ", [item['name'] for item in samples])
return
# interpolate the radii
rsFunc = interp1d( mySample['rv'], mySample['rs'], kind='cubic' )
dcFunc = interp1d( mySample['rv'], mySample['dc'], kind='cubic' )
rs = rsFunc(radius)
dc = dcFunc(radius)
# return best-fits
rVals = np.linspace(0.0, 3*radius, 100) / radius
return (rs,dc), rVals*radius, HSWProfile(rVals,rs,dc)

View file

@ -0,0 +1,147 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/xcorUtil.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib import rc
from . import xcorlib
from vide.voidUtil import getArray
def computeXcor(catalog,
figDir="./",
Nmesh = 256,
Nbin = 100
):
# Computes and plots void-void and void-matter(galaxy) correlations
# catalog: catalog to analyze
# figDir: where to place plots
# Nmesh: number of grid cells in cic mesh-interpolation
# Nbin: number of bins in final plots
# Parameters
Lbox = catalog.boxLen[0] # Boxlength
Lboxcut = 0.
Lbox -= 2*Lboxcut
# Input particle arrays of shape (N,3)
xm = catalog.partPos # Halos / Galaxies / Dark matter
xv = getArray(catalog.voids, 'macrocenter')
# Interpolate to mesh
dm, wm, ws = xcorlib.cic(xm, Lbox, Lboxcut = Lboxcut, Nmesh = Nmesh, weights = None)
dv, wm, ws = xcorlib.cic(xv, Lbox, Lboxcut = Lboxcut, Nmesh = Nmesh, weights = None)
# Fourier transform
dmk = np.fft.rfftn(dm)
dvk = np.fft.rfftn(dv)
# 1D Power spectra & correlation functions
((Nm, km, Pmm, SPmm),(Nmx, rm, Xmm, SXmm)) = xcorlib.powcor(dmk, dmk, Lbox, Nbin, 'lin', True, True, 1)
((Nm, km, Pvm, SPvm),(Nmx, rm, Xvm, SXvm)) = xcorlib.powcor(dvk, dmk, Lbox, Nbin, 'lin', True, True, 1)
((Nm, km, Pvv, SPvv),(Nmx, rm, Xvv, SXvv)) = xcorlib.powcor(dvk, dvk, Lbox, Nbin, 'lin', True, True, 1)
# Number densities
nm = np.empty(len(km))
nv = np.empty(len(km))
nm[:] = len(xm)/Lbox**3
nv[:] = len(xv)/Lbox**3
# Plots
mpl.rc('font', family='serif')
ms = 2.5
fs = 16
mew = 0.1
margin = 1.2
kmin = km.min()/margin
kmax = km.max()*margin
rmin = rm.min()/margin
rmax = rm.max()*margin
# Density fields (projected)
plt.imshow(np.sum(dm[:,:,:]+1,2),extent=[0,Lbox,0,Lbox],aspect='equal',cmap='YlGnBu_r',interpolation='gaussian')
plt.xlabel(r'$x \;[h^{-1}\mathrm{Mpc}]$')
plt.ylabel(r'$y \;[h^{-1}\mathrm{Mpc}]$')
plt.title(r'Dark matter')
plt.savefig(figDir+'/dm.eps', bbox_inches="tight")
plt.savefig(figDir+'/dm.pdf', bbox_inches="tight")
plt.savefig(figDir+'/dm.png', bbox_inches="tight")
plt.clf()
plt.imshow(np.sum(dv[:,:,:]+1,2)/Nmesh,extent=[0,Lbox,0,Lbox],aspect='equal',cmap='YlGnBu_r',interpolation='gaussian')
plt.xlabel(r'$x \;[h^{-1}\mathrm{Mpc}]$')
plt.ylabel(r'$y \;[h^{-1}\mathrm{Mpc}]$')
plt.title(r'Voids')
plt.savefig(figDir+'/dv.eps', bbox_inches="tight") #, dpi=300
plt.savefig(figDir+'/dv.pdf', bbox_inches="tight") #, dpi=300
plt.savefig(figDir+'/dv.png', bbox_inches="tight") #, dpi=300
plt.clf()
# Power spectra & correlation functions
pa ,= plt.plot(km, Pmm, 'k-o', ms=0.8*ms, mew=mew, mec='k')
#plt.plot(km, Pmm-1./nm, 'k--', ms=ms, mew=mew)
plt.fill_between(km, Pmm+SPmm, abs(Pmm-SPmm), color='k', alpha=0.2)
pb ,= plt.plot(km, Pvm, 'm-D', ms=ms, mew=mew, mec='k')
plt.plot(km, -Pvm, 'mD', ms=ms, mew=mew, mec='k')
plt.fill_between(km, abs(Pvm+SPvm), abs(Pvm-SPvm), color='m', alpha=0.2)
pc ,= plt.plot(km, Pvv, 'b-p', ms=1.3*ms, mew=mew, mec='k')
#plt.plot(km, Pvv-1./nv, 'b--', ms=ms, mew=mew)
plt.fill_between(km, Pvv+SPvv, abs(Pvv-SPvv), color='b', alpha=0.2)
plt.xlabel(r'$k \;[h\mathrm{Mpc}^{-1}]$')
plt.ylabel(r'$P(k) \;[h^{-3}\mathrm{Mpc}^3]$')
plt.title(r'Power spectra')
plt.xscale('log')
plt.yscale('log')
plt.xlim(kmin,kmax)
plt.ylim(10**np.floor(np.log10(abs(Pvm[1:]).min()))/margin, max(10**np.ceil(np.log10(Pmm.max())),10**np.ceil(np.log10(Pvv.max())))*margin)
plt.legend([pa, pb, pc],['tt', 'vt', 'vv'],'best',prop={'size':12})
plt.savefig(figDir+'/power.eps', bbox_inches="tight")
plt.savefig(figDir+'/power.pdf', bbox_inches="tight")
plt.savefig(figDir+'/power.png', bbox_inches="tight")
plt.clf()
pa ,= plt.plot(rm, Xmm, 'k-o', ms=0.8*ms, mew=mew)
plt.fill_between(rm, abs(Xmm+SXmm), abs(Xmm-SXmm), color='k', alpha=0.2)
pb ,= plt.plot(rm, Xvm, 'm-D', ms=ms, mew=mew)
plt.plot(rm, -Xvm, 'mD', ms=ms, mew=mew)
plt.fill_between(rm, abs(Xvm+SXvm), abs(Xvm-SXvm), color='m', alpha=0.2)
pc ,= plt.plot(rm, Xvv, 'b-p', ms=1.3*ms, mew=mew)
plt.plot(rm, -Xvv, 'bp', ms=ms, mew=1.3*mew)
plt.fill_between(rm, abs(Xvv+SXvv), abs(Xvv-SXvv), color='b', alpha=0.2)
plt.xlabel(r'$r \;[h^{-1}\mathrm{Mpc}]$')
plt.ylabel(r'$\xi(r)$')
plt.title(r'Correlation functions')
plt.xscale('log')
plt.yscale('log')
plt.xlim(rmin,rmax)
plt.ylim(min(10**np.floor(np.log10(abs(Xvm).min())),10**np.floor(np.log10(abs(Xmm).min())))/margin, max(10**np.ceil(np.log10(Xmm.max())),10**np.ceil(np.log10(Xvv.max())))*margin)
plt.legend([pa, pb, pc],['tt', 'vt', 'vv'],'best',prop={'size':12})
plt.savefig(figDir+'/correlation.eps', bbox_inches="tight")
plt.savefig(figDir+'/correlation.pdf', bbox_inches="tight")
plt.savefig(figDir+'/correlation.png', bbox_inches="tight")
plt.clf()
return

View file

@ -0,0 +1,107 @@
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/vide/voidUtil/xcorlib.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
import numpy as np
# CIC interpolation
def cic(x, Lbox, Lboxcut = 0, Nmesh = 128, weights = None):
if weights == None: weights = 1
wm = np.mean(weights)
ws = np.mean(weights**2)
d = np.mod(x/(Lbox+2*Lboxcut)*Nmesh,1)
box = ([Lboxcut,Lbox+Lboxcut],[Lboxcut,Lbox+Lboxcut],[Lboxcut,Lbox+Lboxcut])
rho = np.histogramdd(x, range = box, bins = Nmesh, weights = weights*(1-d[:,0])*(1-d[:,1])*(1-d[:,2]))[0] \
+ np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*d[:,0]*(1-d[:,1])*(1-d[:,2]))[0],1,0) \
+ np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*(1-d[:,0])*d[:,1]*(1-d[:,2]))[0],1,1) \
+ np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*(1-d[:,0])*(1-d[:,1])*d[:,2])[0],1,2) \
+ np.roll(np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*d[:,0]*d[:,1]*(1-d[:,2]))[0],1,0),1,1) \
+ np.roll(np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*d[:,0]*(1-d[:,1])*d[:,2])[0],1,0),1,2) \
+ np.roll(np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*(1-d[:,0])*d[:,1]*d[:,2])[0],1,1),1,2) \
+ np.roll(np.roll(np.roll(np.histogramdd(x, range = box, bins = Nmesh, weights = weights*d[:,0]*d[:,1]*d[:,2])[0],1,0),1,1),1,2)
rho /= wm
rho = rho/rho.mean() - 1.
return (rho, wm, ws)
# Power spectra & correlation functions
def powcor(d1, d2, Lbox, Nbin = 10, scale = 'lin', cor = False, cic = True, dim = 1):
Nmesh = len(d1)
# CIC correction
if cic:
wid = np.indices(np.shape(d1))
wid[np.where(wid >= Nmesh/2)] -= Nmesh
wid = wid*np.pi/Nmesh + 1e-100
wcic = np.prod(np.sin(wid)/wid,0)**2
# Shell average power spectrum
dk = 2*np.pi/Lbox
Pk = np.conj(d1)*d2*(Lbox/Nmesh**2)**3
if cic: Pk /= wcic**2
(Nm, km, Pkm, SPkm) = shellavg(np.real(Pk), dk, Nmesh, Nbin = Nbin, xmin = 0., xmax = Nmesh*dk/2, scale = scale, dim = dim)
# Inverse Fourier transform and shell average correlation function
if cor:
if cic: Pk *= wcic**2 # Undo cic-correction in correlation function
dx = Lbox/Nmesh
Xr = np.fft.irfftn(Pk)*(Nmesh/Lbox)**3
(Nmx, rm, Xrm, SXrm) = shellavg(np.real(Xr), dx, Nmesh, Nbin = Nbin/2, xmin = dx, xmax = 140., scale = scale, dim = dim)
return ((Nm, km, Pkm, SPkm),(Nmx, rm, Xrm, SXrm))
else: return (Nm, km, Pkm, SPkm)
# Shell averaging
def shellavg(f, dx, Nmesh, Nbin = 10, xmin = 0., xmax = 1., scale = 'lin', dim = 1):
x = np.indices(np.shape(f))
x[np.where(x >= Nmesh/2)] -= Nmesh
f = f.flatten()
if scale == 'lin': bins = xmin+(xmax-xmin)* np.linspace(0,1,Nbin+1)
if scale == 'log': bins = xmin*(xmax/xmin)**np.linspace(0,1,Nbin+1)
if dim == 1: # 1D
x = dx*np.sqrt(np.sum(x**2,0)).flatten()
Nm = np.histogram(x, bins = bins)[0]
xm = np.histogram(x, bins = bins, weights = x)[0]/Nm
fm = np.histogram(x, bins = bins, weights = f)[0]/Nm
fs = np.sqrt((np.histogram(x, bins = bins, weights = f**2)[0]/Nm - fm**2)/(Nm-1))
return (Nm, xm, fm, fs)
elif dim == 2: # 2D
xper = dx*np.sqrt(x[0,:,:,:]**2 + x[1,:,:,:]**2 + 1e-100).flatten()
xpar = dx*np.abs(x[2,:,:,:]).flatten()
x = dx*np.sqrt(np.sum(x**2,0)).flatten()
Nm = np.histogram2d(xper, xpar, bins = [bins,bins])[0]
xmper = np.histogram2d(xper, xpar, bins = [bins,bins], weights = xper)[0]/Nm
xmpar = np.histogram2d(xper, xpar, bins = [bins,bins], weights = xpar)[0]/Nm
fm = np.histogram2d(xper, xpar, bins = [bins,bins], weights = f)[0]/Nm
return (Nm, xmper, xmpar, fm)

View file

View file

@ -0,0 +1,140 @@
#!/usr/bin/env python
#+
# VIDE -- Void IDentification and Examination -- ./python_tools/void_pipeline/__init__.py
# Copyright (C) 2010-2014 Guilhem Lavaux
# Copyright (C) 2011-2014 P. M. Sutter
#
# This program 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; version 2 of the License.
#
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#+
# Stage 1 : prepare particles for void finding
# Stage 2 : find voids
# Stage 3 : prune catalog
from vide.backend import *
import vide
import imp
import os
import pickle
# ------------------------------------------------------------------------------
if (len(sys.argv) == 1):
print("Usage: python3 -m void_pipeline parameter_file.py")
exit(-1)
if (len(sys.argv) > 1):
filename = sys.argv[1]
print(" Loading parameters from", filename)
if not os.access(filename, os.F_OK):
print(" Cannot find parameter file %s!" % filename)
exit(-1)
parms = imp.load_source("name", filename)
regenerateFlag = False
globals().update(vars(parms))
void_path = os.path.split(vide.__file__)[0]
ZOBOV_PATH=f'{void_path}/bin/'
CTOOLS_PATH=ZOBOV_PATH
print(f"ZOBOV_PATH is {ZOBOV_PATH}")
else:
print(" Using default parameters")
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
if not os.access(logDir, os.F_OK):
os.makedirs(logDir)
if not os.access(figDir, os.F_OK):
os.makedirs(figDir)
if not continueRun:
print(" Cleaning out log files...")
if startCatalogStage <= 1 and glob.glob(logDir+"/generate*") != []:
os.system("rm %s/generate*" % logDir)
if startCatalogStage <= 2 and glob.glob(logDir+"/zobov*") != []:
os.system("rm %s/zobov*" % logDir)
if startCatalogStage <= 3 and glob.glob(logDir+"/prune*") != []:
os.system("rm %s/prune*" % logDir)
for sample in dataSampleList:
sampleName = sample.fullName
print(" Working with data set", sampleName, "...")
zobovDir = workDir+"/sample_"+sampleName+"/"
sample.zobovDir = zobovDir
if not os.access(zobovDir, os.F_OK):
os.makedirs(zobovDir)
# ---------------------------------------------------------------------------
if (startCatalogStage <= 1) and (endCatalogStage >= 1) and not sample.isCombo:
print(" Extracting tracers from catalog...", end=' ')
sys.stdout.flush()
logFile = logDir+"/generate_"+sampleName+".out"
if sample.dataType == "observation":
GENERATE_PATH = CTOOLS_PATH+"/prepObservation"
else:
GENERATE_PATH = CTOOLS_PATH+"/prepSimulation"
launchPrep(sample, GENERATE_PATH, workDir=workDir,
inputDataDir=inputDataDir, zobovDir=zobovDir,
figDir=figDir, logFile=logFile, useComoving=sample.useComoving,
continueRun=continueRun, regenerate=regenerateFlag)
# --------------------------------------------------------------------------
if (startCatalogStage <= 2) and (endCatalogStage >= 2) and not sample.isCombo:
print(" Extracting voids with ZOBOV...", end=' ')
sys.stdout.flush()
launchZobov(sample, ZOBOV_PATH, zobovDir=zobovDir, logDir=logDir,
continueRun=continueRun, numZobovDivisions=numZobovDivisions,
numZobovThreads=numZobovThreads, mergingThreshold=mergingThreshold)
# -------------------------------------------------------------------------
if (startCatalogStage <= 3) and (endCatalogStage >= 3) and not sample.isCombo:
print(" Pruning void catalogs", "...", end=' ')
sys.stdout.flush()
logFile = logDir+"/pruneVoids_"+sampleName+".out"
PRUNE_PATH = CTOOLS_PATH+"/pruneVoids"
launchPrune(sample, PRUNE_PATH,
logFile=logFile, zobovDir=zobovDir,
useComoving=sample.useComoving, continueRun=continueRun, mergingThreshold=mergingThreshold)
# -------------------------------------------------------------------------
if (startCatalogStage <= 4) and (endCatalogStage >= 4):
print(" Plotting...", end=' ')
sys.stdout.flush()
#for thisDataPortion in dataPortions:
#plotRedshiftDistribution(workDir, dataSampleList, figDir, showPlot=False,
# dataPortion=thisDataPortion, setName=setName)
#plotSizeDistribution(workDir, dataSampleList, figDir, showPlot=False,
# dataPortion=thisDataPortion, setName=setName)
#plotNumberDistribution(workDir, dataSampleList, figDir, showPlot=False,
# dataPortion=thisDataPortion, setName=setName)
#plotVoidDistribution(workDir, dataSampleList, figDir, showPlot=False,
# dataPortion=thisDataPortion, setName=setName)
print("\n Done!")