dumpframe.C
/*
* Image dumping routines for movies from PKDGRAV
* Original author: James Wadsley, 2002
* This alternative dumpframe was created to:
* 1) allow coloring by all particle properties
* 2) change brightness scaling to be be a number that
* a| increases with brightness
* b| is in the range 0-1
*
* To allow access to more properties, I removed a lot of the
* portability features, so that now I pass GravityParticle's
* into the dfRender_____ functions.
*
* The brightness scaling now relies on the dMinGasMass.
*/
#include <stdio.h>
#include "dumpframe.h"
#include "ParallelGravity.h"
#include "DataManager.h"
#include <assert.h>
#include <libgen.h>
#include <errno.h>
#include "config.h"
#ifdef HAVE_VALUES_H
#include <values.h>
#else
#include <float.h>
#endif
/* #define DEBUGTRACK 10 */
#ifdef DEBUGTRACK
int trackp = 0;
int trackcnt = 0;
int ntrack = 0, ntrack2 = 0;
#endif
#ifndef DBL_MAX
#define DBL_MAX 1.7976931348623157E+308
#endif
void dfInitialize( struct DumpFrameContext **pdf, double dYearUnit, double dTime,
double dDumpFrameTime, double dStep, double dDumpFrameStep,
double dDelta, int iMaxRung, int bVDetails, char* filename,
int bPeriodic, Vector3D<double> vPeriod) {
double tock=0.0;/*initialized to suppress warning: DCR 12/19/02*/
struct DumpFrameContext *df;
if (*pdf!=NULL) (*pdf)->fs = NULL;
if (dDumpFrameTime <= 0 && dDumpFrameStep <=0) return;
if (*pdf == NULL) {
*pdf = (struct DumpFrameContext *) malloc(sizeof(struct DumpFrameContext ));
(*pdf)->bAllocated = 1;
}
else {
(*pdf)->bAllocated = 0;
}
df = *pdf;
df->iMaxRung = 0;
df->dYearUnit = dYearUnit;
df->dTime = 0;
df->dDumpFrameTime = 0;
if (dDumpFrameTime > 0) {
df->dDumpFrameTime = dDumpFrameTime;
df->dTime = dTime-dDumpFrameTime*1e-10;
/* Round to a nearby power of two */
tock = -log((dDumpFrameTime-floor(dDumpFrameTime))/dDelta*0.50001+1e-60)
/log(2.0);
if (tock <= iMaxRung) {
df->iMaxRung = tock;
}
}
df->dStep = 0;
df->dDumpFrameStep = 0;
if (dDumpFrameStep > 0) {
df->dDumpFrameStep = dDumpFrameStep;
df->dStep = dStep-dDumpFrameStep*1e-10;
/* Round to a nearby power of two */
tock = -log((dDumpFrameStep-floor(dDumpFrameStep))*0.50001+1e-60)
/log(2.0);
if (tock <= iMaxRung && tock >df->iMaxRung) {
df->iMaxRung = floor(tock);
}
}
/* General options */
df->bVDetails = bVDetails;
dfParseOptions( *pdf, filename );
/* Parse time dependent camera options (mostly 2D) */
dfParseCameraDirections( *pdf, filename );
for(int i = 0; i < df->nFrameSetup; i++) {
df->fs[i].bPeriodic = bPeriodic;
df->fs[i].fPeriod[0] = vPeriod.x;
df->fs[i].fPeriod[1] = vPeriod.y;
df->fs[i].fPeriod[2] = vPeriod.z;
}
if (df->bVDetails) CkPrintf("DF Initialized Frame dumping: Time Interval %g [%g] (Step %i) Step Interval %g -> MaxRung %i\n",dDumpFrameTime,floor(dDumpFrameTime)+dDelta*pow(2.0,-floor(tock)),(int) floor(dDumpFrameTime/dDelta),dDumpFrameStep,df->iMaxRung);
}
void dfFinalize( struct DumpFrameContext *df ) {
if (df != NULL) {
if (df->fs != NULL) free( df->fs );
if (df->bAllocated) free( df );
}
}
void *dfAllocateImage( int nxPix, int nyPix ) {
DFIMAGE *Image;
Image = (DFIMAGE *) malloc( nxPix*nyPix*sizeof(DFIMAGE) );
CkAssert (Image != NULL );
return Image;
}
void dfFreeImage( void *Image ) {
free( Image );
}
#define SET( a, b ) { \
a[0]=b[0]; \
a[1]=b[1]; \
a[2]=b[2]; \
}
#define ADD( a, b ) { \
a[0]+=b[0]; \
a[1]+=b[1]; \
a[2]+=b[2]; \
}
#define DIFF( a, b, c ) { \
c[0] = b[0]-a[0]; \
c[1] = b[1]-a[1]; \
c[2] = b[2]-a[2]; \
}
#define DOT( a, b ) ( a[0]*b[0] + a[1]*b[1] + a[2]*b[2] )
#define DIST( a, b ) sqrt( (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])+(a[2]-b[2])*(a[2]-b[2]) )
#define LEN( a ) sqrt( (a[0])*(a[0])+(a[1])*(a[1])+(a[2])*(a[2]) )
#define NORM( a ) { \
double ilen; \
ilen = 1./LEN ( a ); \
a[0] *= ilen; a[1] *= ilen; a[2] *= ilen; \
}
#define SIZEVEC( a, f ) { \
double ilen; \
ilen = f/LEN ( a ); \
a[0] *= ilen; a[1] *= ilen; a[2] *= ilen; \
}
#define CURL( a, b, c ) { \
c[0] = a[1]*b[2] - a[2]*b[1]; \
c[1] = a[2]*b[0] - a[0]*b[2]; \
c[2] = a[0]*b[1] - a[1]*b[0]; \
}
std::string VecFilename(int iType) {
switch (iType) {
case OUT_TEMP_ARRAY: return "temperature";
case OUT_DENSITY_ARRAY:
return "density";
case OUT_UDOT_ARRAY:
return "uDot";
case OUT_U_ARRAY:
return "u";
case OUT_METALS_ARRAY:
return "metals";
case OUT_TIMEFORM_ARRAY:
return "TimeForm";
case OUT_GROUP_ARRAY:
return "groupid";
case OUT_AGE_ARRAY:
return "age";
default: CkAbort("Unknown type to render");
}
}
double VecType(int iType, GravityParticle *p, DataManager *dm, double duTFac,
double dTime){
switch (iType) {
#ifndef COOLING_NONE
case OUT_TEMP_ARRAY:
#ifdef COOLING_GRACKLE
return CoolCodeEnergyToTemperature(dm->Cool, &p->CoolParticle(),
p->u(),p->fDensity, p->fMetals());
#else
return CoolCodeEnergyToTemperature(dm->Cool, &p->CoolParticle(),
p->u(),p->fMetals());
#endif
#else
case OUT_TEMP_ARRAY: return duTFac*p->u();
#endif
case OUT_DENSITY_ARRAY: return p->fDensity;
#ifndef COOLING_NONE
case OUT_UDOT_ARRAY: return p->uDot();
#endif
case OUT_U_ARRAY: return p->u();
case OUT_METALS_ARRAY:
if(p->isGas()) return p->fMetals();
else return p->fStarMetals();
case OUT_TIMEFORM_ARRAY: return p->fTimeForm();
case OUT_GROUP_ARRAY: return (double) p->iOrder;
case OUT_AGE_ARRAY: return dTime - p->fTimeForm();
default: return(0.0);
}
}
void dfProjection( struct inDumpFrame *in, struct dfFrameSetup *fs, int nxPix, int nyPix ) {
double width,height;
double vec[3];
int j;
in->r[0] = fs->target[0];
in->r[1] = fs->target[1];
in->r[2] = fs->target[2];
if (nxPix > 0 && nyPix >0) {
in->nxPix = nxPix;
in->nyPix = nyPix;
}
else{
in->nxPix = fs->nxPix;
in->nyPix = fs->nyPix;
}
in->bExpansion = fs->bExpansion;
in->bPeriodic = fs->bPeriodic;
in->fPeriod[0] = fs->fPeriod[0];
in->fPeriod[1] = fs->fPeriod[1];
in->fPeriod[2] = fs->fPeriod[2];
in->iProject = fs->iProject;
in->pScale1 = fs->pScale1;
in->pScale2 = fs->pScale2;
in->dfGasCT.iProperty = fs->dfGasCT.iProperty;
in->dfGasCT.fPropMin = fs->dfGasCT.fPropMin;
in->dfGasCT.fPropMax = fs->dfGasCT.fPropMax;
in->dfGasCT.nColors = fs->dfGasCT.nColors;
for (j=0;j<fs->dfGasCT.nColors;j++) {
in->dfGasCT.dfColors[j] = fs->dfGasCT.dfColors[j];
}
in->dfDarkCT.iProperty = fs->dfDarkCT.iProperty;
in->dfDarkCT.fPropMin = fs->dfDarkCT.fPropMin;
in->dfDarkCT.fPropMax = fs->dfDarkCT.fPropMax;
in->dfDarkCT.nColors = fs->dfDarkCT.nColors;
for (j=0;j<fs->dfDarkCT.nColors;j++) {
in->dfDarkCT.dfColors[j] = fs->dfDarkCT.dfColors[j];
}
in->dfStarCT.iProperty = fs->dfStarCT.iProperty;
in->dfStarCT.fPropMin = fs->dfStarCT.fPropMin;
in->dfStarCT.fPropMax = fs->dfStarCT.fPropMax;
in->dfStarCT.nColors = fs->dfStarCT.nColors;
for (j=0;j<fs->dfStarCT.nColors;j++) {
in->dfStarCT.dfColors[j] = fs->dfStarCT.dfColors[j];
}
in->bColMassWeight = fs->bColMassWeight;
in->bGasSph = fs->bGasSph;
in->iColStarAge = fs->iColStarAge;
in->bColLogInterp = fs->bColLogInterp;
in->iLogScale = fs->iLogScale;
in->iTarget = fs->iTarget;
in->dGasSoftMul = fs->dGasSoftMul;
in->dDarkSoftMul = fs->dDarkSoftMul;
in->dStarSoftMul = fs->dStarSoftMul;
in->iRender = fs->iRender;
if (fs->bEyeAbsolute) {
DIFF( fs->eye, in->r, in->z );
}
else {
double zero[3]={ 0, 0, 0 };
DIFF( fs->eye, zero, in->z );
}
/* fprintf(stderr,"eye2: %i %lf %lf %lf, %lf %lf %lf",fs->bEye2,fs->eye2[0],fs->eye2[1],fs->eye2[2], in->z[0],in->z[1],in->z[2] ); */
if (fs->bzEye1) SIZEVEC( in->z, fs->zEye1 );
/* fprintf(stderr,"eye2: %i %lf %lf %lf, %lf %lf %lf",fs->bEye2,fs->eye2[0],fs->eye2[1],fs->eye2[2], in->z[0],in->z[1],in->z[2] ); */
if (fs->bEye2) {
SET( vec, fs->eye2 );
if (fs->bzEye2) SIZEVEC( vec, fs->zEye2 );
ADD ( in->z, vec );
}
/* fprintf(stderr,"eye2: %i %lf %lf %lf, %lf %lf %lf",fs->bEye2,fs->eye2[0],fs->eye2[1],fs->eye2[2], in->z[0],in->z[1],in->z[2] ); */
if (fs->bzEye) {
in->zEye = fs->zEye;
}
else {
in->zEye = LEN( in->z );
}
if (fs->bExpansion) in->zEye/= in->dExp; /* Use physical units for sizing? */
/* zEye is used to scale viewport */
CkAssert( in->zEye > 0.0 );
if (fs->bzClipFrac) {
in->zClipNear = in->zEye*fs->zClipNear;
in->zClipFar = in->zEye*fs->zClipFar;
}
else {
in->zClipNear = fs->zClipNear;
in->zClipFar = fs->zClipFar;
}
NORM( in->z );
width = 2*tan( fs->FOV*M_PI/180.*0.5 )*in->zEye;
height = width*in->nyPix/in->nxPix;
CURL( fs->up, in->z, in->x );
if (fs->iProject == DF_PROJECT_PERSPECTIVE) {
SIZEVEC( in->x, (in->nxPix*0.5*in->zEye/width) );
}
else {
SIZEVEC( in->x, (in->nxPix*0.5/width) );
}
CURL( in->z, in->x, in->y );
if (fs->iProject == DF_PROJECT_PERSPECTIVE) {
SIZEVEC( in->y, (in->nyPix*0.5*in->zEye/height) );
}
else {
SIZEVEC( in->y, (in->nyPix*0.5/height) );
}
/* Render helper variables */
in->xlim = (in->nxPix-1)*.5;
in->ylim = (in->nyPix-1)*.5;
in->hmul = 4*sqrt(in->x[0]*in->x[0] + in->x[1]*in->x[1] + in->x[2]*in->x[2]);
/* in->bNonLocal not set (an internal use only variable) */
if (in->bVDetails) {
CkPrintf("DF Projection: %i x %i FOV %f width %f height %f\n",fs->nxPix,fs->nyPix,fs->FOV,width,height);
CkPrintf("DF eye %f %f %f, target %f %f %f, (separation %f)\n",fs->eye[0],fs->eye[1],fs->eye[2],fs->target[0],fs->target[1],fs->target[2],in->zEye );
CkPrintf("DF up %f %f %f Z-Clipping: Near %f Far %f\n",fs->up[0],fs->up[1],fs->up[2],in->zClipNear,in->zClipFar);
CkPrintf("DF Vectors: x %f %f %f, y %f %f %f z %f %f %f\n",in->x[0],in->x[1],in->x[2], in->y[0],in->y[1],in->y[2], in->z[0],in->z[1],in->z[2] );
CkPrintf("DF Colours: \n");
if (in->dMassGasMin < DBL_MAX) {
CkPrintf("DF gas %s", VecFilename(in->dfGasCT.iProperty).c_str());
CkPrintf(" %f %f\n",in->dfGasCT.fPropMin,in->dfGasCT.fPropMax);
for (j=0;j<fs->dfGasCT.nColors;j++) {
float fOut = in->dfGasCT.fPropMin + in->dfGasCT.dfColors[j].fVal*
(in->dfGasCT.fPropMax-in->dfGasCT.fPropMin);
CkPrintf("DF gas %f %f %f %f \n",fOut,
in->dfGasCT.dfColors[j].dfColor.r,
in->dfGasCT.dfColors[j].dfColor.g,
in->dfGasCT.dfColors[j].dfColor.b);
}
}
if (in->dMassDarkMin < DBL_MAX) {
CkPrintf("DF dark %s", VecFilename(in->dfDarkCT.iProperty).c_str());
CkPrintf(" %f %f\n",in->dfDarkCT.fPropMin,
in->dfDarkCT.fPropMax);
for (j=0;j<fs->dfDarkCT.nColors;j++) {
float fOut = in->dfDarkCT.fPropMin + in->dfDarkCT.dfColors[j].fVal*
(in->dfDarkCT.fPropMax-in->dfDarkCT.fPropMin);
CkPrintf("DF dark %f %f %f %f \n",fOut,
in->dfDarkCT.dfColors[j].dfColor.r,
in->dfDarkCT.dfColors[j].dfColor.g,
in->dfDarkCT.dfColors[j].dfColor.b);
}
}
if (in->dMassStarMin < DBL_MAX) {
CkPrintf("DF star %s", VecFilename(in->dfStarCT.iProperty).c_str());
CkPrintf(" %f %f\n",in->dfStarCT.fPropMin,
in->dfStarCT.fPropMax);
for (j=0;j<fs->dfStarCT.nColors;j++) {
float fOut = in->dfStarCT.fPropMin + in->dfStarCT.dfColors[j].fVal*
(in->dfStarCT.fPropMax-in->dfStarCT.fPropMin);
CkPrintf("DF star %f %f %f %f \n",fOut,
in->dfStarCT.dfColors[j].dfColor.r,
in->dfStarCT.dfColors[j].dfColor.g,
in->dfStarCT.dfColors[j].dfColor.b);
}
}
}
}
void dfParseOptions( struct DumpFrameContext *df, char * filename ) {
FILE *fp;
int n,nitem;
char line[81],command[40],word[40];
char FileBaseName[81]="Frame";
char NumberingFormat[41]="";
df->iDimension = DF_2D;
df->iEncode = DF_ENCODE_PPM;
df->iNumbering = DF_NUMBERING_FRAME;
df->dMassGasMin = 0;
df->dMassGasMax = DBL_MAX;
df->dMassDarkMin = 0;
df->dMassDarkMax = DBL_MAX;
df->dMassStarMin = 0;
df->dMassStarMax = DBL_MAX;
df->nFrame = 0;
df->bGetCentreOfMass = 0;
df->bGetOldestStar = 0;
df->bGetPhotogenic = 0;
sprintf(df->FileName, "%s.%%09i.ppm", FileBaseName);
fp = fopen( filename, "r" );
if (fp==NULL) return;
for ( ;; ) {
if (fgets( line, 81, fp ) == NULL) break;
sscanf( line, "%s", command );
if (!strcmp( command, "t" ) || !strcmp( command, "time" )) df->nFrameSetup++; /* count times */
}
rewind( fp );
n=0;
for ( ;; ) {
if (fgets( line, 81, fp ) == NULL) break;
nitem = sscanf( line, "%s", command );
if (nitem != 1 || command[0]=='#') continue;
else if (!strcmp( command, "dim") || !strcmp( command, "dimension") ) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2 );
if (!strcmp( word, "2") ) {
df->iDimension = DF_2D;
}
else if (!strcmp( word, "3") ) {
df->iDimension = DF_3D;
}
else {
fprintf(stderr,"DF Unknown dimensions: %s\n",word);
CkAssert( 0 );
}
}
else if (!strcmp( command, "file") ) {
nitem = sscanf( line, "%s %80s", command, FileBaseName );
CkAssert( strlen(FileBaseName) > 0 );
}
else if (!strcmp( command, "gas") ) {
nitem = sscanf( line, "%s %s", command, word );
if (nitem == 2 && (!strcmp( word, "no") ||!strcmp( word, "off" ))) {
df->dMassGasMin = DBL_MAX;
}
else {
nitem = sscanf( line, "%s %lf %lf", command,
&df->dMassGasMin, &df->dMassGasMax );
CkAssert( nitem == 3 );
}
}
else if (!strcmp( command, "dark") ) {
nitem = sscanf( line, "%s %s", command, word );
if (nitem == 2 && (!strcmp( word, "no") ||!strcmp( word, "off" ))) {
df->dMassDarkMin = DBL_MAX;
}
else {
nitem = sscanf( line, "%s %lf %lf", command,
&df->dMassDarkMin, &df->dMassDarkMax );
CkAssert( nitem == 3 );
}
}
else if (!strcmp( command, "star") ) {
nitem = sscanf( line, "%s %s", command, word );
if (nitem == 2 && (!strcmp( word, "no") ||!strcmp( word, "off" ))) {
df->dMassStarMin = DBL_MAX;
}
else {
nitem = sscanf( line, "%s %lf %lf", command,
&df->dMassStarMin, &df->dMassStarMax );
if(nitem != 3) {
CkError("Bad director format: %s\n", line);
CkAbort("Bad director format");
}
}
}
else if (!strcmp( command, "encode") ) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2 );
if (!strcmp( word, "ppm") ) {
df->iEncode = DF_ENCODE_PPM;
}
else if (!strcmp( word, "png") ) {
df->iEncode = DF_ENCODE_PNG;
#ifndef USE_PNG
fprintf(stderr,"DF PNG encoding support not compiled in\n");
CkAssert(0);
#endif
}
else if (!strcmp( word, "rle") ) {
df->iEncode = DF_ENCODE_RLE;
fprintf(stderr,"DF RLE encoding not supported yet\n");
CkAssert(0);
}
else if (!strcmp( word, "treezip") ) {
df->iEncode = DF_ENCODE_TREEZIP;
fprintf(stderr,"DF Voxel encoding not supported yet\n");
CkAssert(0);
}
else {
fprintf(stderr,"DF Unknown encoding: %s\n",word);
CkAssert(0);
}
}
else if (!strcmp( command, "numbering") ) {
nitem = sscanf( line, "%s %s %40s", command, word, NumberingFormat );
if (nitem == 2 ) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2 );
}
if (!strcmp( word, "frame") ) {
df->iNumbering = DF_NUMBERING_FRAME;
}
else if (!strcmp( word, "step") ) {
df->iNumbering = DF_NUMBERING_STEP;
}
else if (!strcmp( word, "time") ) {
df->iNumbering = DF_NUMBERING_TIME;
}
else {
fprintf(stderr,"DF Unknown numbering type: %s\n",word);
CkAssert( 0 );
}
}
else if (!strcmp( command, "frame") ) {
nitem = sscanf( line, "%s %i", command, &df->nFrame );
CkAssert( nitem == 2 );
}
}
if (df->iDimension == DF_3D) {
fprintf(stderr,"DF Voxel projection/encoding not supported yet\n");
CkAssert(0);
df->iEncode = DF_ENCODE_TREEZIP; /* Encode same thing */
}
else CkAssert (df->iEncode != DF_ENCODE_TREEZIP);
if (strlen(NumberingFormat)==0) {
switch( df->iNumbering ) {
case DF_NUMBERING_FRAME:
strcpy(NumberingFormat,"%09i");
break;
case DF_NUMBERING_STEP:
case DF_NUMBERING_TIME:
strcpy(NumberingFormat,"%012.6f");
break;
}
}
switch ( df->iEncode ) {
case DF_ENCODE_PPM:
sprintf(df->FileName,"%s.%s.ppm", FileBaseName, NumberingFormat );
break;
case DF_ENCODE_PNG:
sprintf(df->FileName,"%s.%s.png", FileBaseName, NumberingFormat );
break;
default:
sprintf(df->FileName,"%s.%s.null", FileBaseName, NumberingFormat );
break;
}
fclose(fp);
}
int dfPropertyToType(char *word)
{
if(!strcmp(word,"T") || !strcmp(word,"temp") || !strcmp(word,"Temp") ||
!strcmp(word,"Temperature") || !strcmp(word,"temperature") )
return OUT_TEMP_ARRAY;
else if(!strcmp(word,"density") || !strcmp(word,"Density") ||
!strcmp(word,"rho") || !strcmp(word,"dens") ||
!strcmp(word,"Dens") || !strcmp(word,"DENS"))
return OUT_DENSITY_ARRAY;
// return GasDenOutputParams(string("junk"), 0, fs->dTime);
else if(!strcmp(word,"udot") || !strcmp(word,"uDot") ||
!strcmp(word,"edot") || !strcmp(word,"eDot") ||
!strcmp(word,"Edot") || !strcmp(word,"EDot"))
return OUT_UDOT_ARRAY;
else if(!strcmp(word,"pressure") || !strcmp(word,"pres") ||
!strcmp(word,"Pressure") || !strcmp(word,"Pres"))
return OUT_U_ARRAY;
else if(!strcmp(word,"metals") || !strcmp(word,"Metals") ||
!strcmp(word,"metal") || !strcmp(word,"Metal") ||
!strcmp(word,"metallicity") || !strcmp(word,"Z"))
return OUT_METALS_ARRAY;
else if(!strcmp(word,"tform") || !strcmp(word,"timeform") ||
!strcmp(word,"formtime") || !strcmp(word,"TFORM") ||
!strcmp(word,"formt") || !strcmp(word,"TIMEFORM"))
return OUT_TIMEFORM_ARRAY;
else if(!strcmp(word,"age") || !strcmp(word,"Age"))
return OUT_AGE_ARRAY;
/* else if(!strcmp(word,"grp") || !strcmp(word,"group") ||
!strcmp(word,"GRP") || !strcmp(word,"GROUP") ||
!strcmp(word,"grpID") || !strcmp(word,"grpid") ||
!strcmp(word,"groupid") || !strcmp(word,"groupID"))
return OUT_GROUP_ARRAY;
*/
else return 0;
}
int dfReadColorMapFile(DFCOLORTABLE *dfCT, char *word, float scaler){
char *pachFile, *mapFile, achTemp[128], fileText[100];
FILE *fp;
fpos_t fpPos;
float fVal,r,g,b;
int i=0,nlines=0,iFSret;
fp = fopen("colortables.txt","r"); /* first search local directory*/
if (fp == NULL) { /* Then try the directory where env var points */
pachFile = getenv("PKDGRAV_CHECKPOINT_FDL");
if(pachFile != NULL) {
strcpy(achTemp,pachFile);
mapFile = dirname(achTemp); /* source directory? */
sprintf(mapFile,"%s/colortables.txt",mapFile);
fp = fopen(mapFile, "r");
}
}
if (fp == NULL) { /* Then try the directory where env var points */
mapFile = getenv("CHANGA_AUX_DIR");
if(mapFile != NULL) {
sprintf(mapFile,"%s/colortables.txt",mapFile);
fp = fopen(mapFile, "r");
}
}
if (fp == NULL) return 0;
/* find requested color table */
iFSret = fscanf(fp, "%s", fileText);
while (strcmp(word,fileText) && (iFSret != EOF)) {
iFSret = fscanf(fp, "%s", fileText);
}
if (iFSret == EOF) return 0; /* return 0 when nothing found */
/* read color table */
fgetpos(fp, &fpPos);
while (0<fscanf(fp, "%f %f %f %f\n",&fVal, &r, &g, &b)) nlines++;
fsetpos(fp, &fpPos); /* rewind to before lines */
dfCT->nColors = nlines;
while (0<fscanf(fp, "%f %f %f %f\n",&fVal, &r, &g, &b)) {
dfCT->dfColors[i].fVal = fVal;
dfCT->dfColors[i].dfColor.r = r*scaler;
dfCT->dfColors[i].dfColor.g = g*scaler;
dfCT->dfColors[i].dfColor.b = b*scaler;
i++;
}
fclose(fp);
return nlines;
}
DFCOLORTABLE *dfWordToColortable(char *word, struct dfFrameSetup *fs) {
if (!strcmp("gas",word)||!strcmp("GAS",word)||
!strcmp("Gas",word)||!strcmp("g",word)||
!strcmp("G",word)||!strcmp("gas",word)){
return &(fs->dfGasCT);
}
else if (!strcmp("dark",word)||!strcmp("DARK",word)||
!strcmp("Dark",word)||!strcmp("d",word)||
!strcmp("D",word)||!strcmp("dark",word)) {
return &(fs->dfDarkCT);
}
else if (!strcmp("star",word)||!strcmp("STAR",word)||
!strcmp("Star",word)||!strcmp("s",word)||
!strcmp("S",word)||!strcmp("star",word)||
!strcmp( word,"starbri") || !strcmp( word,"starcol") ||
!strcmp( word, "starbricol" )) {
return &(fs->dfStarCT);
}
else return NULL;
}
void dfParseCameraDirections( struct DumpFrameContext *df, char * filename ) {
FILE *fp;
/* struct inDumpFrame in; */
struct dfFrameSetup fs;
int n,nitem;
#define CMWOFF 1
#define CMWON 2
int bCMW = 0;
char line[81],command[40],word[40],otherword[40];
float fMin, fMax;
df->bLoop = 0;
df->dTimeMod = 0;
df->dTimeLoop = 1e20;
df->dPeriodLoop = 0;
/* Defaults -- most of this is for 2D only */
fs.bCooling = df->bCooling;
fs.duTFac = df->duTFac;
fs.dTime = 0;
fs.nxPix = 800;
fs.nyPix = 600;
fs.target[0] = 0;
fs.target[1] = 0;
fs.target[2] = 0;
fs.eye[0] = 0;
fs.eye[1] = 0;
fs.eye[2] = -.5;
fs.up[0] = 0;
fs.up[1] = 1;
fs.up[2] = 0;
fs.zEye = 0.0;
fs.zEye1 = 0.0;
fs.zEye2 = 0.0;
fs.eye2[0] = 0;
fs.eye2[1] = 0;
fs.eye2[2] = 0;
fs.bEye2 = 0;
fs.bzEye = 0;
fs.bzEye1 = 0;
fs.bzEye2 = 0;
fs.bEyeAbsolute = 0;
fs.FOV = 90.;
fs.zClipNear = 0.01;
fs.zClipFar = 2.0;
fs.bzClipFrac = 1;
fs.bExpansion = 0; /* to physical? */
fs.bPeriodic = 0; /* Periodic? */
fs.fPeriod[0] = 1.0e38;
fs.fPeriod[1] = 1.0e38;
fs.fPeriod[2] = 1.0e38;
fs.iProject = DF_PROJECT_PERSPECTIVE;
/* Render */
fs.dfDarkCT.nColors=1;
fs.dfDarkCT.dfColors[0].dfColor.r = 0;
fs.dfDarkCT.dfColors[0].dfColor.g = 0;
fs.dfDarkCT.dfColors[0].dfColor.b = 1.0;
fs.dfDarkCT.iProperty=OUT_DENSITY_ARRAY;
fs.dfDarkCT.fPropMin=0;
fs.dfDarkCT.fPropMax=1;
fs.dfGasCT.nColors=1;
fs.dfGasCT.dfColors[0].dfColor.r = 0;
fs.dfGasCT.dfColors[0].dfColor.g = 1.0;
fs.dfGasCT.dfColors[0].dfColor.b = 0;
fs.dfGasCT.iProperty=OUT_TEMP_ARRAY;
fs.dfGasCT.fPropMin=3.5;
fs.dfGasCT.fPropMax=6;
fs.dfStarCT.nColors=1;
fs.dfStarCT.dfColors[0].dfColor.r = 1.0;
fs.dfStarCT.dfColors[0].dfColor.g = 0;
fs.dfStarCT.dfColors[0].dfColor.b = 0;
fs.dfStarCT.iProperty=OUT_TIMEFORM_ARRAY;
fs.dfStarCT.fPropMin=0;
fs.dfStarCT.fPropMax=0.3;
fs.bColMassWeight = 1;
fs.bGasSph = 1;
fs.iColStarAge = DF_STAR_AGE_BASIC;
fs.bColLogInterp = 1;
fs.iLogScale = DF_LOG_NULL;
fs.iTarget = DF_TARGET_USER;
fs.dGasSoftMul = 1;
fs.dDarkSoftMul = 1;
fs.dStarSoftMul = 1;
fs.iRender = DF_RENDER_POINT;
fp = fopen( filename, "r" );
if (fp==NULL) {
fprintf(stderr,"DF Could not open camera director file: %s\n",filename );
df->iFrameSetup = 0;
df->nFrameSetup = 1;
df->fs = (struct dfFrameSetup *) malloc(sizeof(struct dfFrameSetup)*df->nFrameSetup);
CkAssert( df->fs != NULL );
if (df->bVDetails) CkPrintf("DF Default Frame Setup\n" );
/* dfProjection( &in, &fs ); */ /* Redundant now -- done again later */
df->fs[0] = fs;
return;
}
if (df->bVDetails) CkPrintf("DF Reading camera directions from: %s\n",filename );
df->iFrameSetup = -1;
df->nFrameSetup=1; /* Defaults */
for ( ;; ) {
if (fgets( line, 81, fp ) == NULL) break;
sscanf( line, "%s", command );
if (!strcmp( command, "t" ) || !strcmp( command, "time" )) df->nFrameSetup++; /* count times */
}
rewind( fp );
df->fs = (struct dfFrameSetup *) malloc(sizeof(struct dfFrameSetup)*df->nFrameSetup);
CkAssert( df->fs != NULL );
n=0;
if (df->bVDetails) CkPrintf("DF Default Frame Setup\n" );
for ( ;; ) {
if (fgets( line, 81, fp ) == NULL) break;
nitem = sscanf( line, "%s", command );
if (nitem != 1 || command[0]=='#') continue;
else if (!strcmp( command, "t" ) || !strcmp( command, "time" )) {
/* dfProjection( &in, &fs ); */ /* Redundant now -- done again later */
df->fs[n] = fs;
n++; /* next setup */
nitem = sscanf( line, "%s %lf", command, &fs.dTime );
CkAssert( nitem == 2 );
if (df->bVDetails) CkPrintf("DF Frame Setup from time: %f\n",fs.dTime );
}
else if (!strcmp( command, "target") ) {
nitem = sscanf( line, "%s %lf %lf %lf", command, &fs.target[0], &fs.target[1], &fs.target[2] );
if (nitem != 4) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2);
if (!strcmp( word, "gas") ) {
fs.iTarget = DF_TARGET_COM_GAS;
df->bGetCentreOfMass = 1;
}
else if (!strcmp( word, "dark") ) {
fs.iTarget = DF_TARGET_COM_DARK;
df->bGetCentreOfMass = 1;
}
else if (!strcmp( word, "star") ) {
fs.iTarget = DF_TARGET_COM_STAR;
df->bGetCentreOfMass = 1;
}
else if (!strcmp( word, "all") ) {
fs.iTarget = DF_TARGET_COM_ALL;
df->bGetCentreOfMass = 1;
}
else if (!strcmp( word, "oldeststar" ) ) {
fs.iTarget = DF_TARGET_OLDEST_STAR;
df->bGetOldestStar = 1;
}
else if (!strcmp( word, "photogenic" ) ) {
fs.iTarget = DF_TARGET_PHOTOGENIC;
df->bGetPhotogenic = 1;
}
else {
CkAssert(0);
}
}
}
else if (!strcmp( command, "eye") || !strcmp( command, "eye1") ) {
nitem = sscanf( line, "%s %lf %lf %lf", command, &fs.eye[0], &fs.eye[1], &fs.eye[2] );
if ( nitem != 4 ) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2 );
if (!strcmp( word, "rel") ) {
fs.bEyeAbsolute = 0;
}
else if (!strcmp( word, "abs") ) {
fs.bEyeAbsolute = 1;
}
else {
fprintf(stderr,"DF Unknown eye offset type: %s\n",word);
CkAssert( 0 );
}
}
}
else if (!strcmp( command, "eye2") ) {
nitem = sscanf( line, "%s %lf %lf %lf", command, &fs.eye2[0], &fs.eye2[1], &fs.eye2[2] );
fs.bEye2 = 1;
CkAssert( nitem == 4 );
}
else if (!strcmp( command, "up") ) {
nitem = sscanf( line, "%s %lf %lf %lf", command, &fs.up[0], &fs.up[1], &fs.up[2] );
CkAssert( nitem == 4 );
}
else if (!strcmp( command, "size") ) {
nitem = sscanf( line, "%s %i %i", command, &fs.nxPix, &fs.nyPix );
CkAssert( nitem == 3 );
}
else if (!strcmp( command, "zeye") ) {
fs.bzEye = 1;
nitem = sscanf( line, "%s %lf", command, &fs.zEye );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "zeye1") ) {
fs.bzEye1 = 1;
nitem = sscanf( line, "%s %lf", command, &fs.zEye1 );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "zeye2") ) {
fs.bzEye2 = 1;
nitem = sscanf( line, "%s %lf", command, &fs.zEye2 );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "exp") || !strcmp( command, "physical") ) {
fs.bExpansion = 1;
}
else if (!strcmp( command, "fov") || !strcmp( command, "FOV") ) {
nitem = sscanf( line, "%s %lf", command, &fs.FOV );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "loop") ) {
nitem = sscanf( line, "%s %lf %lf", command, &df->dTimeLoop, &df->dPeriodLoop );
CkAssert( nitem == 3 );
}
else if (!strcmp( command, "clip") ) {
df->bLoop = 1;
nitem = sscanf( line, "%s %lf %lf", command, &fs.zClipNear, &fs.zClipFar );
CkAssert( nitem == 3 );
}
else if (!strcmp( command, "clipabs") ) {
fs.bzClipFrac = 0;
nitem = sscanf( line, "%s %lf %lf", command, &fs.zClipNear, &fs.zClipFar );
CkAssert( nitem == 3 );
}
else if (!strcmp( command, "clipfrac") ) {
fs.bzClipFrac = 1;
nitem = sscanf( line, "%s %lf %lf", command, &fs.zClipNear, &fs.zClipFar );
CkAssert( nitem == 3 );
}
else if (!strcmp( command, "project") ) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2 );
if (!strcmp( word, "ortho") ) {
fs.iProject = DF_PROJECT_ORTHO;
}
else if (!strcmp( word, "perspective") ) {
fs.iProject = DF_PROJECT_PERSPECTIVE;
}
else {
fprintf(stderr,"DF Unknown projection: %s\n",word);
CkAssert( 0 );
}
}
else if (!strcmp( command, "colbyproperty" )) {
DFCOLORTABLE *pdfCT;
nitem = sscanf( line, "%s %s %s %f %f", command, word,otherword,
&fMin, &fMax);
if (nitem==5) {
pdfCT = dfWordToColortable(word,&fs);
pdfCT->iProperty=dfPropertyToType(otherword);
pdfCT->fPropMin=fMin;
pdfCT->fPropMax=fMax;
}
else {
fprintf(stderr,"DF wrong argument number to colbyproperty type property min max\n");
CkAssert( 0 );
}
}
else if (!strcmp( command, "colormap" )) {
float scaler=1.0;
nitem = sscanf( line, "%s %s %s %f", command, word, otherword,
&scaler);
if (nitem==4) {
dfReadColorMapFile(dfWordToColortable(word,&fs),otherword,
scaler);
}
else {
fprintf(stderr,"DF wrong argument number to: colormap type mapname gamma\n");
CkAssert( 0 );
}
}
else if (!strcmp( command, "color" )) {
DFCOLORTABLE *pdfCT;
float r,g,b,scaler=1.0;
if(6 == sscanf( line, "%s %s %f %f %f %f",command,word,&r,&g,&b,
&scaler )) {
CkAssert( !(bCMW & CMWOFF) );
bCMW |= CMWON;
fs.bColMassWeight = 1;
}
else if (5 == sscanf(line,"%s %s %f %f %f",command,word,&r,&g,&b)){
CkAssert( !(bCMW & CMWON) );
bCMW |= CMWOFF;
}
else {
fprintf(stderr,"DF wrong argument number to color type property r g b [scaler]\n");
CkAssert( 0 );
}
pdfCT = dfWordToColortable(word,&fs);
pdfCT->dfColors[0].dfColor.r=scaler*r;
pdfCT->dfColors[0].dfColor.g=scaler*g;
pdfCT->dfColors[0].dfColor.b=scaler*b;
pdfCT->nColors = 1;
if (!strcmp(word, "colstar" ))
fs.iColStarAge = DF_STAR_AGE_BASIC;
else if(!strcmp(word, "colstarbri" ))
fs.iColStarAge = DF_STAR_AGE_BRIGHT;
else if(!strcmp(word, "colstarcol" ))
fs.iColStarAge = DF_STAR_AGE_COLOUR;
else if(!strcmp(word, "colstarbricol" ))
fs.iColStarAge = DF_STAR_AGE_BRIGHT_COLOUR;
}
else if (!strcmp( command, "colgas" )) {
float r,g,b,scaler=1.0;
nitem = sscanf( line, "%s %f %f %f %f", command, &r, &g, &b, &scaler );
if (nitem == 5) {
assert( !(bCMW & CMWOFF) );
bCMW |= CMWON;
fs.bColMassWeight = 1;
fs.dfGasCT.dfColors[0].dfColor.r=r/scaler;
fs.dfGasCT.dfColors[0].dfColor.g=g/scaler;
fs.dfGasCT.dfColors[0].dfColor.b=b/scaler;
}
else {
nitem = sscanf( line, "%s %f %f %f", command, &r, &g, &b );
assert( nitem == 4 );
assert( !(bCMW & CMWON) );
bCMW |= CMWOFF;
fs.dfGasCT.dfColors[0].dfColor.r=r;
fs.dfGasCT.dfColors[0].dfColor.g=g;
fs.dfGasCT.dfColors[0].dfColor.b=b;
}
}
else if (!strcmp( command, "coldark" )) {
float r,g,b,scaler=1.0;
nitem = sscanf( line, "%s %f %f %f %f", command, &r, &g, &b, &scaler );
if (nitem == 5) {
assert( !(bCMW & CMWOFF) );
bCMW |= CMWON;
fs.bColMassWeight = 1;
fs.dfDarkCT.dfColors[0].dfColor.r=r/scaler;
fs.dfDarkCT.dfColors[0].dfColor.g=g/scaler;
fs.dfDarkCT.dfColors[0].dfColor.b=b/scaler;
}
else {
nitem = sscanf( line, "%s %f %f %f", command, &r, &g, &b );
assert( nitem == 4 );
assert( !(bCMW & CMWON) );
bCMW |= CMWOFF;
fs.dfDarkCT.dfColors[0].dfColor.r=r;
fs.dfDarkCT.dfColors[0].dfColor.g=g;
fs.dfDarkCT.dfColors[0].dfColor.b=b;
}
}
else if (!strcmp( command, "colstar" )
|| !strcmp( command, "colstarbri" )
|| !strcmp( command, "colstarcol" )
|| !strcmp( command, "colstarbricol" )) {
float r,g,b,scaler=1.0;
if (!strcmp( command, "colstar" ))
fs.iColStarAge = DF_STAR_AGE_BASIC;
else if(!strcmp( command, "colstarbri" ))
fs.iColStarAge = DF_STAR_AGE_BRIGHT;
else if(!strcmp( command, "colstarcol" ))
fs.iColStarAge = DF_STAR_AGE_COLOUR;
else if(!strcmp( command, "colstarbricol" ))
fs.iColStarAge = DF_STAR_AGE_BRIGHT_COLOUR;
nitem = sscanf( line, "%s %f %f %f %f", command, &r, &g, &b, &scaler );
if (nitem == 5) {
assert( !(bCMW & CMWOFF) );
bCMW |= CMWON;
fs.bColMassWeight = 1;
fs.dfStarCT.dfColors[0].dfColor.r=r/scaler;
fs.dfStarCT.dfColors[0].dfColor.g=g/scaler;
fs.dfStarCT.dfColors[0].dfColor.b=b/scaler;
}
else {
nitem = sscanf( line, "%s %f %f %f", command, &r, &g, &b );
assert( nitem == 4 );
assert( !(bCMW & CMWON) );
bCMW |= CMWOFF;
fs.dfStarCT.dfColors[0].dfColor.r=r;
fs.dfStarCT.dfColors[0].dfColor.g=g;
fs.dfStarCT.dfColors[0].dfColor.b=b;
}
}
else if (!strcmp( command, "colmass" )) {
CkAssert( !(bCMW & CMWOFF) );
bCMW |= CMWON;
fs.bColMassWeight = 1;
}
else if (!strcmp( command, "colloginterp" )) {
nitem = sscanf( line, "%s %s", command, word );
if (nitem == 2 && (!strcmp( word, "no") ||!strcmp( word, "off" ))) {
fs.bColLogInterp = 0;
}
else
fs.bColLogInterp = 1;
}
else if (!strcmp( command, "logscale" )) {
nitem = sscanf( line, "%s %lf %lf", command, &fs.pScale1, &fs.pScale2 );
CkAssert( nitem == 3 );
fs.iLogScale = DF_LOG_SATURATE;
}
else if (!strcmp( command, "logscalecoloursafe" )) {
nitem = sscanf( line, "%s %lf %lf", command, &fs.pScale1, &fs.pScale2 );
CkAssert( nitem == 3 );
fs.iLogScale = DF_LOG_COLOURSAFE;
}
else if (!strcmp( command, "softgassph" )) {
fs.bGasSph = 1;
}
else if (!strcmp( command, "softgas" )) {
fs.bGasSph = 0;
nitem = sscanf( line, "%s %lf", command, &fs.dGasSoftMul );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "softdark" )) {
nitem = sscanf( line, "%s %lf", command, &fs.dDarkSoftMul );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "softstar" )) {
nitem = sscanf( line, "%s %lf", command, &fs.dStarSoftMul );
CkAssert( nitem == 2 );
}
else if (!strcmp( command, "render") ) {
nitem = sscanf( line, "%s %s", command, word );
CkAssert( nitem == 2 );
if (!strcmp( word, "point") ) {
fs.iRender = DF_RENDER_POINT;
}
else if (!strcmp( word, "tsc") ) {
fs.iRender = DF_RENDER_TSC;
}
else if (!strcmp( word, "solid") ) {
fs.iRender = DF_RENDER_SOLID;
}
else if (!strcmp( word, "shine") ) {
fs.iRender = DF_RENDER_SHINE;
}
else {
fprintf(stderr,"DF Unknown rendering: %s\n",word);
assert( 0 );
}
}
}
/* Redundant now -- done again later */
/*
in.bVDetails = df->bVDetails;
dfProjection( &in, &fs );
*/
df->fs[n] = fs;
n++; /* next setup */
if (n==1) df->iFrameSetup = 0;
CkAssert ( n == df->nFrameSetup );
fclose(fp);
}
void dfSetupFrame( struct DumpFrameContext *df, double dTime, double dStep, double dExp, double *com, struct inDumpFrame *vin, int nxPix, int nyPix ) {
struct dfFrameSetup fs;
int ifs = df->iFrameSetup;
vin->dTime = dTime;
vin->dYearUnit = df->dYearUnit;
vin->dStep = dStep;
vin->dExp = dExp;
vin->duTFac = df->duTFac;
vin->bVDetails = df->bVDetails;
vin->dMassStarMin = df->dMassStarMin;
vin->dMassStarMax = df->dMassStarMax;
vin->dMassGasMin = df->dMassGasMin;
vin->dMassGasMax = df->dMassGasMax;
vin->dMassDarkMin = df->dMassDarkMin;
vin->dMassDarkMax = df->dMassDarkMax;
if (df->bLoop) {
dTime -= df->dTimeMod;
if (dTime > df->dPeriodLoop+df->dTimeLoop) {
dTime -= df->dPeriodLoop;
df->dTimeMod += df->dPeriodLoop;
ifs = -1;
}
}
if (ifs == -1) {
CkAssert( df->nFrameSetup > 1 );
if (dTime < df->fs[1].dTime) { /* Outside range */
fprintf(stderr,"DF WARNING Initial Time outside camera direction table: %g < %g\n",dTime,df->fs[1].dTime);
df->iFrameSetup = ifs = 0;
}
else {
ifs = 1;
while (ifs < df->nFrameSetup && dTime >= df->fs[ifs+1].dTime ) ifs++;
if (ifs >= df->nFrameSetup-1) { /* Outside Range */
if (dTime == df->fs[df->nFrameSetup-1].dTime && ifs > 1) ifs--;
else {
fprintf(stderr,"DF WARNING Initial Time outside camera direction table: %g > %g\n",dTime,df->fs[df->nFrameSetup-1].dTime);
df->iFrameSetup = ifs = 0;
}
}
df->iFrameSetup = ifs;
dfGetCoeff( df, ifs );
}
}
else if (df->nFrameSetup > 1) {
while (dTime > df->fs[ifs+1].dTime || (!ifs && dTime >= df->fs[ifs+1].dTime)) {
ifs++;
if (ifs >= df->nFrameSetup-1) {
fprintf(stderr,"DF WARNING Time outside camera direction table: %g > %g\n",dTime,df->fs[df->nFrameSetup-1].dTime);
df->iFrameSetup = ifs = 0;
break;
}
df->iFrameSetup = ifs;
dfGetCoeff( df, ifs );
}
}
if (df->bVDetails) CkPrintf("DF Interpolating at t=%g Setups: %i (t=%g) %i (t=%g)\n",dTime,ifs,df->fs[ifs].dTime,ifs+1,df->fs[ifs+1].dTime);
fs = df->fs[ifs];
/* Nothing to interpolate? */
if (ifs) {
/*
Interpolate Eye position, FOV etc...
from df->fs[ifs].dTime <= dTime <= df->fs[ifs+1].dTime
*/
dfInterp( df, &fs, (dTime-fs.dTime)*df->rdt );
}
switch (fs.iTarget) {
case DF_TARGET_COM_GAS:
if (com[3]>0) {
fs.target[0] = com[0]/com[3];
fs.target[1] = com[1]/com[3];
fs.target[2] = com[2]/com[3];
}
break;
case DF_TARGET_COM_DARK:
if (com[7]>0) {
fs.target[0] = com[4]/com[7];
fs.target[1] = com[5]/com[7];
fs.target[2] = com[6]/com[7];
}
break;
case DF_TARGET_COM_STAR:
if (com[11]>0) {
fs.target[0] = com[8]/com[11];
fs.target[1] = com[9]/com[11];
fs.target[2] = com[10]/com[11];
}
break;
case DF_TARGET_COM_ALL:
if (com[3]+com[7]+com[11]>0) {
fs.target[0] = (com[0]+com[4]+com[8])/(com[3]+com[7]+com[11]);
fs.target[1] = (com[1]+com[5]+com[9])/(com[3]+com[7]+com[11]);
fs.target[2] = (com[2]+com[6]+com[10])/(com[3]+com[7]+com[11]);
}
break;
case DF_TARGET_OLDEST_STAR:
if (com[3] < DBL_MAX) {
fs.target[0] = com[0];
fs.target[1] = com[1];
fs.target[2] = com[2];
}
break;
case DF_TARGET_PHOTOGENIC:
if (com[3] < DBL_MAX) {
fs.target[0] = com[0]/com[3];
fs.target[1] = com[1]/com[3];
fs.target[2] = com[2]/com[3];
}
break;
}
dfProjection( vin, &fs, nxPix, nyPix );
}
void dfClearImage( struct inDumpFrame *in, void *vImage, int *nImage ) {
DFIMAGE *Image = (DFIMAGE *)vImage;
int i;
DFIMAGE blank;
blank.r = 0;
blank.g = 0;
blank.b = 0;
*nImage = in->nxPix * in->nyPix * sizeof(DFIMAGE);
for (i=in->nxPix*in->nyPix-1;i>=0;i--) Image[i] = blank;
}
DFIMAGE dfInterpOnColorMap(DFCOLORTABLE *dfCT,double fVar, int bColLogInterp)
{
/* If fVar isn't between 0 and 1, the values will pin
to the min/max colors -GSS March 2013 */
int iCol;
float xCol, fCTrange;
DFIMAGE col;
if (dfCT->nColors<=1) return dfCT->dfColors[0].dfColor;
if (bColLogInterp) {
if (fVar > 0) fVar = log10(fVar);
else return dfCT->dfColors[0].dfColor;
}
fCTrange = dfCT->dfColors[dfCT->nColors-1].fVal - dfCT->dfColors[0].fVal;
fVar = (fVar - dfCT->fPropMin)/(dfCT->fPropMax-dfCT->fPropMin)*fCTrange;
if (fVar <= dfCT->dfColors[0].fVal) {
return dfCT->dfColors[0].dfColor;
}
else if (fVar >= dfCT->dfColors[dfCT->nColors-1].fVal) {
return dfCT->dfColors[dfCT->nColors-1].dfColor;
}
/* iCol specifies which range in colormap we're in */
/*find where we are in the colormap */
for (iCol = 1; fVar>=dfCT->dfColors[iCol].fVal; iCol++);
if (iCol >= dfCT->nColors)
return dfCT->dfColors[dfCT->nColors-1].dfColor;
/* xCol is the fraction distance through colormap range */
xCol = (fVar - dfCT->dfColors[iCol-1].fVal)/
(dfCT->dfColors[iCol].fVal-dfCT->dfColors[iCol-1].fVal);
col.r = xCol*dfCT->dfColors[iCol].dfColor.r +
(1-xCol)*dfCT->dfColors[iCol-1].dfColor.r;
col.g = xCol*dfCT->dfColors[iCol].dfColor.g +
(1-xCol)*dfCT->dfColors[iCol-1].dfColor.g;
col.b = xCol*dfCT->dfColors[iCol].dfColor.b +
(1-xCol)*dfCT->dfColors[iCol-1].dfColor.b;
return col;
}
void dfRenderParticlePoint( struct inDumpFrame *in, void *vImage,
GravityParticle *p, DataManager *dm)
{
DFIMAGE *Image = (DFIMAGE *)vImage;
DFIMAGE col; /* Colour */
DFCOLORTABLE *dfCT;
double x,y,z,dr[3];
int j;
int xp,yp;
Vector3D<double> r=p->position;
double fMass=p->mass;
if (p->isGas()) {
if (fMass < in->dMassGasMin || fMass > in->dMassGasMax) return;
dfCT=&(in->dfGasCT);
}
else if (p->isDark()) {
if (fMass < in->dMassDarkMin || fMass > in->dMassDarkMax) return;
dfCT=&(in->dfDarkCT);
}
else if (p->isStar()) {
if (fMass < in->dMassStarMin || fMass > in->dMassStarMax) return;
dfCT=&(in->dfStarCT);
}
col = dfInterpOnColorMap(dfCT,VecType (dfCT->iProperty,p,dm,in->duTFac,in->dTime),
in->bColLogInterp);
for (j=0;j<3;j++) {
dr[j] = r[j]-in->r[j];
if(dr[j] >= 0.5*in->fPeriod[j])
dr[j] -= in->fPeriod[j];
if(dr[j] < -0.5*in->fPeriod[j])
dr[j] += in->fPeriod[j];
}
z = dr[0]*in->z[0] + dr[1]*in->z[1] + dr[2]*in->z[2] + in->zEye;
if (z >= in->zClipNear && z <= in->zClipFar) {
x = dr[0]*in->x[0] + dr[1]*in->x[1] + dr[2]*in->x[2];
if (in->iProject == DF_PROJECT_PERSPECTIVE) x/=z;
if (fabs(x)<in->xlim) {
y = dr[0]*in->y[0] + dr[1]*in->y[1] + dr[2]*in->y[2];
if (in->iProject == DF_PROJECT_PERSPECTIVE) y/=z;
if (fabs(y)<in->ylim) {
xp = x+in->xlim;
yp = in->ylim-y; /* standard screen convention */
Image[ xp + yp*in->nxPix ].r += col.r;
Image[ xp + yp*in->nxPix ].g += col.g;
Image[ xp + yp*in->nxPix ].b += col.b;
}
}
}
}
void dfRenderParticleTSC( struct inDumpFrame *in, void *vImage,
GravityParticle *p, DataManager *dm)
{
DFIMAGE *Image = (DFIMAGE *)vImage;
DFIMAGE col; /* Colour */
DFCOLORTABLE *dfCT;
double h;
double x,y,z,dr[3],br0=1;
int hint, bNoMoreColCalc=0;
int j;
int xp,yp;
Vector3D<double> r=p->position;
double fMass=p->mass;
double fSoft=p->soft;
double fVar;
double fAge=0.0;
if (p->isStar()) fAge=(in->dTime-p->fTimeForm())*in->dYearUnit;
if (p->isGas()) {
if (fMass < in->dMassGasMin || fMass > in->dMassGasMax) return;
if (in->bGasSph) h = p->fBall*0.5*in->dGasSoftMul;
else h = fSoft*in->dGasSoftMul;
dfCT=&(in->dfGasCT);
}
else if (p->isDark()) {
if (fMass < in->dMassDarkMin || fMass > in->dMassDarkMax) return;
h = fSoft*in->dDarkSoftMul;
dfCT=&(in->dfDarkCT);
}
else if (p->isStar()) {
float al;
if (fMass < in->dMassStarMin || fMass > in->dMassStarMax) return;
h = fSoft*in->dStarSoftMul;
dfCT=&(in->dfStarCT);
switch (in->iColStarAge) {
case DF_STAR_AGE_BRIGHT_COLOUR:
case DF_STAR_AGE_COLOUR:
al = (log(fabs(fAge+1e6))-13.815)*(1/9.6);
col.b = dfCT->dfColors[0].dfColor.b*fabs(1-0.7*al);
col.g = dfCT->dfColors[0].dfColor.g*0.4;
col.r = dfCT->dfColors[0].dfColor.r*(0.4+0.32*al);
bNoMoreColCalc = 1;
break;
}
switch (in->iColStarAge) {
case DF_STAR_AGE_BASIC:
break;
case DF_STAR_AGE_BRIGHT:
case DF_STAR_AGE_BRIGHT_COLOUR:
br0 = 1./(fabs(fAge)/1e6+1.);
break;
case DF_STAR_AGE_COLOUR:
break;
}
}
/* Place particle on color table. */
if (!bNoMoreColCalc) {
double fTemp;
fTemp = VecType(dfCT->iProperty,p,dm,in->duTFac,in->dTime);
col = dfInterpOnColorMap(dfCT,fTemp,in->bColLogInterp);
}
if (in->bColMassWeight) {
if (in->dMinGasMass>0) br0*=fMass/in->dMinGasMass;
else br0*=fMass;
}
for (j=0;j<3;j++) {
dr[j] = r[j]-in->r[j];
if(dr[j] >= 0.5*in->fPeriod[j])
dr[j] -= in->fPeriod[j];
if(dr[j] < -0.5*in->fPeriod[j])
dr[j] += in->fPeriod[j];
}
z = dr[0]*in->z[0] + dr[1]*in->z[1] + dr[2]*in->z[2] + in->zEye;
if (z >= in->zClipNear && z <= in->zClipFar) {
if (in->iProject == DF_PROJECT_PERSPECTIVE) h = h*in->hmul/z;
else h = h*in->hmul;
hint = h;
x = dr[0]*in->x[0] + dr[1]*in->x[1] + dr[2]*in->x[2];
if (in->iProject == DF_PROJECT_PERSPECTIVE) x/=z;
if (fabs(x)<in->xlim+hint) {
y = dr[0]*in->y[0] + dr[1]*in->y[1] + dr[2]*in->y[2];
if (in->iProject == DF_PROJECT_PERSPECTIVE) y/=z;
if (fabs(y)<in->ylim+hint) {
x = x+in->xlim;
xp = x;
y = in->ylim-y; /* standard screen convention */
yp = y;
if (hint < 1) {
Image[ xp + yp*in->nxPix ].r += br0*col.r;
Image[ xp + yp*in->nxPix ].g += br0*col.g;
Image[ xp + yp*in->nxPix ].b += br0*col.b;
}
else {
int xpmin,xpmax,ypmin,ypmax,ix,iy;
DFIMAGE *Imagey;
double br,br1,r2,ih2;
ih2 = 1./(h*h);
br1 = br0*(6/(2.0*3.1412))*ih2;
xpmin = xp - hint; if (xpmin<0) xpmin=0;
xpmax = xp + hint; if (xpmax>=in->nxPix) xpmax=in->nxPix-1;
ypmin = yp - hint; if (ypmin<0) ypmin=0;
ypmax = yp + hint; if (ypmax>=in->nyPix) ypmax=in->nyPix-1;
for (iy=ypmin,Imagey = Image + iy*in->nxPix;iy<=ypmax;iy++,Imagey += in->nxPix) {
for (ix=xpmin;ix<=xpmax;ix++) {
r2 = ((ix-x)*(ix-x)+(iy-y)*(iy-y))*ih2;
if (r2 > 1) continue;
br = br1*(1.0-sqrt(r2));
Imagey[ ix ].r += br*col.r;
Imagey[ ix ].g += br*col.g;
Imagey[ ix ].b += br*col.b;
}
}
}
}
}
}
}
void dfRenderParticleSolid( struct inDumpFrame *in, void *vImage,
GravityParticle *p, DataManager *dm)
{
DFIMAGE *Image = (DFIMAGE *)vImage;
DFIMAGE col; /* Colour */
DFCOLORTABLE *dfCT;
double h;
double x,y,z,dr[3],br0;
int hint,bNoMoreColCalc=0;
int j;
int xp,yp;
double fVar;
Vector3D<double> r=p->position;
double fMass=p->mass;
double fSoft=p->soft;
double fBall=p->fBall;
double fAge;
if (p->isStar()) fAge=(in->dTime-p->fTimeForm())*in->dYearUnit;
br0=1;
if (p->isGas()) {
if (fMass < in->dMassGasMin || fMass > in->dMassGasMax) return;
if (in->bGasSph) h = fBall*0.5*in->dGasSoftMul;
else h = fSoft*in->dGasSoftMul;
dfCT=&(in->dfGasCT);
}
else if (p->isDark()) {
if (fMass < in->dMassDarkMin || fMass > in->dMassDarkMax) return;
h = fSoft*in->dDarkSoftMul;
dfCT=&(in->dfDarkCT);
}
else if (p->isStar()) {
if (fMass < in->dMassStarMin || fMass > in->dMassStarMax) return;
h = fSoft*in->dStarSoftMul;
dfCT=&(in->dfStarCT);
switch (in->iColStarAge) {
float al;
case DF_STAR_AGE_BRIGHT_COLOUR:
case DF_STAR_AGE_COLOUR:
al = (log(fabs(fAge+1e6))-13.815)*(1/9.6);
col.b = dfCT->dfColors[0].dfColor.b*fabs(1-0.7*al);
col.g = dfCT->dfColors[0].dfColor.g*0.4;
col.r = dfCT->dfColors[0].dfColor.r*(0.4+0.32*al);
bNoMoreColCalc = 1;
break;
}
switch (in->iColStarAge) {
case DF_STAR_AGE_BASIC:
break;
case DF_STAR_AGE_BRIGHT:
case DF_STAR_AGE_BRIGHT_COLOUR:
br0 = 1./(fabs(fAge)/1e6+1.);
break;
}
}
if (!bNoMoreColCalc) {
col = dfInterpOnColorMap(dfCT,VecType(dfCT->iProperty,p,dm,in->duTFac,in->dTime),
in->bColLogInterp);
}
if (in->bColMassWeight) {
if (in->dMinGasMass>0) br0*=fMass/in->dMinGasMass;
else br0*=fMass;
}
for (j=0;j<3;j++) {
dr[j] = r[j]-in->r[j];
if(dr[j] >= 0.5*in->fPeriod[j])
dr[j] -= in->fPeriod[j];
if(dr[j] < -0.5*in->fPeriod[j])
dr[j] += in->fPeriod[j];
}
z = dr[0]*in->z[0] + dr[1]*in->z[1] + dr[2]*in->z[2] + in->zEye;
if (z >= in->zClipNear && z <= in->zClipFar) {
if (in->iProject == DF_PROJECT_PERSPECTIVE) h = h*in->hmul/z;
else h = h*in->hmul;
hint = h;
x = dr[0]*in->x[0] + dr[1]*in->x[1] + dr[2]*in->x[2];
if (in->iProject == DF_PROJECT_PERSPECTIVE) x/=z;
if (fabs(x)<in->xlim+hint) {
y = dr[0]*in->y[0] + dr[1]*in->y[1] + dr[2]*in->y[2];
if (in->iProject == DF_PROJECT_PERSPECTIVE) y/=z;
if (fabs(y)<in->ylim+hint) {
xp = x+in->xlim;
yp = in->ylim-y; /* standard screen convention */
if (hint < 1) {
double br = 0.523599*br0*h*h; /* integral of TSC to h */
Image[ xp + yp*in->nxPix ].r += br*col.r;
Image[ xp + yp*in->nxPix ].g += br*col.g;
Image[ xp + yp*in->nxPix ].b += br*col.b;
}
else {
int xpmin,xpmax,ypmin,ypmax,ix,iy;
DFIMAGE *Imagey;
double br,r2,ih2;
ih2 = 1./(h*h);
xpmin = xp - hint; if (xpmin<0) xpmin=0;
xpmax = xp + hint; if (xpmax>=in->nxPix) xpmax=in->nxPix-1;
ypmin = yp - hint; if (ypmin<0) ypmin=0;
ypmax = yp + hint; if (ypmax>=in->nyPix) ypmax=in->nyPix-1;
for (iy=ypmin,Imagey = Image + iy*in->nxPix;iy<=ypmax;iy++,Imagey += in->nxPix) {
for (ix=xpmin;ix<=xpmax;ix++) {
if (ix==xp && iy==yp) {
br = br0*(1.57080-1.04720/h); /* Integral of tsc disc to r=1 */
}
else {
r2 = ((ix-xp)*(ix-xp)+(iy-yp)*(iy-yp))*ih2;
if (r2 > 1) continue;
br = br0*(1.0-sqrt(r2));
}
Imagey[ ix ].r += br*col.r;
Imagey[ ix ].g += br*col.g;
Imagey[ ix ].b += br*col.b;
}
}
}
}
}
}
}
void dfMergeImage( struct inDumpFrame *in, void *vImage1, int *nImage1, void *vImage2, int *nImage2 ) {
int i;
DFIMAGE *Image1 = (DFIMAGE *)vImage1, *Image2 = (DFIMAGE *)vImage2;
switch (in->iRender) {
case DF_RENDER_POINT:
case DF_RENDER_TSC:
case DF_RENDER_SOLID:
CkAssert( *nImage1 == in->nxPix*in->nyPix*sizeof(DFIMAGE) );
CkAssert( *nImage1 == *nImage2 );
for (i=in->nxPix*in->nyPix-1;i>=0;i--) {
Image1[i].r += Image2[i].r;
Image1[i].g += Image2[i].g;
Image1[i].b += Image2[i].b;
}
break;
case DF_RENDER_SHINE:
CkAssert( *nImage1 == in->nxPix*in->nyPix*sizeof(DFIMAGE) );
CkAssert( *nImage1 == *nImage2 );
for (i=in->nxPix*in->nyPix-1;i>=0;i--) {
if (Image2[i].r > Image1[i].r) Image1[i].r = Image2[i].r;
if (Image2[i].g > Image1[i].g) Image1[i].g = Image2[i].g;
if (Image2[i].b > Image1[i].b) Image1[i].b = Image2[i].b;
}
break;
default:
break;
}
}
void dfFinishFrame( struct DumpFrameContext *df, double dTime, double dStep, struct inDumpFrame *in, void *vImage, int liveViz, unsigned char **outgray) {
DFIMAGE *Image = (DFIMAGE *) vImage;
char fileout[160];
FILE *fp;
int i;
int iMax;
unsigned char *g;
unsigned char *gray;
/*char number[40]; -- not used: DCR 12/19/02*/
iMax = in->nxPix*in->nyPix;
gray = (unsigned char *) malloc(sizeof(unsigned char)*3*iMax);
CkAssert( gray != NULL );
*outgray = gray;
if (df->bVDetails) {
double min = 1e38;
double max = 0.0;
for(i = 0; i < iMax; i++) {
if(Image[i].r > max) max = Image[i].r;
if(Image[i].r < min) min = Image[i].r;
if(Image[i].g > max) max = Image[i].g;
if(Image[i].g < min) min = Image[i].g;
if(Image[i].b > max) max = Image[i].b;
if(Image[i].b < min) min = Image[i].b;
}
CkPrintf("DF image range: %g to %g\n", min, max);
}
if (in->iRender == DF_RENDER_POINT) {
for (i=0,g=gray;i<iMax;i++) {
if ( Image[i].r > 0.0 ) {
*g=255; g++;
*g=255; g++;
*g=255; g++;
}
else {
*g=0; g++;
*g=0; g++;
*g=0; g++;
}
}
}
else if (in->iRender == DF_RENDER_TSC || in->iRender == DF_RENDER_SOLID || in->iRender == DF_RENDER_SHINE) {
if (in->iLogScale == DF_LOG_COLOURSAFE) {
double lmin,factor;
lmin = log(in->pScale1);
factor = 255.999/(log(in->pScale2)-lmin);
for (i=0,g=gray;i<iMax;i++) {
int bing;
float tot = Image[i].r;
if (Image[i].g > tot) tot = Image[i].g;
if (Image[i].b > tot) tot = Image[i].b;
if (tot <= 0) {
*g = 0; g++;
*g = 0; g++;
*g = 0; g++;
}
else {
tot = factor/tot*(log(tot)-lmin);
bing = Image[i].r*tot;
*g = (bing < 255 ? (bing < 0 ? 0 : bing) : 255 );
g++;
bing = Image[i].g*tot;
*g = (bing < 255 ? (bing < 0 ? 0 : bing) : 255 );
g++;
bing = Image[i].b*tot;
*g = (bing < 255 ? (bing < 0 ? 0 : bing) : 255 );
g++;
}
}
}
else if (in->iLogScale == DF_LOG_SATURATE) {
double lmin,factor;
lmin = log(in->pScale1);
factor = 255.999/(log(in->pScale2)-lmin);
for (i=0,g=gray;i<iMax;i++) {
int bing;
if (Image[i].r <= 0) *g = 0;
else {
bing = factor*(log(Image[i].r)-lmin);
*g = (bing < 255 ? (bing < 0 ? 0 : bing) : 255 );
}
g++;
if (Image[i].g <= 0) *g = 0;
else {
bing = factor*(log(Image[i].g)-lmin);
*g = (bing < 255 ? (bing < 0 ? 0 : bing) : 255 );
}
g++;
if (Image[i].b <= 0) *g = 0;
else {
bing = factor*(log(Image[i].b)-lmin);
*g = (bing < 255 ? (bing < 0 ? 0 : bing) : 255 );
}
g++;
}
}
else {
for (i=0,g=gray;i<iMax;i++) {
int bing;
bing = 260*(1.-1./(0.1*Image[i].r+1));
*g = (bing < 255 ? bing : 255 );
g++;
bing = 260*(1.-1./(0.1*Image[i].g+1));
*g = (bing < 255 ? bing : 255 );
g++;
bing = 260*(1.-1./(0.1*Image[i].b+1));
*g = (bing < 255 ? bing : 255 );
g++;
}
}
}
if(!liveViz) {
switch( df->iNumbering ) {
case DF_NUMBERING_FRAME:
sprintf(fileout, df->FileName, df->nFrame );
break;
case DF_NUMBERING_STEP:
sprintf(fileout, df->FileName, dStep );
break;
case DF_NUMBERING_TIME:
sprintf(fileout, df->FileName, dTime );
break;
}
df->nFrame++; /* NB: need to sort out something for restarts */
fp = CmiFopen(fileout,"w");
if(fp == NULL) {
fprintf(stderr, "Bad Frame file open: %s\n", fileout);
if(errno == ENOENT)
fprintf(stderr, "directory of %s does not exist\n", fileout);
}
CkAssert(fp!=NULL);
if (df->iEncode == DF_ENCODE_PPM) {
fprintf(fp,"P6\n#T=%20.10f\n%5i %5i\n255\n",dTime,in->nxPix,in->nyPix);
CmiFwrite( gray, 3*iMax, sizeof(char), fp);
}
else if (df->iEncode == DF_ENCODE_PNG) {
#ifdef USE_PNG
static mainprog_info wpng_info;
int rowbytes;
int iErr;
wpng_info.outfile = fp;
wpng_info.infile = NULL;
wpng_info.image_data = gray;
wpng_info.pnmtype = 6; /* RGB */
wpng_info.sample_depth = 8; /* <==> maxval 255 */
wpng_info.width = in->nxPix;
wpng_info.height = in->nyPix;
rowbytes = 3*wpng_info.width; /* 8 bit RGB */
wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));
wpng_info.filter = FALSE;
wpng_info.interlaced = FALSE;
wpng_info.have_bg = FALSE;
wpng_info.have_time = FALSE;
wpng_info.have_text = 0;
wpng_info.gamma = 0.0;
iErr = writepng_init(&wpng_info);
CkAssert (!iErr);
for (i = 0; i < wpng_info.height; ++i)
wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes;
iErr = writepng_encode_image(&wpng_info);
CkAssert (!iErr);
writepng_cleanup(&wpng_info);
#endif
}
CmiFclose(fp);
if (df->dDumpFrameTime > 0 && dTime >= df->dTime)
df->dTime = df->dTime + df->dDumpFrameTime;
if (df->dDumpFrameStep > 0 && dStep >= df->dStep)
df->dStep = df->dStep + df->dDumpFrameStep;
free(gray);
}
}