vide_public/c_tools/analysis/voidOverlap.cpp

815 lines
30 KiB
C++

/*+
VIDE -- Void IDentification and Examination -- ./c_tools/analysis/voidOverlap.cpp
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.
+*/
// =============================================================================
//
// Program: voidOverlap
//
// Description: Takes two void catalogs and reports the "overlap" between
// them.
//
// ============================================================================
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include <stdio.h>
#include <math.h>
#include "voidOverlap_conf.h"
#include <vector>
#include <netcdfcpp.h>
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
typedef struct partStruct {
float x, y, z, volume;
float ra, dec, redshift;
long uniqueID;
} PART;
typedef struct zoneStruct {
int numPart;
int *partIDs;
} ZONE2PART;
typedef struct voidZoneStruct {
int numZones;
int *zoneIDs;
} VOID2ZONE;
typedef struct matchProps {
int matchID;
float commonVolOrig, commonVolProg;
float dist;
float merit;
} MATCHPROPS;
typedef struct voidStruct {
float vol, coreDens, zoneVol, densCon, voidProb, radius;
int voidID, numPart, numZones, coreParticle, zoneNumPart;
float maxRadius, nearestMock, centralDen, redshift, redshiftInMpc;
float nearestEdge;
float macrocenter[3];
float ellipticity;
float eigv1[3], eigv2[3], eigv3[3], eig[3];
std::vector<MATCHPROPS> matches;
int numMatches;
int numBigMatches;
float radiusMpc;
} VOID;
typedef struct catalog {
int numVoids, numPartTot, numZonesTot;
float boxLen[3];
std::vector<PART> part;
std::vector<ZONE2PART> zones2Parts;
std::vector<VOID2ZONE> void2Zones;
std::vector<VOID> voids;
} CATALOG;
void loadCatalog(const char *partFile, const char *volFile,
const char *voidFile, const char *zoneFile,
const char *infoFile, const char *centerFile,
const char *shapeFile,
const char *zonePartFile, CATALOG& catalog);
float getDist(CATALOG& catalog1, CATALOG& catalog2, int& iVoid1, int& iVoid2,
bool periodicX, bool periodicY, bool operiodicZ);
void sortMatches(std::vector<MATCHPROPS>& matches,
CATALOG& catalog2, int mode);
// ----------------------------------------------------------------------------
int main(int argc, char **argv) {
int p1, p2, iZ1, iZ2, iVoid1, iVoid2, iVoid, zoneID1, zoneID2, iMatch;
int partID1, partID2;
int voidID1, voidID2;
bool periodicX=false, periodicY=false, periodicZ=false, match;
float dist[3], rdist, r1, r2;
FILE *fp;
int closestMatchID;
float closestMatchDist;
float commonVolRatio;
MATCHPROPS newMatch;
int MAX_MATCHES = 300;
float matchDist = 0.25;
bool alreadyMatched;
int clock1, clock2;
CATALOG catalog1, catalog2;
// initialize arguments
voidOverlap_info args;
voidOverlap_conf_params params;
voidOverlap_conf_init(&args);
voidOverlap_conf_params_init(&params);
params.check_required = 0;
if (voidOverlap_conf_ext (argc, argv, &args, &params))
return 1;
if (!args.configFile_given) {
if (voidOverlap_conf_required (&args, VOIDOVERLAP_CONF_PACKAGE))
return 1;
} else {
params.check_required = 1;
params.initialize = 0;
if (voidOverlap_conf_config_file (args.configFile_arg, &args, &params))
return 1;
}
matchDist = args.overlapFrac_arg;
loadCatalog(args.partFile1_arg, args.volFile1_arg, args.voidFile1_arg,
args.zoneFile1_arg, args.infoFile1_arg, args.centerFile1_arg,
args.shapeFile1_arg,
args.zonePartFile1_arg, catalog1);
loadCatalog(args.partFile2_arg, args.volFile2_arg, args.voidFile2_arg,
args.zoneFile2_arg, args.infoFile2_arg, args.centerFile2_arg,
args.shapeFile2_arg,
args.zonePartFile2_arg, catalog2);
// check for periodic box
if ( strchr(args.periodic_arg, 'x') != NULL) {
periodicX = true;
printf("Will assume x-direction is periodic.\n");
}
if ( strchr(args.periodic_arg, 'y') != NULL) {
periodicY = true;
printf("Will assume y-direction is periodic.\n");
}
if ( strchr(args.periodic_arg, 'z') != NULL) {
periodicZ = true;
printf("Will assume z-direction is periodic.\n");
}
// find closest voids
printf(" Finding nearest matches...\n");
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
printf(" Matching for void %d of %d...", iVoid1, catalog1.numVoids);
fflush(stdout);
clock1 = clock();
for (iVoid2 = 0; iVoid2 < catalog2.numVoids; iVoid2++) {
rdist = getDist(catalog1, catalog2, iVoid1, iVoid2,
periodicX, periodicY, periodicZ);
newMatch.matchID = iVoid2;
newMatch.commonVolOrig = 0;
newMatch.commonVolProg = 0;
newMatch.dist = rdist;
//if (rdist > 1.5) continue;
if (rdist/catalog1.voids[iVoid1].radius > 1.5) continue;
// see if center is contained in void
match = false;
voidID1 = catalog1.voids[iVoid1].voidID;
for (iZ1 = 0; iZ1 < catalog1.void2Zones[voidID1].numZones; iZ1++) {
zoneID1 = catalog1.void2Zones[voidID1].zoneIDs[iZ1];
for (p1 = 0; p1 < catalog1.zones2Parts[zoneID1].numPart; p1++) {
partID1 = catalog1.zones2Parts[zoneID1].partIDs[p1];
dist[0] = fabs(catalog1.part[partID1].x -
catalog2.voids[iVoid2].macrocenter[0]);
dist[1] = fabs(catalog1.part[partID1].y -
catalog2.voids[iVoid2].macrocenter[1]);
dist[2] = fabs(catalog1.part[partID1].z -
catalog2.voids[iVoid2].macrocenter[2]);
if (periodicX) dist[0] = fmin(dist[0], 1.0 - dist[0]);
if (periodicY) dist[1] = fmin(dist[1], 1.0 - dist[1]);
if (periodicZ) dist[2] = fmin(dist[2], 1.0 - dist[2]);
rdist = sqrt(dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2]);
r1 = pow(3./4./M_PI*catalog1.part[partID1].volume /
catalog1.numPartTot, 1./3.);
if (rdist <= matchDist*8*r1) {
match = true;
break;
}
}
}
if (!match) continue;
//if (rdist/catalog1.voids[iVoid1].radius > 1.) continue;
//if (catalog1.voids[iVoid1].matches.size() < MAX_MATCHES) {
catalog1.voids[iVoid1].matches.push_back(newMatch);
//} else {
// // find the farthest match
// float farthestMatchDist = 0;
// int farthestMatchID = 0;
// for (iMatch = 0; iMatch < MAX_MATCHES; iMatch++) {
// if (catalog1.voids[iVoid1].matches[iMatch].dist > farthestMatchDist){
// farthestMatchDist = catalog1.voids[iVoid1].matches[iMatch].dist;
// farthestMatchID = iMatch;
// }
// }
// if (rdist < farthestMatchDist)
// catalog1.voids[iVoid1].matches[farthestMatchID] = newMatch;
//}
}
clock2 = clock();
printf("Time: %f sec\n", (1.*clock2-clock1)/CLOCKS_PER_SEC);
clock1 = clock();
}
// pick the closest matches to speed up computation
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
int numPotential = catalog1.voids[iVoid1].matches.size();
catalog1.voids[iVoid1].numMatches = numPotential;
if (numPotential > MAX_MATCHES) {
sortMatches(catalog1.voids[iVoid1].matches, catalog2, 1);
catalog1.voids[iVoid1].matches.resize(MAX_MATCHES);
}
}
printf(" Determining overlap...\n");
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
printf(" Working on void %d of %d...", iVoid1+1, catalog1.numVoids);
fflush(stdout);
clock1 = clock();
voidID1 = catalog1.voids[iVoid1].voidID;
for (iMatch = 0; iMatch < catalog1.voids[iVoid1].matches.size();iMatch++) {
iVoid2 = catalog1.voids[iVoid1].matches[iMatch].matchID;
voidID2 = catalog2.voids[iVoid2].voidID;
for (iZ1 = 0; iZ1 < catalog1.void2Zones[voidID1].numZones; iZ1++) {
zoneID1 = catalog1.void2Zones[voidID1].zoneIDs[iZ1];
for (p1 = 0; p1 < catalog1.zones2Parts[zoneID1].numPart; p1++) {
partID1 = catalog1.zones2Parts[zoneID1].partIDs[p1];
alreadyMatched = false;
for (iZ2 = 0; iZ2 < catalog2.void2Zones[voidID2].numZones; iZ2++) {
zoneID2 = catalog2.void2Zones[voidID2].zoneIDs[iZ2];
for (p2 = 0; p2 < catalog2.zones2Parts[zoneID2].numPart; p2++) {
partID2 = catalog2.zones2Parts[zoneID2].partIDs[p2];
match = false;
if (args.useID_flag) {
if (catalog1.part[partID1].uniqueID ==
catalog2.part[partID2].uniqueID) match = true;
} else {
dist[0] = fabs(catalog1.part[partID1].x -
catalog2.part[partID2].x);
dist[1] = fabs(catalog1.part[partID1].y -
catalog2.part[partID2].y);
dist[2] = fabs(catalog1.part[partID1].z -
catalog2.part[partID2].z);
if (periodicX) dist[0] = fmin(dist[0], 1.0 - dist[0]);
if (periodicY) dist[1] = fmin(dist[1], 1.0 - dist[1]);
if (periodicZ) dist[2] = fmin(dist[2], 1.0 - dist[2]);
rdist = sqrt(dist[0]*dist[0] + dist[1]*dist[1] +
dist[2]*dist[2]);
r1 = pow(3./4./M_PI*catalog1.part[partID1].volume /
catalog1.numPartTot, 1./3.);
r2 = pow(3./4./M_PI*catalog2.part[partID2].volume /
catalog2.numPartTot, 1./3.);
if (rdist <= matchDist*(r1+r2)) match = true;
}
if (match) {
if (!alreadyMatched) {
catalog1.voids[iVoid1].matches[iMatch].commonVolOrig +=
catalog1.part[partID1].volume;
}
catalog1.voids[iVoid1].matches[iMatch].commonVolProg +=
catalog2.part[partID2].volume;
alreadyMatched = true;
} // end if match
} // end p2
} // end iZ2
} // end p1
} // end iZ1
} // end iVoid2
for (iMatch = 0; iMatch < catalog1.voids[iVoid1].matches.size(); iMatch++) {
int matchID = catalog1.voids[iVoid1].matches[iMatch].matchID;
catalog1.voids[iVoid1].matches[iMatch].merit =
catalog1.voids[iVoid1].matches[iMatch].commonVolOrig *
catalog1.voids[iVoid1].matches[iMatch].commonVolOrig /
catalog1.voids[iVoid1].vol /
catalog2.voids[iVoid2].vol;
//catalog1.voids[iVoid1].matches[iMatch].commonVolOrig *
//catalog1.voids[iVoid1].matches[iMatch].commonVolProg /
//catalog1.voids[iVoid1].vol /
//catalog2.voids[matchID].vol;
//pow(catalog1.voids[iVoid1].matches[iMatch].commonVol,2) /
//catalog1.voids[iVoid1].vol /
//catalog2.voids[matchID].vol;
}
// sortMatches(catalog1.voids[iVoid1].matches, catalog2);
clock2 = clock();
printf("Time: %f sec\n", (1.*clock2-clock1)/CLOCKS_PER_SEC);
clock1 = clock();
//printf("BEST VOL %e\n", catalog2.voids[catalog1.voids[iVoid1].matches[0].matchID].vol/catalog1.voids[iVoid1].vol);
} // end match finding
printf(" Sorting matches...\n");
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
sortMatches(catalog1.voids[iVoid1].matches, catalog2, 0);
if (catalog1.voids[iVoid1].matches.size() > 0 &&
catalog1.voids[iVoid1].matches[0].merit < 1.e-6)
sortMatches(catalog1.voids[iVoid1].matches, catalog2, 1);
}
// count up significant matches
printf(" Categorizing matches...\n");
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
closestMatchDist = 0.;
for (iMatch = 0; iMatch < catalog1.voids[iVoid1].matches.size(); iMatch++) {
commonVolRatio = catalog1.voids[iVoid1].matches[iMatch].commonVolOrig /
// catalog1.voids[iVoid1].numPart;
catalog1.voids[iVoid1].vol;
if (commonVolRatio > 0.2) catalog1.voids[iVoid1].numBigMatches++;
}
}
// output summary
printf(" Output...\n");
std::string filename;
filename = string(args.outfile_arg);
filename = filename.append("summary.out");
fp = fopen(filename.c_str(), "w");
fprintf(fp, "# void ID, radius, radius ratio, common volume ratio (to original), common volume ratio (to match), relative dist, num matches, num significant matches, match ID, merit, ellipticity ratio, density contrast, cosTheta, major axis ratio, minor axis ratio, ellipticity\n");
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
int voidID = catalog1.voids[iVoid1].voidID;
if (catalog1.voids[iVoid1].numMatches > 0) {
iVoid2 = catalog1.voids[iVoid1].matches[0].matchID;
float rRatio = catalog2.voids[iVoid2].radius /
catalog1.voids[iVoid1].radius;
float ellipRatio = catalog2.voids[iVoid2].ellipticity /
catalog1.voids[iVoid1].ellipticity;
// find angles between major axes, etc.
int iMaj1, iMed1, iMin1;
int iMaj2, iMed2, iMin2;
float eig1[3], eig2[3];
float eigv1[6], eigv2[6];
float cosThetaMaj, cosThetaMed, cosThetaMin;
for (int i = 0; i < 3; i++) {
eig1[i] = catalog1.voids[iVoid1].eig[i];
eigv1[0,i] = catalog1.voids[iVoid1].eigv1[i];
eigv1[1,i] = catalog1.voids[iVoid1].eigv2[i];
eigv1[2,i] = catalog1.voids[iVoid1].eigv3[i];
eig2[i] = catalog2.voids[iVoid2].eig[i];
eigv2[0,i] = catalog2.voids[iVoid2].eigv1[i];
eigv2[1,i] = catalog2.voids[iVoid2].eigv2[i];
eigv2[2,i] = catalog2.voids[iVoid2].eigv3[i];
}
if (eig1[0] > eig1[1] && eig1[0] > eig1[2]) iMaj1 = 0;
if (eig1[1] > eig1[2] && eig1[1] > eig1[0]) iMaj1 = 1;
if (eig1[2] > eig1[1] && eig1[2] > eig1[0]) iMaj1 = 2;
if (eig1[0] > eig1[1] && eig1[0] < eig1[2]) iMed1 = 0;
if (eig1[1] > eig1[2] && eig1[1] < eig1[0]) iMed1 = 1;
if (eig1[2] > eig1[1] && eig1[2] < eig1[0]) iMed1 = 2;
if (eig1[0] < eig1[1] && eig1[0] < eig1[2]) iMin1 = 0;
if (eig1[1] < eig1[2] && eig1[1] < eig1[0]) iMin1 = 1;
if (eig1[2] < eig1[1] && eig1[2] < eig1[0]) iMin1 = 2;
if (eig2[0] > eig2[1] && eig2[0] > eig2[2]) iMaj2 = 0;
if (eig2[1] > eig2[2] && eig2[1] > eig2[0]) iMaj2 = 1;
if (eig2[2] > eig2[1] && eig2[2] > eig2[0]) iMaj2 = 2;
if (eig2[0] > eig2[1] && eig2[0] < eig2[2]) iMed2 = 0;
if (eig2[1] > eig2[2] && eig2[1] < eig2[0]) iMed2 = 1;
if (eig2[2] > eig2[1] && eig2[2] < eig2[0]) iMed2 = 2;
if (eig2[0] < eig2[1] && eig2[0] < eig2[2]) iMin2 = 0;
if (eig2[1] < eig2[2] && eig2[1] < eig2[0]) iMin2 = 1;
if (eig2[2] < eig2[1] && eig2[2] < eig2[0]) iMin2 = 2;
//printf("EIG CHECK %d %d %e %e %e %d %e %e %e %d\n", iVoid1, iVoid2, eig1[0], eig1[1], eig1[2], iMin1, eig2[0], eig2[1], eig2[2], iMin2);
cosThetaMaj = (eigv1[iMaj1,0]*eigv2[iMaj2,0] +
eigv1[iMaj1,1]*eigv2[iMaj2,1] +
eigv1[iMaj1,2]*eigv2[iMaj2,2]);
//printf("EIG CHECK %d %d %e %e %e %e %e %e %e\n", iVoid1, iVoid2, eigv1[iMaj1,0], eigv1[iMaj1,1], eigv1[iMaj1,2], eigv2[iMaj2,0], eigv2[iMaj2,1], eigv2[iMaj2,2], cosThetaMaj);
if (fabs(cosThetaMaj) > 0.) cosThetaMaj = acos(fabs(cosThetaMaj));
float majAxisRatio = eig2[iMaj2]/eig1[iMaj1];
float minAxisRatio = eig2[iMin2]/eig1[iMin1];
// TEST
/*
if (catalog1.voids[iVoid1].voidID == 267 &&
catalog2.voids[iVoid2].voidID == 346) {
int voidID1 = catalog1.voids[iVoid1].voidID;
for (iZ1 = 0; iZ1 < catalog1.void2Zones[voidID1].numZones; iZ1++) {
zoneID1 = catalog1.void2Zones[voidID1].zoneIDs[iZ1];
for (p1 = 0; p1 < catalog1.zones2Parts[zoneID1].numPart; p1++) {
partID1 = catalog1.zones2Parts[zoneID1].partIDs[p1];
printf("VOID1 %e %e %e\n", catalog1.part[partID1].x,
catalog1.part[partID1].y,
catalog1.part[partID1].z);
}
}
int voidID2 = catalog2.voids[iVoid2].voidID;
for (iZ2 = 0; iZ2 < catalog2.void2Zones[voidID2].numZones; iZ2++) {
zoneID2 = catalog2.void2Zones[voidID2].zoneIDs[iZ2];
for (p2 = 0; p2 < catalog2.zones2Parts[zoneID2].numPart; p2++) {
partID2 = catalog2.zones2Parts[zoneID2].partIDs[p2];
printf("VOID1 %e %e %e\n", catalog2.part[partID2].x,
catalog2.part[partID2].y,
catalog2.part[partID2].z);
}
}
}
*/
// END TEST
commonVolRatio = catalog1.voids[iVoid1].matches[0].commonVolOrig /
//catalog1.voids[iVoid1].numPart;
catalog1.voids[iVoid1].vol;
float volRatio = catalog1.voids[iVoid1].matches[0].commonVolProg /
catalog2.voids[iVoid2].vol;
rdist = catalog1.voids[iVoid1].matches[0].dist;
rdist /= catalog1.voids[iVoid1].radius;
fprintf(fp, "%d %.4f %.4f %e %e %.4f %d %d %d %e %e %e %e %e %e %e\n", voidID,
//fprintf(fp, "%d %.4f %.4f %.4f %.4f %.4f %d %d %d\n", voidID,
catalog1.voids[iVoid1].radiusMpc,
rRatio,
commonVolRatio,
volRatio,
rdist,
catalog1.voids[iVoid1].numMatches,
catalog1.voids[iVoid1].numBigMatches,
catalog2.voids[iVoid2].voidID,
catalog1.voids[iVoid1].matches[0].merit,
ellipRatio,
catalog1.voids[iVoid1].densCon,
cosThetaMaj,
majAxisRatio,
minAxisRatio,
catalog1.voids[iVoid1].ellipticity
);
} else {
fprintf(fp, "%d %.4f 0.0 0.0 0.0 0.0 0.0 0 0 0 0.0 0.0 0.0 0.0 0.0 %e\n", voidID,
catalog1.voids[iVoid1].radiusMpc, catalog1.voids[iVoid1].ellipticity);
}
} // end printing
fclose(fp);
// output detail
printf(" Output detail...\n");
filename = string(args.outfile_arg);
filename = filename.append("detail.out");
fp = fopen(filename.c_str(), "w");
fprintf(fp, "# match ID, merit, relative dist, relative radius\n");
for (iVoid1 = 0; iVoid1 < catalog1.numVoids; iVoid1++) {
int voidID = catalog1.voids[iVoid1].voidID;
fprintf(fp,"#%d (%.4f Mpc/h):\n", voidID, catalog1.voids[iVoid1].radiusMpc);
for (iMatch = 0; iMatch < catalog1.voids[iVoid1].matches.size(); iMatch++) {
commonVolRatio = catalog1.voids[iVoid1].matches[iMatch].commonVolOrig /
//catalog1.voids[iVoid1].numPart;
catalog1.voids[iVoid1].vol;
int matchID = catalog1.voids[iVoid1].matches[iMatch].matchID;
fprintf(fp, "%d %e %.4f %.4f\n", matchID,
catalog1.voids[iVoid1].matches[iMatch].merit,
catalog1.voids[iVoid1].matches[iMatch].dist/
catalog1.voids[iVoid1].radius,
catalog2.voids[matchID].radius/
catalog1.voids[iVoid1].radius);
}
fprintf(fp, "\n ");
fprintf(fp, "\n ");
} // end printing detail
fclose(fp);
printf("\nDone!\n");
return 0;
} // end main
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void loadCatalog(const char *partFile, const char *volFile,
const char *voidFile, const char *zoneFile,
const char *infoFile, const char *centerFile,
const char *shapeFile,
const char *zonePartFile, CATALOG& catalog) {
int i, p, numPartTot, numZonesTot, dummy, iVoid, iZ, numVolTot;
FILE *fp;
float *temp, junk, voidVol, coreParticle, coreDens, zoneVol, zoneNumPart;
float densCon, voidProb, volNorm;
long *temp2;
int junkInt, voidID, numPart, numZones, zoneID, partID;
char line[500], junkStr[10];
float ranges[3][2];
printf("Loading info...\n");
NcFile f_info(infoFile);
ranges[0][0] = f_info.get_att("range_x_min")->as_double(0);
ranges[0][1] = f_info.get_att("range_x_max")->as_double(0);
ranges[1][0] = f_info.get_att("range_y_min")->as_double(0);
ranges[1][1] = f_info.get_att("range_y_max")->as_double(0);
ranges[2][0] = f_info.get_att("range_z_min")->as_double(0);
ranges[2][1] = f_info.get_att("range_z_max")->as_double(0);
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];
f_info.close();
// read in all particle positions
printf("Loading particles...\n");
fp = fopen(partFile, "r");
fread(&dummy, 1, 4, fp);
fread(&numPartTot, 1, 4, fp);
fread(&dummy, 1, 4, fp);
catalog.part.resize(numPartTot);
catalog.numPartTot = numPartTot;
volNorm = numPartTot/(catalog.boxLen[0]*catalog.boxLen[1]*catalog.boxLen[2]);
temp = (float *) malloc(numPartTot * sizeof(float));
temp2 = (long *) malloc(numPartTot * sizeof(long));
fread(&dummy, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].x = temp[p];
fread(&dummy, 1, 4, fp);
fread(&dummy, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].y = temp[p];
fread(&dummy, 1, 4, fp);
fread(&dummy, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].z = temp[p];
fread(&dummy, 1, 4, fp);
fread(&dummy, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].ra = temp[p];
fread(&dummy, 1, 4, fp);
fread(&dummy, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].dec = temp[p];
fread(&dummy, 1, 4, fp);
fread(&dummy, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].redshift = temp[p];
fread(&dummy, 1, 4, fp);
fread(&dummy, 1, 4, fp);
fread(temp2, numPartTot, 8, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].uniqueID = temp2[p];
free(temp2);
fclose(fp);
printf(" Read %d particles...\n", catalog.numPartTot);
// read in all particle volumes
printf(" Loading volumes...\n");
fp = fopen(volFile, "r");
fread(&numVolTot, 1, 4, fp);
fread(temp, numPartTot, 4, fp);
for (p = 0; p < numPartTot; p++)
catalog.part[p].volume = temp[p];
fclose(fp);
free(temp);
// read in desired voids
printf(" Loading voids...\n");
fp = fopen(voidFile ,"r");
fgets(line, sizeof(line), fp);
sscanf(line, "%d %s %d %s", &junkInt, junkStr, &catalog.numVoids, junkStr);
fgets(line, sizeof(line), fp);
catalog.voids.resize(catalog.numVoids);
i = 0;
while (fgets(line, sizeof(line), fp) != NULL) {
sscanf(line, "%d %d %d %f %f %d %d %f %d %f %f\n", &iVoid, &voidID,
&coreParticle, &coreDens, &zoneVol, &zoneNumPart, &numZones,
&voidVol, &numPart, &densCon, &voidProb);
catalog.voids[i].coreParticle = coreParticle;
catalog.voids[i].zoneNumPart = zoneNumPart;
catalog.voids[i].coreDens = coreDens;
catalog.voids[i].zoneVol = zoneVol;
catalog.voids[i].voidID = voidID;
catalog.voids[i].vol = voidVol;
catalog.voids[i].numPart = numPart;
catalog.voids[i].numZones = numZones;
catalog.voids[i].densCon = densCon;
catalog.voids[i].voidProb = voidProb;
catalog.voids[i].radius = pow(voidVol/catalog.numPartTot*3./4./M_PI, 1./3.);
catalog.voids[i].numMatches = 0;
catalog.voids[i].numBigMatches = 0;
catalog.voids[i].radiusMpc = pow(voidVol/volNorm*3./4./M_PI, 1./3.);
i++;
}
fclose(fp);
catalog.numVoids = i - 1;
catalog.voids.resize(catalog.numVoids);
printf(" Read %d voids.\n", catalog.numVoids);
printf(" Loading macrocenters\n");
fp = fopen(centerFile, "r");
float tempBary[3];
float tempFloat;
int tempInt;
iVoid = 0;
//fgets(line, sizeof(line), fp);
while (fgets(line, sizeof(line), fp) != NULL) {
sscanf(line, "%d %f %f %f\n",
&tempInt, &tempBary[0], &tempBary[1], &tempBary[2]);
//sscanf(line, "%f %f %f %f %f %f %f %d %f %d %d %d %d\n",
// &tempBary[0], &tempBary[1], &tempBary[2],
// &tempFloat, &tempFloat, &tempFloat, &tempFloat, &tempInt,
// &tempFloat, &tempInt, &tempInt, &tempInt, &tempInt);
//if (iVoid < 10) printf("BARY %d %d %e %e %e\n", iVoid, catalog.voids[iVoid].voidID, tempBary[0], tempBary[1], tempBary[2]);
tempBary[0] = (tempBary[0] - ranges[0][0])/catalog.boxLen[0];
tempBary[1] = (tempBary[1] - ranges[1][0])/catalog.boxLen[1];
tempBary[2] = (tempBary[2] - ranges[2][0])/catalog.boxLen[2];
catalog.voids[iVoid].macrocenter[0] = tempBary[0];
catalog.voids[iVoid].macrocenter[1] = tempBary[1];
catalog.voids[iVoid].macrocenter[2] = tempBary[2];
iVoid++;
}
fclose(fp);
printf(" Loading shapes\n");
fp = fopen(shapeFile, "r");
iVoid = 0;
float tempEllip, eig[3], eigv1[3], eigv2[3], eigv3[3];
fgets(line, sizeof(line), fp);
while (fgets(line, sizeof(line), fp) != NULL) {
sscanf(line, "%d %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
&tempInt, &tempEllip, &eig[0], &eig[1], &eig[2],
&eigv1[0], &eigv1[1], &eigv1[2],
&eigv2[0], &eigv2[1], &eigv2[2],
&eigv3[0], &eigv3[1], &eigv3[2]);
//if (iVoid < 10) printf("SHAPE %d %d %e\n", iVoid, catalog.voids[iVoid].voidID, tempEllip);
catalog.voids[iVoid].ellipticity = tempEllip;
catalog.voids[iVoid].eig[0] = eig[0];
catalog.voids[iVoid].eig[1] = eig[1];
catalog.voids[iVoid].eig[2] = eig[2];
catalog.voids[iVoid].eigv1[0] = eigv1[0];
catalog.voids[iVoid].eigv1[1] = eigv1[1];
catalog.voids[iVoid].eigv1[2] = eigv1[2];
catalog.voids[iVoid].eigv2[0] = eigv2[0];
catalog.voids[iVoid].eigv2[1] = eigv2[1];
catalog.voids[iVoid].eigv2[2] = eigv2[2];
catalog.voids[iVoid].eigv3[0] = eigv3[0];
catalog.voids[iVoid].eigv3[1] = eigv3[1];
catalog.voids[iVoid].eigv3[2] = eigv3[2];
iVoid++;
}
fclose(fp);
// load up the zone membership for each void
printf(" Loading zone-void membership info...\n");
fp = fopen(zoneFile, "r");
fread(&catalog.numZonesTot, 1, 4, fp);
catalog.void2Zones.resize(catalog.numZonesTot);
for (iZ = 0; iZ < catalog.numZonesTot; iZ++) {
fread(&numZones, 1, 4, fp);
catalog.void2Zones[iZ].numZones = numZones;
catalog.void2Zones[iZ].zoneIDs = (int *) malloc(numZones * sizeof(int));
for (p = 0; p < numZones; p++) {
fread(&catalog.void2Zones[iZ].zoneIDs[p], 1, 4, fp);
}
}
fclose(fp);
// now the zone membership
printf(" Loading particle-zone membership info...\n");
fp = fopen(zonePartFile, "r");
fread(&dummy, 1, 4, fp);
fread(&numZonesTot, 1, 4, fp);
catalog.zones2Parts.resize(numZonesTot);
for (iZ = 0; iZ < numZonesTot; iZ++) {
fread(&numPart, 1, 4, fp);
catalog.zones2Parts[iZ].numPart = numPart;
catalog.zones2Parts[iZ].partIDs = (int *) malloc(numPart * sizeof(int));
for (p = 0; p < numPart; p++) {
fread(&catalog.zones2Parts[iZ].partIDs[p], 1, 4, fp);
}
}
fclose(fp);
} // end loadCatalog
// ----------------------------------------------------------------------------
float getDist(CATALOG& catalog1, CATALOG& catalog2, int& iVoid1, int& iVoid2,
bool periodicX, bool periodicY, bool periodicZ) {
float rdist, dist[3];
dist[0] = fabs(catalog1.voids[iVoid1].macrocenter[0] -
catalog2.voids[iVoid2].macrocenter[0]);
dist[1] = fabs(catalog1.voids[iVoid1].macrocenter[1] -
catalog2.voids[iVoid2].macrocenter[1]);
dist[2] = fabs(catalog1.voids[iVoid1].macrocenter[2] -
catalog2.voids[iVoid2].macrocenter[2]);
if (periodicX) dist[0] = fmin(dist[0], 1.0 - dist[0]);
if (periodicY) dist[1] = fmin(dist[1], 1.0 - dist[1]);
if (periodicZ) dist[2] = fmin(dist[2], 1.0 - dist[2]);
rdist = sqrt(dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2]);
return rdist;
} // end getDist
// ----------------------------------------------------------------------------
void sortMatches(std::vector<MATCHPROPS>& matches,
CATALOG& catalog2, int mode) {
//printf("SORTING %d\n", matches.size());
MATCHPROPS tempMatch;
bool swapped;
int matchID, matchID2;
if (matches.size() <= 1) return;
swapped = true;
while (swapped) {
swapped = false;
for (int iMatch = 0; iMatch < matches.size() - 1; iMatch++) {
matchID = matches[iMatch].matchID;
matchID2 = matches[iMatch+1].matchID;
if ((mode == 0 && matches[iMatch].merit < matches[iMatch+1].merit) ||
(mode == 1 && matches[iMatch].dist > matches[iMatch+1].dist)) {
tempMatch = matches[iMatch+1];
matches[iMatch+1] = matches[iMatch];
matches[iMatch] = tempMatch;
swapped = true;
}
}
}
return;
} // end sortMatches