Skip to content

Commit cca16f1

Browse files
committed
Several minor fixes.
1 parent 7f9cda5 commit cca16f1

File tree

8 files changed

+81
-43
lines changed

8 files changed

+81
-43
lines changed

doc/usermanual.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ thousands and about ten thousand.
321321
322322
If this is left at the default value of 0, grid point sampling is performed according to the LIME<1.7 algorithm, as governed by parameter :ref:`par->sampling <par-sampling>`. If 1 is chosen, a new algorithm is employed which can quickly generate points with a distribution which accurately follows any feasible :ref:`gridDensity <grid-density>` function - including with sharp step-changes. This algorithm also incorporates a quasi-random choice of point candidates which avoids the requirement for the relatively time-consuming post-gridding smoothing phase.
323323

324+
A user who selects par->samplingAlgorithm=1 and constructs their own :ref:`gridDensity <grid-density>` function obtains full control over the distribution of points. With this control however come some hazards. LIME still relies on 3rd-party software called qhull to triangulate the points after they are chosen, and qhull is a little flaky. It is prone to failing silently if it doesn't like the set of points one gives it. We have tried to trap these instances, to at least head off segmentation faults, but it is hard to guess all the ways in which somebody else's package may fail. If you have problems, try to smooth out any steps in your :ref:`gridDensity <grid-density>` function. If that doesn't fix things, you may have to go back to par->samplingAlgorithm=0.
325+
324326
.. _par-sampling:
325327

326328
.. code:: c

src/aux.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,13 @@ exit(1);
723723
exit(1);
724724
}
725725

726+
if(!silent && !par->doMolCalcs && par->init_lte)
727+
warning("Your choice of par.init_lte will have no effect.");
728+
if(!silent && !par->doMolCalcs && par->lte_only)
729+
warning("Your choice of par.lte_only will have no effect.");
730+
if(!silent && par->nSolveIters>0 && par->lte_only)
731+
warning("Requesting par.nSolveIters>0 will have no effect if LTE calculation is also requested.");
732+
726733
/* Allocate moldata array.
727734
*/
728735
if(par->nSpecies>0){

src/grid.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,14 @@ Elements of structs are set as follows:
419419
gp[id].numNeigh=qh_setsize(vertex->neighbors);
420420
/* Note that vertex->neighbors refers to facets abutting the vertex, not other vertices. In general there seem to be more facets surrounding a point than vertices (in fact there seem to be exactly 2x as many). In any case, mallocing to N_facets gives extra room. */
421421

422+
if(gp[id].numNeigh<=0){
423+
if(!silent){
424+
sprintf(message, "qhull failed silently, grid point %lu has 0 neighbours. Smoother gridDensity() might help.", id);
425+
bail_out(message);
426+
}
427+
exit(1);
428+
}
429+
422430
free(gp[id].neigh);
423431
gp[id].neigh=malloc(sizeof(struct grid *)*gp[id].numNeigh);
424432
for(k=0;k<gp[id].numNeigh;k++) {
@@ -498,7 +506,7 @@ Elements of structs are set as follows:
498506
sprintf(message, "Something weird going on. Cannot find a cell with ID %lu", (unsigned long)(neighbor->id));
499507
bail_out(message);
500508
}
501-
exit(1);
509+
exit(1);
502510
}
503511
}
504512
i++;
@@ -1080,7 +1088,7 @@ exit(1);
10801088
exit(1);
10811089
}
10821090
if(gridInfoRead.nSpecies > 0){
1083-
if((int)gridInfoRead.nSpecies!=par->nSpecies){
1091+
if((int)gridInfoRead.nSpecies!=par->nSpecies && par->doMolCalcs){
10841092
if(!silent){
10851093
sprintf(message, "Grid file had %d species but you have provided moldata files for %d."\
10861094
, (int)gridInfoRead.nSpecies, par->nSpecies);
@@ -1098,6 +1106,9 @@ exit(1);
10981106
}
10991107
exit(1);
11001108
}
1109+
1110+
if(!silent && par->nSolveItersDone>0 && (par->init_lte || par->lte_only))
1111+
warning("Your choice of LTE calculation will erase the RTE solution you read from file.");
11011112
}
11021113

11031114
/*....................................................................*/
@@ -1155,10 +1166,10 @@ readOrBuildGrid(configInfo *par, struct grid **gp){
11551166
status = readGrid(par->gridInFile, &gridInfoRead, desiredKwds\
11561167
, numDesiredKwds, gp, &collPartNames, &numCollPartRead, &(par->dataFlags));
11571168

1158-
sanityCheckOfRead(status, par, gridInfoRead);
1159-
11601169
par->nSolveItersDone = desiredKwds[1].intValue;
11611170

1171+
sanityCheckOfRead(status, par, gridInfoRead);
1172+
11621173
freeKeywords(desiredKwds, numDesiredKwds);
11631174
freeGridInfo(&gridInfoRead);
11641175

@@ -1373,7 +1384,8 @@ Generate the remaining values if needed.
13731384
par->dataFlags |= DS_mask_density;
13741385
}
13751386

1376-
checkGridDensities(par, *gp); /* Check that none of the density samples is too small. */
1387+
if(par->doMolCalcs)
1388+
checkGridDensities(par, *gp); /* Check that none of the density samples is too small. */
13771389

13781390
if(!allBitsSet(par->dataFlags, DS_mask_temperatures)){
13791391
for(i=0;i<par->pIntensity;i++)

src/lime.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,6 @@ typedef struct {
258258
_Bool doInterpolateVels;
259259
} imageInfo;
260260

261-
typedef struct {
262-
double x,y, *intensity, *tau;
263-
unsigned int ppi;
264-
} rayData;
265-
266261
struct blend{
267262
int molJ, lineJ;
268263
double deltaV;
@@ -364,7 +359,7 @@ void lineBlend(molData*, configInfo*, struct blendInfo*);
364359
void LTE(configInfo*, struct grid*, molData*);
365360
void lteOnePoint(molData*, const int, const double, double*);
366361
void mallocAndSetDefaultGrid(struct grid**, const size_t, const size_t);
367-
void molInit(configInfo*, molData*, int*, const int);
362+
void molInit(configInfo*, molData*);
368363
void openSocket(char*);
369364
void parseInput(inputPars, image*, const int, configInfo*, imageInfo**, molData**);
370365
void photon(int, struct grid*, molData*, const gsl_rng*, configInfo*, const int, struct blendInfo, gridPointData*, double*);
@@ -377,7 +372,6 @@ void processFitsError(int);
377372
double ratranInput(char*, char*, double, double, double);
378373
void raytrace(int, configInfo*, struct grid*, molData*, imageInfo*, double*, double*, const int);
379374
void readDustFile(char*, double**, double**, int*);
380-
void readMolData(configInfo*, molData*, int**, int*);
381375
void readOrBuildGrid(configInfo*, struct grid**);
382376
void readUserInput(inputPars*, imageInfo**, int*, int*);
383377
unsigned long reorderGrid(const unsigned long, struct grid*);

src/main.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,6 @@ run(inputPars inpars, image *inimg, const int nImages){
169169
char message[80];
170170
int nEntries=0;
171171
double *lamtab=NULL,*kaptab=NULL;
172-
int *allUniqueCollPartIds=NULL;
173-
int numUniqueCollPartsFound;
174172

175173
/*Set locale to avoid trouble when reading files*/
176174
setlocale(LC_ALL, "C");
@@ -215,16 +213,13 @@ run(inputPars inpars, image *inimg, const int nImages){
215213
}
216214
}
217215

218-
if(!popsdone)
219-
readMolData(&par, md, &allUniqueCollPartIds, &numUniqueCollPartsFound);
220-
221216
if(par.doMolCalcs){
222217
if(!popsdone){
223-
molInit(&par, md, allUniqueCollPartIds, numUniqueCollPartsFound);
218+
molInit(&par, md);
224219
calcGridMolDoppler(&par, md, gp);
225220
}
226221
if(par.useAbun)
227-
calcGridMolDensities(&par,&gp);
222+
calcGridMolDensities(&par, &gp);
228223

229224
for(gi=0;gi<par.ncell;gi++){
230225
for(si=0;si<par.nSpecies;si++)
@@ -240,8 +235,6 @@ run(inputPars inpars, image *inimg, const int nImages){
240235
par.nSolveItersDone = par.nSolveIters;
241236
}
242237

243-
free(allUniqueCollPartIds);
244-
245238
if(onlyBitsSet(par.dataFlags & DS_mask_all_but_mag, DS_mask_3))
246239
writeGridIfRequired(&par, gp, NULL, 3);
247240
else if(onlyBitsSet(par.dataFlags & DS_mask_all_but_mag, DS_mask_5)){

src/molinit.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,15 @@ void setUpGir(configInfo *par, molData *md){
309309
}
310310

311311
/*....................................................................*/
312-
void molInit(configInfo *par, molData *md, int *allUniqueCollPartIds, const int numUniqueCollPartsFound){
312+
void molInit(configInfo *par, molData *md){
313313
int i,j,jStart,numActiveCollParts;
314314
char partstr[90];
315+
int *allUniqueCollPartIds=NULL;
316+
int numUniqueCollPartsFound;
315317

318+
readMolData(par, md, &allUniqueCollPartIds, &numUniqueCollPartsFound);
316319
setUpDensityAux(par, allUniqueCollPartIds, numUniqueCollPartsFound);
320+
317321
if(par->girdatfile!=NULL){
318322
setUpGir(par, md);
319323
}
@@ -358,5 +362,6 @@ void molInit(configInfo *par, molData *md, int *allUniqueCollPartIds, const int
358362
}
359363

360364
calcMolCMBs(par, md);
365+
free(allUniqueCollPartIds);
361366
}
362367

src/predefgrid.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ predefinedGrid(configInfo *par, struct grid *gp){
5757
if(!silent) progressbar((double) i/((double)par->pIntensity-1), 4);
5858
}
5959

60-
checkGridDensities(par, gp);
60+
fclose(fp);
61+
if(!silent) printDone(4);
62+
63+
if(par->doMolCalcs)
64+
checkGridDensities(par, gp);
6165

6266
for(i=par->pIntensity;i<par->ncell;i++){
6367
x=2*gsl_rng_uniform(ran)-1.;
@@ -82,7 +86,6 @@ predefinedGrid(configInfo *par, struct grid *gp){
8286
for(j=0;j<DIM;j++) gp[i].vel[j]=0.;
8387
} else i--;
8488
}
85-
fclose(fp);
8689

8790
delaunay(DIM, gp, (unsigned long)par->ncell, 0, 1, &dc, &numCells);
8891

src/raytrace.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
#include "lime.h"
1414
#include "raythrucells.h"
1515

16+
typedef struct {
17+
double x,y, *intensity, *tau;
18+
unsigned int ppi;
19+
_Bool isInsideImage;
20+
} rayData;
21+
1622
struct baryVelBuffType {
1723
int numVertices,numEdges,(*edgeVertexIndices)[2];
1824
double **vertexVels,**edgeVels,*entryCellBary,*midCellBary,*exitCellBary,*shapeFns;
@@ -844,8 +850,31 @@ At the moment I will fix the number of segments, but it might possibly be faster
844850
}
845851

846852
/*....................................................................*/
847-
void
853+
_Bool
848854
locateRayOnImage(double x[2], const double size, const double imgCentreXPixels\
855+
, const double imgCentreYPixels, imageInfo *img, const int im\
856+
, int *xi, int *yi, unsigned int *ppi){
857+
858+
_Bool isInsideImage;
859+
860+
/* Calculate which pixel the projected position (x[0],x[1]) falls within.
861+
*/
862+
*xi = floor(x[0]/size + imgCentreXPixels);
863+
*yi = floor(x[1]/size + imgCentreYPixels);
864+
if(*xi<0 || *xi>=img[im].pxls || *yi<0 || *yi>=img[im].pxls){
865+
isInsideImage = 0;
866+
*ppi = 0; /* Under these circumstances it ought never to be accessed, but it is not good to leave it without a value at all. */
867+
}else{
868+
isInsideImage = 1;
869+
*ppi = (unsigned int)(*yi)*(unsigned int)img[im].pxls + (unsigned int)(*xi);
870+
}
871+
872+
return isInsideImage;
873+
}
874+
875+
/*....................................................................*/
876+
void
877+
assignRayOnImage(double x[2], const double size, const double imgCentreXPixels\
849878
, const double imgCentreYPixels, imageInfo *img, const int im\
850879
, const int maxNumRaysPerPixel, rayData *rays, int *numActiveRays){
851880
/*
@@ -863,27 +892,19 @@ Returned information is thus:
863892
*/
864893

865894
int xi,yi,ichan;
866-
_Bool isOutsideImage;
895+
_Bool isInsideImage;
867896
unsigned int ppi;
868897

869-
/* Calculate which pixel the projected position (x[0],x[1]) falls within.
870-
*/
871-
xi = floor(x[0]/size + imgCentreXPixels);
872-
yi = floor(x[1]/size + imgCentreYPixels);
873-
if(xi<0 || xi>=img[im].pxls || yi<0 || yi>=img[im].pxls){
874-
isOutsideImage = 1;
875-
ppi = 0; /* Under these circumstances it ought never to be accessed, but it is not good to leave it without a value at all. */
876-
}else{
877-
isOutsideImage = 0;
878-
ppi = (unsigned int)yi*(unsigned int)img[im].pxls + (unsigned int)xi;
879-
}
898+
isInsideImage = locateRayOnImage(x, size, imgCentreXPixels\
899+
, imgCentreYPixels, img, im, &xi, &yi, &ppi);
880900

881-
/* See if we want to keep the ray. For the time being we will include those outside the image bounds, but a cleverer algorithm would exclude some of them. Note that maxNumRaysPerPixel<1 is used to flag that there is no upper limit to the number of rays per pixel.
901+
/* See if we want to keep the ray. For the time being we will include those outside the image bounds, because we need to interpolate between outside-image rays and inside-image ones, but a cleverer algorithm would exclude all but those which are affected by this (i.e. that immediately abut the image bounds). Note that maxNumRaysPerPixel<1 is used to flag that there is no upper limit to the number of rays per pixel.
882902
*/
883-
if(isOutsideImage || maxNumRaysPerPixel<1 || img[im].pixel[ppi].numRays<maxNumRaysPerPixel){
884-
if(!isOutsideImage)
903+
if(!isInsideImage || maxNumRaysPerPixel<1 || img[im].pixel[ppi].numRays<maxNumRaysPerPixel){
904+
if(isInsideImage)
885905
img[im].pixel[ppi].numRays++;
886906

907+
rays[*numActiveRays].isInsideImage = isInsideImage;
887908
rays[*numActiveRays].ppi = ppi;
888909
rays[*numActiveRays].x = x[0];
889910
rays[*numActiveRays].y = x[1];
@@ -1221,7 +1242,7 @@ How to calculate this distance? Well if we have N points randomly but evenly dis
12211242
}
12221243
}
12231244

1224-
locateRayOnImage(xs, pixelSize, imgCentreXPixels, imgCentreYPixels, img, im, maxNumRaysPerPixel, rays, &numActiveRaysInternal);
1245+
assignRayOnImage(xs, pixelSize, imgCentreXPixels, imgCentreYPixels, img, im, maxNumRaysPerPixel, rays, &numActiveRaysInternal);
12251246
} /* End loop 1, over grid points. */
12261247

12271248
/* Add the circle rays:
@@ -1233,7 +1254,7 @@ How to calculate this distance? Well if we have N points randomly but evenly dis
12331254
angle = i*scale;
12341255
xs[0] = par->radius*cos(angle);
12351256
xs[1] = par->radius*sin(angle);
1236-
locateRayOnImage(xs, pixelSize, imgCentreXPixels, imgCentreYPixels, img, im, maxNumRaysPerPixel, rays, &numActiveRays);
1257+
assignRayOnImage(xs, pixelSize, imgCentreXPixels, imgCentreYPixels, img, im, maxNumRaysPerPixel, rays, &numActiveRays);
12371258
}
12381259
}
12391260
oneOnNumActiveRaysMinus1 = 1.0/(double)(numActiveRaysInternal-1);
@@ -1362,6 +1383,7 @@ While this is off however, gsl_* calls will not exit if they encounter a problem
13621383
} /* End of parallel block. */
13631384

13641385
gsl_set_error_handler(defaultErrorHandler);
1386+
if(!silent) printDone(13);
13651387

13661388
if(par->traceRayAlgorithm==1){
13671389
free(cells);
@@ -1393,7 +1415,7 @@ While this is off however, gsl_* calls will not exit if they encounter a problem
13931415
/* For pixels with more than a cutoff number of rays, just average those rays into the pixel:
13941416
*/
13951417
for(ri=0;ri<numActiveRays;ri++){
1396-
if(img[im].pixel[rays[ri].ppi].numRays >= minNumRaysForAverage){
1418+
if(rays[ri].isInsideImage && img[im].pixel[rays[ri].ppi].numRays >= minNumRaysForAverage){
13971419
for(ichan=0;ichan<img[im].nchan;ichan++){
13981420
img[im].pixel[rays[ri].ppi].intense[ichan] += rays[ri].intensity[ichan];
13991421
img[im].pixel[rays[ri].ppi].tau[ ichan] += rays[ri].tau[ ichan];

0 commit comments

Comments
 (0)