File: | src/pull/pointPull.c |
Location: | line 1320, column 5 |
Description: | Value stored to 'point' is never read |
1 | /* |
2 | Teem: Tools to process and visualize scientific data and images . |
3 | Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago |
4 | Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann |
5 | Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Lesser General Public License |
9 | (LGPL) as published by the Free Software Foundation; either |
10 | version 2.1 of the License, or (at your option) any later version. |
11 | The terms of redistributing and/or modifying this software also |
12 | include exceptions to the LGPL that facilitate static linking. |
13 | |
14 | This library is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | Lesser General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Lesser General Public License |
20 | along with this library; if not, write to Free Software Foundation, Inc., |
21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | */ |
23 | |
24 | |
25 | #include "pull.h" |
26 | #include "privatePull.h" |
27 | |
28 | #define DEBUG1 1 |
29 | |
30 | /* |
31 | ** HEY: this has to be threadsafe, at least threadsafe when there |
32 | ** are no errors, because this can now be called from multiple |
33 | ** tasks during population control |
34 | */ |
35 | pullPoint * |
36 | pullPointNew(pullContext *pctx) { |
37 | static const char me[]="pullPointNew"; |
38 | pullPoint *pnt; |
39 | unsigned int ii; |
40 | size_t pntSize; |
41 | pullPtrPtrUnion pppu; |
42 | |
43 | if (!pctx) { |
44 | biffAddf(PULLpullBiffKey, "%s: got NULL pointer", me); |
45 | return NULL((void*)0); |
46 | } |
47 | if (!pctx->infoTotalLen) { |
48 | biffAddf(PULLpullBiffKey, "%s: can't allocate points w/out infoTotalLen set\n", me); |
49 | return NULL((void*)0); |
50 | } |
51 | /* Allocate the pullPoint so that it has pctx->infoTotalLen doubles. |
52 | The pullPoint declaration has info[1], hence the "- 1" below */ |
53 | pntSize = sizeof(pullPoint) + sizeof(double)*(pctx->infoTotalLen - 1); |
54 | pnt = AIR_CAST(pullPoint *, calloc(1, pntSize))((pullPoint *)(calloc(1, pntSize))); |
55 | if (!pnt) { |
56 | biffAddf(PULLpullBiffKey, "%s: couldn't allocate point (info len %u)\n", me, |
57 | pctx->infoTotalLen - 1); |
58 | return NULL((void*)0); |
59 | } |
60 | |
61 | pnt->idtag = pctx->idtagNext++; |
62 | pnt->idCC = 0; |
63 | pnt->neighPoint = NULL((void*)0); |
64 | pnt->neighPointNum = 0; |
65 | pppu.points = &(pnt->neighPoint); |
66 | pnt->neighPointArr = airArrayNew(pppu.v, &(pnt->neighPointNum), |
67 | sizeof(pullPoint *), |
68 | PULL_POINT_NEIGH_INCR16); |
69 | pnt->neighPointArr->noReallocWhenSmaller = AIR_TRUE1; |
70 | pnt->neighDistMean = 0; |
71 | ELL_10V_ZERO_SET(pnt->neighCovar)((pnt->neighCovar)[0]=0, (pnt->neighCovar)[1]=0, (pnt-> neighCovar)[2]=0, (pnt->neighCovar)[3]=0, (pnt->neighCovar )[4]=0, (pnt->neighCovar)[5]=0, (pnt->neighCovar)[6]=0, (pnt->neighCovar)[7]=0, (pnt->neighCovar)[8]=0, (pnt-> neighCovar)[9]=0); |
72 | pnt->stability = 0.0; |
73 | #if PULL_TANCOVAR1 |
74 | ELL_6V_ZERO_SET(pnt->neighTanCovar)((pnt->neighTanCovar)[0]=(0), (pnt->neighTanCovar)[1]=( 0), (pnt->neighTanCovar)[2]=(0), (pnt->neighTanCovar)[3 ]=(0), (pnt->neighTanCovar)[4]=(0), (pnt->neighTanCovar )[5]=(0)); |
75 | #endif |
76 | pnt->neighInterNum = 0; |
77 | pnt->stuckIterNum = 0; |
78 | #if PULL_PHIST0 |
79 | pnt->phist = NULL((void*)0); |
80 | pnt->phistNum = 0; |
81 | pnt->phistArr = airArrayNew(AIR_CAST(void**, &(pnt->phist))((void**)(&(pnt->phist))), |
82 | &(pnt->phistNum), |
83 | _PHN6*sizeof(double), 32); |
84 | #endif |
85 | pnt->status = 0; |
86 | ELL_4V_SET(pnt->pos, AIR_NAN, AIR_NAN, AIR_NAN, AIR_NAN)((pnt->pos)[0] = ((airFloatQNaN.f)), (pnt->pos)[1] = (( airFloatQNaN.f)), (pnt->pos)[2] = ((airFloatQNaN.f)), (pnt ->pos)[3] = ((airFloatQNaN.f))); |
87 | pnt->energy = AIR_NAN(airFloatQNaN.f); |
88 | ELL_4V_SET(pnt->force, AIR_NAN, AIR_NAN, AIR_NAN, AIR_NAN)((pnt->force)[0] = ((airFloatQNaN.f)), (pnt->force)[1] = ((airFloatQNaN.f)), (pnt->force)[2] = ((airFloatQNaN.f)), (pnt->force)[3] = ((airFloatQNaN.f))); |
89 | pnt->stepEnergy = pctx->sysParm.stepInitial; |
90 | pnt->stepConstr = pctx->sysParm.stepInitial; |
91 | for (ii=0; ii<pctx->infoTotalLen; ii++) { |
92 | pnt->info[ii] = AIR_NAN(airFloatQNaN.f); |
93 | } |
94 | return pnt; |
95 | } |
96 | |
97 | pullPoint * |
98 | pullPointNix(pullPoint *pnt) { |
99 | |
100 | pnt->neighPointArr = airArrayNuke(pnt->neighPointArr); |
101 | #if PULL_PHIST0 |
102 | pnt->phistArr = airArrayNuke(pnt->phistArr); |
103 | #endif |
104 | airFree(pnt); |
105 | return NULL((void*)0); |
106 | } |
107 | |
108 | #if PULL_PHIST0 |
109 | void |
110 | _pullPointHistInit(pullPoint *point) { |
111 | |
112 | airArrayLenSet(point->phistArr, 0); |
113 | return; |
114 | } |
115 | |
116 | void |
117 | _pullPointHistAdd(pullPoint *point, int cond, double val) { |
118 | static const char me[]="_pullPointHistAdd"; |
119 | unsigned int phistIdx; |
120 | |
121 | phistIdx = airArrayLenIncr(point->phistArr, 1); |
122 | ELL_4V_COPY(point->phist + _PHN*phistIdx, point->pos)((point->phist + 6*phistIdx)[0] = (point->pos)[0], (point ->phist + 6*phistIdx)[1] = (point->pos)[1], (point-> phist + 6*phistIdx)[2] = (point->pos)[2], (point->phist + 6*phistIdx)[3] = (point->pos)[3]); |
123 | |
124 | fprintf(stderr__stderrp, "!%s: point %p pos = %.17g %.17g %.17g %.17g (%g)\n", me, |
125 | point, point->pos[0], point->pos[1], point->pos[2], point->pos[3], |
126 | val); |
127 | |
128 | (point->phist + _PHN6*phistIdx)[4] = cond; |
129 | (point->phist + _PHN6*phistIdx)[5] = val; |
130 | return; |
131 | } |
132 | #endif |
133 | |
134 | /* |
135 | ** HEY: there should be something like a "map" over all the points, |
136 | ** which could implement all these redundant functions |
137 | */ |
138 | |
139 | unsigned int |
140 | pullPointNumberFilter(const pullContext *pctx, |
141 | unsigned int idtagMin, |
142 | unsigned int idtagMax) { |
143 | unsigned int binIdx, pointNum; |
144 | const pullBin *bin; |
145 | const pullPoint *point; |
146 | |
147 | pointNum = 0; |
148 | for (binIdx=0; binIdx<pctx->binNum; binIdx++) { |
149 | unsigned int pointIdx; |
150 | bin = pctx->bin + binIdx; |
151 | if (0 == idtagMin && 0 == idtagMax) { |
152 | pointNum += bin->pointNum; |
153 | } else { |
154 | for (pointIdx=0; pointIdx<bin->pointNum; pointIdx++) { |
155 | point = bin->point[pointIdx]; |
156 | pointNum += (idtagMin <= point->idtag |
157 | && (0 == idtagMax |
158 | || point->idtag <= idtagMax)); |
159 | } |
160 | } |
161 | } |
162 | return pointNum; |
163 | } |
164 | |
165 | unsigned int |
166 | pullPointNumber(const pullContext *pctx) { |
167 | |
168 | return pullPointNumberFilter(pctx, 0, 0); |
169 | } |
170 | |
171 | double |
172 | _pullEnergyTotal(const pullContext *pctx) { |
173 | unsigned int binIdx, pointIdx; |
174 | const pullBin *bin; |
175 | const pullPoint *point; |
176 | double sum; |
177 | |
178 | sum = 0; |
179 | for (binIdx=0; binIdx<pctx->binNum; binIdx++) { |
180 | bin = pctx->bin + binIdx; |
181 | for (pointIdx=0; pointIdx<bin->pointNum; pointIdx++) { |
182 | point = bin->point[pointIdx]; |
183 | sum += point->energy; |
184 | } |
185 | } |
186 | return sum; |
187 | } |
188 | |
189 | void |
190 | _pullPointStepEnergyScale(pullContext *pctx, double scale) { |
191 | unsigned int binIdx, pointIdx; |
192 | const pullBin *bin; |
193 | pullPoint *point; |
194 | |
195 | for (binIdx=0; binIdx<pctx->binNum; binIdx++) { |
196 | bin = pctx->bin + binIdx; |
197 | for (pointIdx=0; pointIdx<bin->pointNum; pointIdx++) { |
198 | point = bin->point[pointIdx]; |
199 | point->stepEnergy *= scale; |
200 | point->stepEnergy = AIR_MIN(point->stepEnergy,((point->stepEnergy) < (3.40282347e+38F) ? (point->stepEnergy ) : (3.40282347e+38F)) |
201 | _PULL_STEP_ENERGY_MAX)((point->stepEnergy) < (3.40282347e+38F) ? (point->stepEnergy ) : (3.40282347e+38F)); |
202 | } |
203 | } |
204 | return; |
205 | } |
206 | |
207 | double |
208 | _pullStepInterAverage(const pullContext *pctx) { |
209 | unsigned int binIdx, pointIdx, pointNum; |
210 | const pullBin *bin; |
211 | const pullPoint *point; |
212 | double sum, avg; |
213 | |
214 | sum = 0; |
215 | pointNum = 0; |
216 | for (binIdx=0; binIdx<pctx->binNum; binIdx++) { |
217 | bin = pctx->bin + binIdx; |
218 | pointNum += bin->pointNum; |
219 | for (pointIdx=0; pointIdx<bin->pointNum; pointIdx++) { |
220 | point = bin->point[pointIdx]; |
221 | sum += point->stepEnergy; |
222 | } |
223 | } |
224 | avg = (!pointNum ? AIR_NAN(airFloatQNaN.f) : sum/pointNum); |
225 | return avg; |
226 | } |
227 | /* ^^^ vvv HEY HEY HEY: COPY + PASTE COPY + PASTE COPY + PASTE */ |
228 | double |
229 | _pullStepConstrAverage(const pullContext *pctx) { |
230 | unsigned int binIdx, pointIdx, pointNum; |
231 | const pullBin *bin; |
232 | const pullPoint *point; |
233 | double sum, avg; |
234 | |
235 | sum = 0; |
236 | pointNum = 0; |
237 | for (binIdx=0; binIdx<pctx->binNum; binIdx++) { |
238 | bin = pctx->bin + binIdx; |
239 | pointNum += bin->pointNum; |
240 | for (pointIdx=0; pointIdx<bin->pointNum; pointIdx++) { |
241 | point = bin->point[pointIdx]; |
242 | sum += point->stepConstr; |
243 | } |
244 | } |
245 | avg = (!pointNum ? AIR_NAN(airFloatQNaN.f) : sum/pointNum); |
246 | return avg; |
247 | } |
248 | |
249 | /* |
250 | ** convenience function for learning a scalar AND its gradient or hessian |
251 | ** |
252 | */ |
253 | double |
254 | pullPointScalar(const pullContext *pctx, const pullPoint *point, int sclInfo, |
255 | /* output */ |
256 | double grad[3], double hess[9]) { |
257 | static const char me[]="pullPointScalar"; |
258 | double scl; |
259 | const pullInfoSpec *ispec; |
260 | int gradInfo[1+PULL_INFO_MAX23] = { |
261 | 0, /* pullInfoUnknown */ |
262 | 0, /* pullInfoTensor */ |
263 | 0, /* pullInfoTensorInverse */ |
264 | 0, /* pullInfoHessian */ |
265 | pullInfoInsideGradient, /* pullInfoInside */ |
266 | 0, /* pullInfoInsideGradient */ |
267 | pullInfoHeightGradient, /* pullInfoHeight */ |
268 | 0, /* pullInfoHeightGradient */ |
269 | 0, /* pullInfoHeightHessian */ |
270 | 0, /* pullInfoHeightLaplacian */ |
271 | 0, /* pullInfoSeedPreThresh */ |
272 | 0, /* pullInfoSeedThresh */ |
273 | 0, /* pullInfoLiveThresh */ |
274 | 0, /* pullInfoLiveThresh2 */ |
275 | 0, /* pullInfoLiveThresh3 */ |
276 | 0, /* pullInfoTangent1 */ |
277 | 0, /* pullInfoTangent2 */ |
278 | 0, /* pullInfoNegativeTangent1 */ |
279 | 0, /* pullInfoNegativeTangent2 */ |
280 | pullInfoIsovalueGradient, /* pullInfoIsovalue */ |
281 | 0, /* pullInfoIsovalueGradient */ |
282 | 0, /* pullInfoIsovalueHessian */ |
283 | 0, /* pullInfoStrength */ |
284 | }; |
285 | int hessInfo[1+PULL_INFO_MAX23] = { |
286 | 0, /* pullInfoUnknown */ |
287 | 0, /* pullInfoTensor */ |
288 | 0, /* pullInfoTensorInverse */ |
289 | 0, /* pullInfoHessian */ |
290 | 0, /* pullInfoInside */ |
291 | 0, /* pullInfoInsideGradient */ |
292 | pullInfoHeightHessian, /* pullInfoHeight */ |
293 | 0, /* pullInfoHeightGradient */ |
294 | 0, /* pullInfoHeightHessian */ |
295 | 0, /* pullInfoHeightLaplacian */ |
296 | 0, /* pullInfoSeedPreThresh */ |
297 | 0, /* pullInfoSeedThresh */ |
298 | 0, /* pullInfoLiveThresh */ |
299 | 0, /* pullInfoLiveThresh2 */ |
300 | 0, /* pullInfoLiveThresh3 */ |
301 | 0, /* pullInfoTangent1 */ |
302 | 0, /* pullInfoTangent2 */ |
303 | 0, /* pullInfoNegativeTangent1 */ |
304 | 0, /* pullInfoNegativeTangent2 */ |
305 | pullInfoIsovalueHessian, /* pullInfoIsovalue */ |
306 | 0, /* pullInfoIsovalueGradient */ |
307 | 0, /* pullInfoIsovalueHessian */ |
308 | 0, /* pullInfoStrength */ |
309 | }; |
310 | const unsigned int *infoIdx; |
311 | |
312 | infoIdx = pctx->infoIdx; |
313 | ispec = pctx->ispec[sclInfo]; |
314 | /* NB: this "scl" is not scale-space scale; its the scaling |
315 | of the scalar. this is getting confusing ... */ |
316 | scl = point->info[infoIdx[sclInfo]]; |
317 | scl = (scl - ispec->zero)*ispec->scale; |
318 | /* if (289 == pctx->iter) { |
319 | fprintf(stderr, "!%s(%04u,%s)@(%g,%g): (%g - %g)*%g == %g\n", |
320 | me, point->idtag, airEnumStr(pullInfo, sclInfo), |
321 | point->pos[0], point->pos[1], |
322 | point->info[infoIdx[sclInfo]], ispec->zero, ispec->scale, scl); |
323 | } */ |
324 | if (0 && _pullVerbose) { |
325 | if (pullInfoSeedThresh == sclInfo) { |
326 | printf("!%s: seed thresh (%g - %g)*%g == %g\n", me, |
327 | point->info[infoIdx[sclInfo]], ispec->zero, ispec->scale, scl); |
328 | } |
329 | } |
330 | /* |
331 | learned: this wasn't thought through: the idea was that the height |
332 | *laplacian* answer should be transformed by the *height* zero and |
333 | scale. scale might make sense, but not zero. This cost a few |
334 | hours of tracking down the fact that the first zero-crossing |
335 | detection phase of the lapl constraint was failing because the |
336 | laplacian was vacillating around hspec->zero, not 0.0 . . . |
337 | if (pullInfoHeightLaplacian == sclInfo) { |
338 | const pullInfoSpec *hspec; |
339 | hspec = pctx->ispec[pullInfoHeight]; |
340 | scl = (scl - hspec->zero)*hspec->scale; |
341 | } else { |
342 | scl = (scl - ispec->zero)*ispec->scale; |
343 | } |
344 | */ |
345 | /* |
346 | fprintf(stderr, "!%s: %s = (%g - %g)*%g = %g*%g = %g = %g\n", me, |
347 | airEnumStr(pullInfo, sclInfo), |
348 | point->info[infoIdx[sclInfo]], |
349 | ispec->zero, ispec->scale, |
350 | point->info[infoIdx[sclInfo]] - ispec->zero, ispec->scale, |
351 | (point->info[infoIdx[sclInfo]] - ispec->zero)*ispec->scale, |
352 | scl); |
353 | */ |
354 | if (grad && gradInfo[sclInfo]) { |
355 | const double *ptr = point->info + infoIdx[gradInfo[sclInfo]]; |
356 | ELL_3V_SCALE(grad, ispec->scale, ptr)((grad)[0] = (ispec->scale)*(ptr)[0], (grad)[1] = (ispec-> scale)*(ptr)[1], (grad)[2] = (ispec->scale)*(ptr)[2]); |
357 | } |
358 | if (hess && hessInfo[sclInfo]) { |
359 | const double *ptr = point->info + infoIdx[hessInfo[sclInfo]]; |
360 | ELL_3M_SCALE(hess, ispec->scale, ptr)((((hess)+0)[0] = ((ispec->scale))*((ptr)+0)[0], ((hess)+0 )[1] = ((ispec->scale))*((ptr)+0)[1], ((hess)+0)[2] = ((ispec ->scale))*((ptr)+0)[2]), (((hess)+3)[0] = ((ispec->scale ))*((ptr)+3)[0], ((hess)+3)[1] = ((ispec->scale))*((ptr)+3 )[1], ((hess)+3)[2] = ((ispec->scale))*((ptr)+3)[2]), (((hess )+6)[0] = ((ispec->scale))*((ptr)+6)[0], ((hess)+6)[1] = ( (ispec->scale))*((ptr)+6)[1], ((hess)+6)[2] = ((ispec-> scale))*((ptr)+6)[2])); |
361 | } |
362 | return scl; |
363 | } |
364 | |
365 | int |
366 | pullProbe(pullTask *task, pullPoint *point) { |
367 | static const char me[]="pullProbe"; |
368 | unsigned int ii, gret=0; |
369 | int edge; |
370 | /* |
371 | fprintf(stderr, "!%s: task->probeSeedPreThreshOnly = %d\n", me, |
372 | task->probeSeedPreThreshOnly); |
373 | */ |
374 | #if 0 |
375 | static int opened=AIR_FALSE0; |
376 | static FILE *flog; |
377 | #endif |
378 | |
379 | /* |
380 | fprintf(stderr, "%s(%u,%u): A volNum = %u\n", me, task->pctx->iter, point->idtag,task->pctx->volNum); |
381 | */ |
382 | #if 0 |
383 | static int logIdx=0, logDone=AIR_FALSE0, logStarted=AIR_FALSE0; |
384 | static Nrrd *nlog; |
385 | static double *log=NULL((void*)0); |
386 | if (!logStarted) { |
387 | if (81 == point->idtag) { |
388 | printf("\n\n%s: ###### HELLO begin logging . . .\n\n\n", me); |
389 | /* knowing the logIdx at the end of logging . . . */ |
390 | nlog = nrrdNew(); |
391 | nrrdMaybeAlloc_va(nlog, nrrdTypeDouble, 2, |
392 | AIR_CAST(size_t, 25)((size_t)(25)), |
393 | AIR_CAST(size_t, 2754)((size_t)(2754))); |
394 | log = AIR_CAST(double*, nlog->data)((double*)(nlog->data)); |
395 | logStarted = AIR_TRUE1; |
396 | } |
397 | } |
398 | #endif |
399 | |
400 | if (!ELL_4V_EXISTS(point->pos)((((int)(!(((point->pos)[0]) - ((point->pos)[0]))))) && (((int)(!(((point->pos)[1]) - ((point->pos)[1]))))) && (((int)(!(((point->pos)[2]) - ((point->pos)[2]))))) && (((int)(!(((point->pos)[3]) - ((point->pos)[3]))))))) { |
401 | fprintf(stderr__stderrp, "%s: pnt %u non-exist pos (%g,%g,%g,%g)\n\n!!!\n\n\n", |
402 | me, point->idtag, point->pos[0], point->pos[1], |
403 | point->pos[2], point->pos[3]); |
404 | biffAddf(PULLpullBiffKey, "%s: pnt %u non-exist pos (%g,%g,%g,%g)", |
405 | me, point->idtag, point->pos[0], point->pos[1], |
406 | point->pos[2], point->pos[3]); |
407 | return 1; |
408 | /* can't probe, but make it go away as quickly as possible */ |
409 | /* |
410 | ELL_4V_SET(point->pos, 0, 0, 0, 0); |
411 | point->status |= PULL_STATUS_NIXME_BIT; |
412 | return 0; |
413 | */ |
414 | } |
415 | if (task->pctx->verbose > 3) { |
416 | printf("%s: hello; probing %u volumes\n", me, task->pctx->volNum); |
417 | } |
418 | edge = AIR_FALSE0; |
419 | task->pctx->count[pullCountProbe] += 1; |
420 | /* |
421 | fprintf(stderr, "%s(%u,%u): B volNum = %u\n", me, task->pctx->iter, point->idtag,task->pctx->volNum); |
422 | */ |
423 | for (ii=0; ii<task->pctx->volNum; ii++) { |
424 | pullVolume *vol; |
425 | vol = task->vol[ii]; |
426 | if (task->probeSeedPreThreshOnly |
427 | && !(vol->forSeedPreThresh)) { |
428 | /* we're here *only* to probe SeedPreThresh, |
429 | and this volume isn't used for that */ |
430 | continue; |
431 | } |
432 | if (task->pctx->iter && vol->seedOnly) { |
433 | /* its after the 1st iteration (#0), and this vol is only for seeding */ |
434 | continue; |
435 | } |
436 | /* HEY should task->vol[ii]->scaleNum be the using-scale-space test? */ |
437 | if (!task->vol[ii]->ninScale) { |
438 | gret = gageProbeSpace(task->vol[ii]->gctx, |
439 | point->pos[0], point->pos[1], point->pos[2], |
440 | AIR_FALSE0 /* index-space */, |
441 | AIR_TRUE1 /* clamp */); |
442 | } else { |
443 | if (task->pctx->verbose > 3) { |
444 | printf("%s: vol[%u] has scale (%u)-> " |
445 | "gageStackProbeSpace(%p) (v %d)\n", |
446 | me, ii, task->vol[ii]->scaleNum, |
447 | AIR_VOIDP(task->vol[ii]->gctx)((void *)(task->vol[ii]->gctx)), |
448 | task->vol[ii]->gctx->verbose); |
449 | } |
450 | /* |
451 | if (81 == point->idtag) { |
452 | printf("%s: probing vol[%u] @ %g %g %g %g\n", me, ii, |
453 | point->pos[0], point->pos[1], point->pos[2], point->pos[3]); |
454 | } |
455 | */ |
456 | gret = gageStackProbeSpace(task->vol[ii]->gctx, |
457 | point->pos[0], point->pos[1], point->pos[2], |
458 | (task->pctx->flag.scaleIsTau |
459 | ? gageSigOfTau(point->pos[3])airSigmaOfTau(point->pos[3]) |
460 | : point->pos[3]), |
461 | AIR_FALSE0 /* index-space */, |
462 | AIR_TRUE1 /* clamp */); |
463 | } |
464 | if (gret) { |
465 | biffAddf(PULLpullBiffKey, "%s: probe failed on vol %u/%u: (%d) %s", me, |
466 | ii, task->pctx->volNum, |
467 | task->vol[ii]->gctx->errNum, task->vol[ii]->gctx->errStr); |
468 | return 1; |
469 | } |
470 | /* |
471 | if (!edge |
472 | && AIR_ABS(point->pos[1] - 67) < 1 |
473 | && AIR_ABS(point->pos[2] - 67) < 1 |
474 | && point->pos[3] > 3.13 |
475 | && !!task->vol[ii]->gctx->edgeFrac) { |
476 | fprintf(stderr, "!%s(%u @ %g,%g,%g,%g): " |
477 | "vol[%u]->gctx->edgeFrac %g => edge bit on\n", |
478 | me, point->idtag, |
479 | point->pos[0], point->pos[1], |
480 | point->pos[2], point->pos[3], |
481 | ii, task->vol[ii]->gctx->edgeFrac); |
482 | } |
483 | */ |
484 | edge |= !!task->vol[ii]->gctx->edgeFrac; |
485 | } |
486 | if (edge) { |
487 | point->status |= PULL_STATUS_EDGE_BIT(1<< 4); |
488 | } else { |
489 | point->status &= ~PULL_STATUS_EDGE_BIT(1<< 4); |
490 | } |
491 | |
492 | /* maybe is a little stupid to have the infos indexed this way, |
493 | since it means that we always have to loop through all indices, |
494 | but at least the compiler can unroll it . . . */ |
495 | for (ii=0; ii<=PULL_INFO_MAX23; ii++) { |
496 | unsigned int alen, aidx; |
497 | const pullInfoSpec *ispec; |
498 | ispec = task->pctx->ispec[ii]; |
499 | if (ispec) { |
500 | alen = _pullInfoLen[ii]; |
501 | aidx = task->pctx->infoIdx[ii]; |
502 | if (pullSourceGage == ispec->source) { |
503 | _pullInfoCopy[alen](point->info + aidx, task->ans[ii]); |
504 | /* if (289 == task->pctx->iter) { |
505 | fprintf(stderr, "!%s(%u): copied info %u (%s) len %u\n", me, point->idtag, |
506 | ii, airEnumStr(pullInfo, ii), alen); |
507 | if (1 == alen) { |
508 | fprintf(stderr, "!%s(%u): (point->info + %u)[0] = %g\n", me, point->idtag, |
509 | aidx, (point->info + aidx)[0]); |
510 | } |
511 | } */ |
512 | /* |
513 | if (81 == point->idtag) { |
514 | pullVolume *vol; |
515 | pullInfoSpec *isp; |
516 | isp = task->pctx->ispec[ii]; |
517 | vol = task->pctx->vol[isp->volIdx]; |
518 | if (1 == alen) { |
519 | printf("!%s: info[%u] %s: %s(\"%s\") = %g\n", me, |
520 | ii, airEnumStr(pullInfo, ii), |
521 | airEnumStr(vol->kind->enm, isp->item), |
522 | vol->name, task->ans[ii][0]); |
523 | } else { |
524 | unsigned int vali; |
525 | printf("!%s: info[%u] %s: %s(\"%s\") =\n", me, |
526 | ii, airEnumStr(pullInfo, ii), |
527 | airEnumStr(vol->kind->enm, isp->item), vol->name); |
528 | for (vali=0; vali<alen; vali++) { |
529 | printf("!%s: [%u] %g\n", me, vali, |
530 | task->ans[ii][vali]); |
531 | } |
532 | } |
533 | } |
534 | */ |
535 | } else if (pullSourceProp == ispec->source) { |
536 | switch (ispec->prop) { |
537 | case pullPropIdtag: |
538 | point->info[aidx] = point->idtag; |
539 | break; |
540 | case pullPropIdCC: |
541 | point->info[aidx] = point->idCC; |
542 | break; |
543 | case pullPropEnergy: |
544 | point->info[aidx] = point->energy; |
545 | break; |
546 | case pullPropStepEnergy: |
547 | point->info[aidx] = point->stepEnergy; |
548 | break; |
549 | case pullPropStepConstr: |
550 | point->info[aidx] = point->stepConstr; |
551 | break; |
552 | case pullPropStuck: |
553 | point->info[aidx] = ((point->status & PULL_STATUS_STUCK_BIT(1<< 1)) |
554 | ? point->stuckIterNum |
555 | : 0); |
556 | break; |
557 | case pullPropPosition: |
558 | ELL_4V_COPY(point->info + aidx, point->pos)((point->info + aidx)[0] = (point->pos)[0], (point-> info + aidx)[1] = (point->pos)[1], (point->info + aidx) [2] = (point->pos)[2], (point->info + aidx)[3] = (point ->pos)[3]); |
559 | break; |
560 | case pullPropForce: |
561 | ELL_4V_COPY(point->info + aidx, point->force)((point->info + aidx)[0] = (point->force)[0], (point-> info + aidx)[1] = (point->force)[1], (point->info + aidx )[2] = (point->force)[2], (point->info + aidx)[3] = (point ->force)[3]); |
562 | break; |
563 | case pullPropNeighDistMean: |
564 | point->info[aidx] = point->neighDistMean; |
565 | break; |
566 | case pullPropScale: |
567 | point->info[aidx] = point->pos[3]; |
568 | break; |
569 | case pullPropNeighCovar: |
570 | ELL_10V_COPY(point->info + aidx, point->neighCovar)((point->info + aidx)[0] = (point->neighCovar)[0], (point ->info + aidx)[1] = (point->neighCovar)[1], (point-> info + aidx)[2] = (point->neighCovar)[2], (point->info + aidx)[3] = (point->neighCovar)[3], (point->info + aidx )[4] = (point->neighCovar)[4], (point->info + aidx)[5] = (point->neighCovar)[5], (point->info + aidx)[6] = (point ->neighCovar)[6], (point->info + aidx)[7] = (point-> neighCovar)[7], (point->info + aidx)[8] = (point->neighCovar )[8], (point->info + aidx)[9] = (point->neighCovar)[9]); |
571 | break; |
572 | case pullPropNeighCovar7Ten: |
573 | TEN_T_SET(point->info + aidx, 1.0f,( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ) |
574 | point->neighCovar[0],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ) |
575 | point->neighCovar[1],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ) |
576 | point->neighCovar[2],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ) |
577 | point->neighCovar[4],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ) |
578 | point->neighCovar[5],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ) |
579 | point->neighCovar[7])( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighCovar[0]), (point->info + aidx)[2] = (point->neighCovar[1]), (point->info + aidx)[3] = (point ->neighCovar[2]), (point->info + aidx)[4] = (point-> neighCovar[4]), (point->info + aidx)[5] = (point->neighCovar [5]), (point->info + aidx)[6] = (point->neighCovar[7]) ); |
580 | break; |
581 | #if PULL_TANCOVAR1 |
582 | case pullPropNeighTanCovar: |
583 | TEN_T_SET(point->info + aidx, 1.0f,( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ) |
584 | point->neighTanCovar[0],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ) |
585 | point->neighTanCovar[1],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ) |
586 | point->neighTanCovar[2],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ) |
587 | point->neighTanCovar[3],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ) |
588 | point->neighTanCovar[4],( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ) |
589 | point->neighTanCovar[5])( (point->info + aidx)[0] = (1.0f), (point->info + aidx )[1] = (point->neighTanCovar[0]), (point->info + aidx)[ 2] = (point->neighTanCovar[1]), (point->info + aidx)[3] = (point->neighTanCovar[2]), (point->info + aidx)[4] = (point->neighTanCovar[3]), (point->info + aidx)[5] = ( point->neighTanCovar[4]), (point->info + aidx)[6] = (point ->neighTanCovar[5]) ); |
590 | break; |
591 | #endif |
592 | case pullPropStability: |
593 | point->info[aidx] = point->stability; |
594 | break; |
595 | default: |
596 | break; |
597 | } |
598 | } |
599 | } |
600 | } |
601 | |
602 | #if 0 |
603 | if (logStarted && !logDone) { |
604 | unsigned int ai; |
605 | /* the actual logging */ |
606 | log[0] = point->idtag; |
607 | ELL_4V_COPY(log + 1, point->pos)((log + 1)[0] = (point->pos)[0], (log + 1)[1] = (point-> pos)[1], (log + 1)[2] = (point->pos)[2], (log + 1)[3] = (point ->pos)[3]); |
608 | for (ai=0; ai<20; ai++) { |
609 | log[5 + ai] = point->info[ai]; |
610 | } |
611 | log += nlog->axis[0].size; |
612 | logIdx++; |
613 | if (1 == task->pctx->iter && 81 == point->idtag) { |
614 | printf("\n\n%s: ###### OKAY done logging (%u). . .\n\n\n", me, logIdx); |
615 | nrrdSave("probelog.nrrd", nlog, NULL((void*)0)); |
616 | nlog = nrrdNuke(nlog); |
617 | logDone = AIR_TRUE1; |
618 | } |
619 | } |
620 | #endif |
621 | |
622 | |
623 | #if 0 |
624 | if (!opened) { |
625 | flog = fopen("flog.txt", "w"); |
626 | opened = AIR_TRUE1; |
627 | } |
628 | if (opened) { |
629 | fprintf(flog, "%s(%u): spthr(%g,%g,%g,%g) = %g\n", me, point->idtag, |
630 | point->pos[0], point->pos[1], point->pos[2], point->pos[3], |
631 | point->info[task->pctx->infoIdx[pullInfoSeedPreThresh]]); |
632 | } |
633 | #endif |
634 | |
635 | return 0; |
636 | } |
637 | |
638 | static int |
639 | _threshFail(const pullContext *pctx, const pullPoint *point, int info) { |
640 | /* static const char me[]="_threshFail"; */ |
641 | double val; |
642 | int ret; |
643 | |
644 | if (pctx->ispec[info]) { |
645 | val = pullPointScalar(pctx, point, info, NULL((void*)0), NULL((void*)0)); |
646 | ret = (val < 0); |
647 | /* |
648 | fprintf(stderr, "%s(%s): val=%g -> ret=%d\n", me, |
649 | airEnumStr(pullInfo, info), val, ret); |
650 | */ |
651 | } else { |
652 | ret = AIR_FALSE0; |
653 | } |
654 | return ret; |
655 | } |
656 | |
657 | int |
658 | pullPointInitializePerVoxel(const pullContext *pctx, |
659 | const unsigned int pointIdx, |
660 | pullPoint *point, pullVolume *scaleVol, |
661 | /* output */ |
662 | int *createFailP) { |
663 | static const char me[]="pullPointInitializePerVoxel"; |
664 | unsigned int vidx[3], pix; |
665 | double iPos[3]; |
666 | airRandMTState *rng; |
667 | pullVolume *seedVol; |
668 | gageShape *seedShape; |
669 | int reject, rejectEdge, constrFail; |
670 | unsigned int k; |
671 | |
672 | seedVol = pctx->vol[pctx->ispec[pullInfoSeedThresh]->volIdx]; |
673 | seedShape = seedVol->gctx->shape; |
674 | rng = pctx->task[0]->rng; |
675 | |
676 | /* Obtain voxel and indices from pointIdx */ |
677 | /* axis ordering for this is x, y, z, scale */ |
678 | pix = pointIdx; |
679 | if (pctx->initParm.pointPerVoxel > 0) { |
680 | pix /= pctx->initParm.pointPerVoxel; |
681 | } else { |
682 | pix *= -pctx->initParm.pointPerVoxel; |
683 | } |
684 | vidx[0] = pix % seedShape->size[0]; |
685 | pix = (pix - vidx[0])/seedShape->size[0]; |
686 | vidx[1] = pix % seedShape->size[1]; |
687 | pix = (pix - vidx[1])/seedShape->size[1]; |
688 | if (pctx->initParm.ppvZRange[0] <= pctx->initParm.ppvZRange[1]) { |
689 | unsigned int zrn; |
690 | zrn = pctx->initParm.ppvZRange[1] - pctx->initParm.ppvZRange[0] + 1; |
691 | vidx[2] = (pix % zrn) + pctx->initParm.ppvZRange[0]; |
692 | pix = (pix - (pix % zrn))/zrn; |
693 | } else { |
694 | vidx[2] = pix % seedShape->size[2]; |
695 | pix = (pix - vidx[2])/seedShape->size[2]; |
696 | } |
697 | for (k=0; k<=2; k++) { |
698 | iPos[k] = vidx[k] + pctx->initParm.jitter*(airDrandMT_r(rng)-0.5); |
699 | } |
700 | gageShapeItoW(seedShape, point->pos, iPos); |
701 | if (pctx->flag.zeroZ) { |
702 | point->pos[2] = 0.0; |
703 | } |
704 | |
705 | if (0 && _pullVerbose) { |
706 | printf("!%s: pointIdx %u -> vidx %u %u %u (%u)\n" |
707 | " -> iPos %g %g %g -> wPos %g %g %g\n", |
708 | me, pointIdx, vidx[0], vidx[1], vidx[2], pix, |
709 | iPos[0], iPos[1], iPos[2], |
710 | point->pos[0], point->pos[1], point->pos[2]); |
711 | } |
712 | |
713 | /* Compute sigma coordinate from pix */ |
714 | if (pctx->haveScale) { |
715 | int outside; |
716 | double aidx, bidx; |
717 | /* pix should already be integer in [0, pctx->samplesAlongScaleNum-1)]. */ |
718 | aidx = pix + pctx->initParm.jitter*(airDrandMT_r(rng)-0.5); |
719 | bidx = AIR_AFFINE(-0.5, aidx, pctx->initParm.samplesAlongScaleNum-0.5,( ((double)(scaleVol->scaleNum-1)-(0.0))*((double)(aidx)-( -0.5)) / ((double)(pctx->initParm.samplesAlongScaleNum-0.5 )-(-0.5)) + (0.0)) |
720 | 0.0, scaleVol->scaleNum-1)( ((double)(scaleVol->scaleNum-1)-(0.0))*((double)(aidx)-( -0.5)) / ((double)(pctx->initParm.samplesAlongScaleNum-0.5 )-(-0.5)) + (0.0)); |
721 | point->pos[3] = gageStackItoW(scaleVol->gctx, bidx, &outside); |
722 | if (pctx->flag.scaleIsTau) { |
723 | point->pos[3] = gageTauOfSig(point->pos[3])airTauOfSigma(point->pos[3]); |
724 | } |
725 | if (0 && _pullVerbose) { |
726 | printf("!%s(%u): pix %u -> a %g b %g -> wpos %g\n", me, point->idtag, |
727 | pix, aidx, bidx, point->pos[3]); |
728 | } |
729 | } else { |
730 | point->pos[3] = 0; |
731 | } |
732 | |
733 | if (pctx->ispec[pullInfoSeedPreThresh]) { |
734 | /* we first do a special-purpose probe just for SeedPreThresh */ |
735 | pctx->task[0]->probeSeedPreThreshOnly = AIR_TRUE1; |
736 | if (pullProbe(pctx->task[0], point)) { |
737 | biffAddf(PULLpullBiffKey, "%s: pre-probing pointIdx %u of world", me, pointIdx); |
738 | return 1; |
739 | } |
740 | pctx->task[0]->probeSeedPreThreshOnly = AIR_FALSE0; |
741 | if (_threshFail(pctx, point, pullInfoSeedPreThresh)) { |
742 | reject = AIR_TRUE1; |
743 | /* HEY! this obviously need to be re-written */ |
744 | goto finish; |
745 | } |
746 | } |
747 | /* else, we didn't have a SeedPreThresh, or we did, and we passed |
748 | it. Now we REDO the probe, including possibly re-learning |
749 | SeedPreThresh, which is silly, but the idea is that this is a |
750 | small price compared to what has been saved by avoiding all the |
751 | gageProbe()s on volumes unrelated to SeedPreThresh */ |
752 | if (pullProbe(pctx->task[0], point)) { |
753 | biffAddf(PULLpullBiffKey, "%s: probing pointIdx %u of world", me, pointIdx); |
754 | return 1; |
755 | } |
756 | |
757 | constrFail = AIR_FALSE0; |
758 | reject = AIR_FALSE0; |
759 | |
760 | /* Check we pass pre-threshold */ |
761 | if (!reject) reject |= _threshFail(pctx, point, pullInfoSeedPreThresh); |
762 | |
763 | if (!pctx->flag.constraintBeforeSeedThresh) { |
764 | /* we should be guaranteed to have a seed thresh info */ |
765 | if (!reject) reject |= _threshFail(pctx, point, pullInfoSeedThresh); |
766 | if (pctx->initParm.liveThreshUse) { |
767 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh); |
768 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh2); |
769 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh3); |
770 | } |
771 | } |
772 | |
773 | if (!reject && pctx->constraint) { |
774 | if (_pullConstraintSatisfy(pctx->task[0], point, |
775 | 10*_PULL_CONSTRAINT_TRAVEL_MAX2, |
776 | &constrFail)) { |
777 | biffAddf(PULLpullBiffKey, "%s: on pnt %u", |
778 | me, pointIdx); |
779 | return 1; |
780 | } |
781 | reject |= constrFail; |
782 | /* post constraint-satisfaction, we certainly have to assert thresholds */ |
783 | if (!reject) reject |= _threshFail(pctx, point, pullInfoSeedThresh); |
784 | if (pctx->initParm.liveThreshUse) { |
785 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh); |
786 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh2); |
787 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh3); |
788 | } |
789 | if (pctx->flag.nixAtVolumeEdgeSpace |
790 | && (point->status & PULL_STATUS_EDGE_BIT(1<< 4))) { |
791 | rejectEdge = AIR_TRUE1; |
792 | } else { |
793 | rejectEdge = AIR_FALSE0; |
794 | } |
795 | reject |= rejectEdge; |
796 | if (pctx->verbose > 1) { |
797 | fprintf(stderr__stderrp, "%s(%u): constr %d, seed %d, thresh %d %d %d, edge %d\n", |
798 | me, point->idtag, constrFail, |
799 | _threshFail(pctx, point, pullInfoSeedThresh), |
800 | _threshFail(pctx, point, pullInfoLiveThresh), |
801 | _threshFail(pctx, point, pullInfoLiveThresh2), |
802 | _threshFail(pctx, point, pullInfoLiveThresh3), rejectEdge); |
803 | } |
804 | } else { |
805 | constrFail = AIR_FALSE0; |
806 | } |
807 | |
808 | finish: |
809 | /* Gather consensus */ |
810 | if (reject) { |
811 | *createFailP = AIR_TRUE1; |
812 | } else { |
813 | *createFailP = AIR_FALSE0; |
814 | } |
815 | |
816 | return 0; |
817 | } |
818 | |
819 | static void |
820 | _pullUnitToWorld(const pullContext *pctx, const pullVolume *scaleVol, |
821 | double wrld[4], const double unit[4]) { |
822 | /* static const char me[]="_pullUnitToWorld"; */ |
823 | |
824 | wrld[0] = AIR_AFFINE(0.0, unit[0], 1.0, pctx->bboxMin[0], pctx->bboxMax[0])( ((double)(pctx->bboxMax[0])-(pctx->bboxMin[0]))*((double )(unit[0])-(0.0)) / ((double)(1.0)-(0.0)) + (pctx->bboxMin [0])); |
825 | wrld[1] = AIR_AFFINE(0.0, unit[1], 1.0, pctx->bboxMin[1], pctx->bboxMax[1])( ((double)(pctx->bboxMax[1])-(pctx->bboxMin[1]))*((double )(unit[1])-(0.0)) / ((double)(1.0)-(0.0)) + (pctx->bboxMin [1])); |
826 | wrld[2] = AIR_AFFINE(0.0, unit[2], 1.0, pctx->bboxMin[2], pctx->bboxMax[2])( ((double)(pctx->bboxMax[2])-(pctx->bboxMin[2]))*((double )(unit[2])-(0.0)) / ((double)(1.0)-(0.0)) + (pctx->bboxMin [2])); |
827 | if (pctx->haveScale) { |
828 | double sridx; |
829 | int outside; |
830 | sridx = AIR_AFFINE(0.0, unit[3], 1.0, 0, scaleVol->scaleNum-1)( ((double)(scaleVol->scaleNum-1)-(0))*((double)(unit[3])- (0.0)) / ((double)(1.0)-(0.0)) + (0)); |
831 | wrld[3] = gageStackItoW(scaleVol->gctx, sridx, &outside); |
832 | if (pctx->flag.scaleIsTau) { |
833 | wrld[3] = gageTauOfSig(wrld[3])airTauOfSigma(wrld[3]); |
834 | } |
835 | } else { |
836 | wrld[3] = 0.0; |
837 | } |
838 | /* |
839 | fprintf(stderr, "!%s: (%g,%g,%g,%g) -- [%g,%g]x[%g,%g]x[%g,%g]--> (%g,%g,%g,%g)\n", me, |
840 | unit[0], unit[1], unit[2], unit[3], |
841 | pctx->bboxMin[0], pctx->bboxMin[1], pctx->bboxMin[2], |
842 | pctx->bboxMax[0], pctx->bboxMax[1], pctx->bboxMax[2], |
843 | wrld[0], wrld[1], wrld[2], wrld[3]); |
844 | */ |
845 | return; |
846 | } |
847 | |
848 | int |
849 | pullPointInitializeRandomOrHalton(pullContext *pctx, |
850 | const unsigned int pointIdx, |
851 | pullPoint *point, pullVolume *scaleVol) { |
852 | static const char me[]="pullPointInitializeRandomOrHalton"; |
853 | int reject, verbo; |
854 | airRandMTState *rng; |
855 | unsigned int tryCount = 0, threshFailCount = 0, spthreshFailCount = 0, |
856 | constrFailCount = 0; |
857 | rng = pctx->task[0]->rng; |
858 | |
859 | do { |
860 | double rpos[4]; |
861 | /* fprintf(stderr, "!%s: starting doooo (tryCount %u)!\n", me, tryCount); */ |
862 | tryCount++; |
863 | reject = AIR_FALSE0; |
864 | _pullPointHistInit(point); |
865 | /* Populate tentative random point */ |
866 | if (pullInitMethodHalton == pctx->initParm.method) { |
867 | /* we generate all 4 coordinates, even if we don't need them all */ |
868 | airHalton(rpos, (pointIdx + threshFailCount + constrFailCount |
869 | + pctx->haltonOffset + pctx->initParm.haltonStartIndex), |
870 | airPrimeList, 4); |
871 | /* |
872 | fprintf(stderr, "!%s(%u/%u): halton(%u=%u+%u+%u+%u+%u) => %g %g %g %g\n", |
873 | me, pointIdx, pctx->idtagNext, |
874 | (pointIdx + threshFailCount + constrFailCount + |
875 | pctx->haltonOffset + pctx->initParm.haltonStartIndex), |
876 | pointIdx, threshFailCount, constrFailCount, |
877 | pctx->haltonOffset, pctx->initParm.haltonStartIndex, |
878 | rpos[0], rpos[1], rpos[2], rpos[3]); |
879 | */ |
880 | /* |
881 | fprintf(stderr, "%g %g %g %g ", |
882 | rpos[0], rpos[1], rpos[2], rpos[3]); |
883 | */ |
884 | if (!pctx->haveScale) { |
885 | rpos[3] = 0; |
886 | } |
887 | } else { |
888 | ELL_3V_SET(rpos, airDrandMT_r(rng), airDrandMT_r(rng), airDrandMT_r(rng))((rpos)[0] = (airDrandMT_r(rng)), (rpos)[1] = (airDrandMT_r(rng )), (rpos)[2] = (airDrandMT_r(rng))); |
889 | if (pctx->haveScale) { |
890 | rpos[3] = airDrandMT_r(rng); |
891 | } else { |
892 | rpos[3] = 0; |
893 | } |
894 | } |
895 | _pullUnitToWorld(pctx, scaleVol, point->pos, rpos); |
896 | if (pctx->flag.zeroZ) { |
897 | point->pos[2] = 0.0; |
898 | } |
899 | /* |
900 | verbo = (AIR_ABS(-0.246015 - point->pos[0]) < 0.1 && |
901 | AIR_ABS(-144.78 - point->pos[0]) < 0.1 && |
902 | AIR_ABS(-85.3813 - point->pos[0]) < 0.1); |
903 | */ |
904 | verbo = AIR_FALSE0; |
905 | if (verbo) { |
906 | fprintf(stderr__stderrp, "%s: verbo on for point %u at %g %g %g %g\n", me, |
907 | point->idtag, point->pos[0], point->pos[1], |
908 | point->pos[2], point->pos[3]); |
909 | } |
910 | _pullPointHistAdd(point, pullCondOld, AIR_NAN); |
911 | |
912 | /* HEY copy and paste */ |
913 | if (pctx->ispec[pullInfoSeedPreThresh]) { |
914 | /* we first do a special-purpose probe just for SeedPreThresh */ |
915 | pctx->task[0]->probeSeedPreThreshOnly = AIR_TRUE1; |
916 | if (pullProbe(pctx->task[0], point)) { |
917 | biffAddf(PULLpullBiffKey, "%s: pre-probing pointIdx %u of world", me, pointIdx); |
918 | return 1; |
919 | } |
920 | pctx->task[0]->probeSeedPreThreshOnly = AIR_FALSE0; |
921 | if (_threshFail(pctx, point, pullInfoSeedPreThresh)) { |
922 | threshFailCount++; |
923 | spthreshFailCount++; |
924 | reject = AIR_TRUE1; |
925 | goto reckoning; |
926 | } |
927 | } |
928 | if (pullProbe(pctx->task[0], point)) { |
929 | biffAddf(PULLpullBiffKey, "%s: probing pointIdx %u of world", me, pointIdx); |
930 | return 1; |
931 | } |
932 | /* Check we pass pre-threshold */ |
933 | #define THRESH_TEST(INFO)if (pctx->ispec[INFO] && _threshFail(pctx, point, INFO )) { threshFailCount++; reject = 1; goto reckoning; } \ |
934 | if (pctx->ispec[INFO] && _threshFail(pctx, point, INFO)) { \ |
935 | threshFailCount++; \ |
936 | reject = AIR_TRUE1; \ |
937 | goto reckoning; \ |
938 | } |
939 | /* fprintf(stderr, "!%s: bi ngo 0 (%d) %d %p\n", me, |
940 | !pctx->flag.constraintBeforeSeedThresh, |
941 | pctx->initParm.liveThreshUse, pctx->ispec[pullInfoLiveThresh]); */ |
942 | if (!pctx->flag.constraintBeforeSeedThresh) { |
943 | THRESH_TEST(pullInfoSeedThresh)if (pctx->ispec[pullInfoSeedThresh] && _threshFail (pctx, point, pullInfoSeedThresh)) { threshFailCount++; reject = 1; goto reckoning; }; |
944 | if (pctx->initParm.liveThreshUse) { |
945 | THRESH_TEST(pullInfoLiveThresh)if (pctx->ispec[pullInfoLiveThresh] && _threshFail (pctx, point, pullInfoLiveThresh)) { threshFailCount++; reject = 1; goto reckoning; }; |
946 | THRESH_TEST(pullInfoLiveThresh2)if (pctx->ispec[pullInfoLiveThresh2] && _threshFail (pctx, point, pullInfoLiveThresh2)) { threshFailCount++; reject = 1; goto reckoning; }; |
947 | THRESH_TEST(pullInfoLiveThresh3)if (pctx->ispec[pullInfoLiveThresh3] && _threshFail (pctx, point, pullInfoLiveThresh3)) { threshFailCount++; reject = 1; goto reckoning; }; |
948 | } |
949 | } |
950 | /* fprintf(stderr, "!%s: bi ngo 1\n", me); */ |
951 | |
952 | if (pctx->constraint) { |
953 | int constrFail; |
954 | /* fprintf(stderr, "!%s: calling _pullConstraintSatisfy(%u)\n", me, pointIdx); */ |
955 | if (_pullConstraintSatisfy(pctx->task[0], point, |
956 | _PULL_CONSTRAINT_TRAVEL_MAX2, |
957 | &constrFail)) { |
958 | biffAddf(PULLpullBiffKey, "%s: trying constraint on point %u", me, pointIdx); |
959 | return 1; |
960 | } |
961 | #if PULL_PHIST0 |
962 | if (DEBUG1) { |
963 | Nrrd *nhist; |
964 | FILE *fhist; |
965 | char fname[AIR_STRLEN_SMALL(128+1)]; |
966 | nhist = nrrdNew(); |
967 | if (pullPositionHistoryNrrdGet(nhist, pctx, point)) { |
968 | biffAddf(PULLpullBiffKey, "%s: trouble", me); |
969 | return 1; |
970 | } |
971 | sprintf(fname, "%04u-%04u-%04u-phist.nrrd", pctx->iter,__builtin___sprintf_chk (fname, 0, __builtin_object_size (fname , 2 > 1 ? 1 : 0), "%04u-%04u-%04u-phist.nrrd", pctx->iter , point->idtag, tryCount) |
972 | point->idtag, tryCount)__builtin___sprintf_chk (fname, 0, __builtin_object_size (fname , 2 > 1 ? 1 : 0), "%04u-%04u-%04u-phist.nrrd", pctx->iter , point->idtag, tryCount); |
973 | if ((fhist = fopen(fname, "w"))) { |
974 | if (nrrdSave(fname, nhist, NULL((void*)0))) { |
975 | biffMovef(PULLpullBiffKey, NRRDnrrdBiffKey, "%s: trouble", me); |
976 | return 1; |
977 | } |
978 | fclose(fhist); |
979 | } |
980 | nrrdNuke(nhist); |
981 | } |
982 | #endif |
983 | if (constrFail) { |
984 | constrFailCount++; |
985 | reject = AIR_TRUE1; |
986 | goto reckoning; |
987 | } |
988 | /* fprintf(stderr, "!%s: bi ngo 2\n", me); */ |
989 | /* post constraint-satisfaction, we certainly have to assert thresholds */ |
990 | THRESH_TEST(pullInfoSeedThresh)if (pctx->ispec[pullInfoSeedThresh] && _threshFail (pctx, point, pullInfoSeedThresh)) { threshFailCount++; reject = 1; goto reckoning; }; |
991 | if (pctx->initParm.liveThreshUse) { |
992 | THRESH_TEST(pullInfoLiveThresh)if (pctx->ispec[pullInfoLiveThresh] && _threshFail (pctx, point, pullInfoLiveThresh)) { threshFailCount++; reject = 1; goto reckoning; }; |
993 | THRESH_TEST(pullInfoLiveThresh2)if (pctx->ispec[pullInfoLiveThresh2] && _threshFail (pctx, point, pullInfoLiveThresh2)) { threshFailCount++; reject = 1; goto reckoning; }; |
994 | THRESH_TEST(pullInfoLiveThresh3)if (pctx->ispec[pullInfoLiveThresh3] && _threshFail (pctx, point, pullInfoLiveThresh3)) { threshFailCount++; reject = 1; goto reckoning; }; |
995 | } |
996 | /* fprintf(stderr, "!%s: bi ngo 3 (reject=%d)\n", me, reject); */ |
997 | } |
998 | |
999 | reckoning: |
1000 | if (reject) { |
1001 | if (threshFailCount + constrFailCount >= _PULL_RANDOM_SEED_TRY_MAX1000000) { |
1002 | /* Very bad luck; we've too many times */ |
1003 | biffAddf(PULLpullBiffKey, "%s: failed too often (%u times) placing point %u: " |
1004 | "%u fails on thresh (%u on pre-thresh), %u on constr", |
1005 | me, _PULL_RANDOM_SEED_TRY_MAX1000000, pointIdx, |
1006 | threshFailCount, spthreshFailCount, constrFailCount); |
1007 | return 1; |
1008 | } |
1009 | } |
1010 | } while (reject); |
1011 | |
1012 | if (pullInitMethodHalton == pctx->initParm.method) { |
1013 | pctx->haltonOffset += threshFailCount + constrFailCount; |
1014 | } |
1015 | |
1016 | return 0; |
1017 | } |
1018 | |
1019 | int |
1020 | pullPointInitializeGivenPos(pullContext *pctx, |
1021 | const double *posData, |
1022 | const unsigned int pointIdx, |
1023 | pullPoint *point, |
1024 | /* output */ |
1025 | int *createFailP) { |
1026 | static const char me[]="pullPointInitializeGivenPos"; |
1027 | int reject, rejectEdge; |
1028 | |
1029 | /* Copy nrrd point into pullPoint */ |
1030 | ELL_4V_COPY(point->pos, posData + 4*pointIdx)((point->pos)[0] = (posData + 4*pointIdx)[0], (point->pos )[1] = (posData + 4*pointIdx)[1], (point->pos)[2] = (posData + 4*pointIdx)[2], (point->pos)[3] = (posData + 4*pointIdx )[3]); |
1031 | if (pctx->flag.zeroZ) { |
1032 | point->pos[2] = 0.0; |
1033 | } |
1034 | |
1035 | /* |
1036 | if (AIR_ABS(247.828 - point->pos[0]) < 0.1 && |
1037 | AIR_ABS(66.8817 - point->pos[1]) < 0.1 && |
1038 | AIR_ABS(67.0031 - point->pos[2]) < 0.1) { |
1039 | fprintf(stderr, "%s: --------- point %u at %g %g %g %g\n", me, |
1040 | point->idtag, |
1041 | point->pos[0], point->pos[1], |
1042 | point->pos[2], point->pos[3]); |
1043 | } |
1044 | */ |
1045 | |
1046 | /* we're dictating positions, but still have to do initial probe, |
1047 | and possibly liveThresholding */ |
1048 | if (pullProbe(pctx->task[0], point)) { |
1049 | biffAddf(PULLpullBiffKey, "%s: probing pointIdx %u of npos", me, pointIdx); |
1050 | return 1; |
1051 | } |
1052 | reject = AIR_FALSE0; |
1053 | if (pctx->flag.nixAtVolumeEdgeSpace |
1054 | && (point->status & PULL_STATUS_EDGE_BIT(1<< 4))) { |
1055 | rejectEdge = AIR_TRUE1; |
1056 | } else { |
1057 | rejectEdge = AIR_FALSE0; |
1058 | } |
1059 | reject |= rejectEdge; |
1060 | if (pctx->initParm.liveThreshUse) { |
1061 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh); |
1062 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh2); |
1063 | if (!reject) reject |= _threshFail(pctx, point, pullInfoLiveThresh3); |
1064 | } |
1065 | /* |
1066 | if (reject) { |
1067 | fprintf(stderr, "!%s(%u): edge %d thresh %d %d %d\n", |
1068 | me, point->idtag, rejectEdge, |
1069 | _threshFail(pctx, point, pullInfoLiveThresh), |
1070 | _threshFail(pctx, point, pullInfoLiveThresh2), |
1071 | _threshFail(pctx, point, pullInfoLiveThresh3)); |
1072 | } |
1073 | */ |
1074 | if (reject) { |
1075 | *createFailP = AIR_TRUE1; |
1076 | } else { |
1077 | *createFailP = AIR_FALSE0; |
1078 | } |
1079 | |
1080 | return 0; |
1081 | } |
1082 | |
1083 | /* |
1084 | ** _pullPointSetup sets: |
1085 | ** |
1086 | ** This is only called by the master thread |
1087 | ** |
1088 | ** this should set stuff to be like after an update stage and |
1089 | ** just before the rebinning |
1090 | */ |
1091 | int |
1092 | _pullPointSetup(pullContext *pctx) { |
1093 | static const char me[]="_pullPointSetup"; |
1094 | char doneStr[AIR_STRLEN_SMALL(128+1)]; |
1095 | unsigned int pointIdx, binIdx, tick, pn; |
1096 | pullPoint *point; |
1097 | pullBin *bin; |
1098 | int createFail,added; |
1099 | airArray *mop; |
1100 | Nrrd *npos; |
1101 | pullVolume *seedVol, *scaleVol; |
1102 | gageShape *seedShape; |
1103 | double factor, *posData; |
1104 | unsigned int totalNumPoints, voxNum, ii; |
1105 | |
1106 | /* on using pullBinsPointMaybeAdd: This is used only in the context |
1107 | of constraints; it makes sense to be a little more selective |
1108 | about adding points, so that they aren't completely piled on top |
1109 | of each other. This relies on _PULL_BINNING_MAYBE_ADD_THRESH: its |
1110 | tempting to set this value high, to more aggressively limit the |
1111 | number of points added, but that's really the job of population |
1112 | control, and we can't always guarantee that constraint manifolds |
1113 | will be well-sampled (with respect to pctx->radiusSpace and |
1114 | pctx->radiusScale) to start with */ |
1115 | |
1116 | if (pctx->verbose) { |
1117 | printf("%s: beginning (%s). . . ", me, |
1118 | airEnumStr(pullInitMethod, pctx->initParm.method)); |
1119 | fflush(stdout__stdoutp); |
1120 | } |
1121 | mop = airMopNew(); |
1122 | switch (pctx->initParm.method) { |
1123 | case pullInitMethodGivenPos: |
1124 | npos = nrrdNew(); |
1125 | airMopAdd(mop, npos, (airMopper)nrrdNuke, airMopAlways); |
1126 | /* even if npos came in as double, we have to copy it */ |
1127 | if (nrrdConvert(npos, pctx->initParm.npos, nrrdTypeDouble)) { |
1128 | biffMovef(PULLpullBiffKey, NRRDnrrdBiffKey, "%s: trouble converting npos", me); |
1129 | airMopError(mop); return 1; |
1130 | } |
1131 | posData = AIR_CAST(double *, npos->data)((double *)(npos->data)); |
1132 | if (pctx->initParm.numInitial || pctx->initParm.pointPerVoxel) { |
1133 | printf("%s: with npos, overriding both numInitial (%u) " |
1134 | "and pointPerVoxel (%d)\n", me, pctx->initParm.numInitial, |
1135 | pctx->initParm.pointPerVoxel); |
1136 | } |
1137 | totalNumPoints = AIR_CAST(unsigned int, npos->axis[1].size)((unsigned int)(npos->axis[1].size)); |
1138 | break; |
1139 | case pullInitMethodPointPerVoxel: |
1140 | npos = NULL((void*)0); |
1141 | posData = NULL((void*)0); |
1142 | if (pctx->initParm.numInitial && pctx->verbose) { |
1143 | printf("%s: pointPerVoxel %d overrides numInitial (%u)\n", me, |
1144 | pctx->initParm.pointPerVoxel, pctx->initParm.numInitial); |
1145 | } |
1146 | /* Obtain number of voxels */ |
1147 | seedVol = pctx->vol[pctx->ispec[pullInfoSeedThresh]->volIdx]; |
1148 | seedShape = seedVol->gctx->shape; |
1149 | if (pctx->initParm.ppvZRange[0] <= pctx->initParm.ppvZRange[1]) { |
1150 | unsigned int zrn; |
1151 | if (!( pctx->initParm.ppvZRange[0] < seedShape->size[2] |
1152 | && pctx->initParm.ppvZRange[1] < seedShape->size[2] )) { |
1153 | biffAddf(PULLpullBiffKey, "%s: ppvZRange[%u,%u] outside volume [0,%u]", me, |
1154 | pctx->initParm.ppvZRange[0], pctx->initParm.ppvZRange[1], |
1155 | seedShape->size[2]-1); |
1156 | airMopError(mop); return 1; |
1157 | } |
1158 | zrn = pctx->initParm.ppvZRange[1] - pctx->initParm.ppvZRange[0] + 1; |
1159 | voxNum = seedShape->size[0]*seedShape->size[1]*zrn; |
1160 | if (pctx->verbose) { |
1161 | printf("%s: vol size %u %u [%u,%u] -> voxNum %u\n", me, |
1162 | seedShape->size[0], seedShape->size[1], |
1163 | pctx->initParm.ppvZRange[0], pctx->initParm.ppvZRange[1], |
1164 | voxNum); |
1165 | } |
1166 | } else { |
1167 | voxNum = seedShape->size[0]*seedShape->size[1]*seedShape->size[2]; |
1168 | if (pctx->verbose) { |
1169 | printf("%s: vol size %u %u %u -> voxNum %u\n", me, |
1170 | seedShape->size[0], seedShape->size[1], seedShape->size[2], |
1171 | voxNum); |
1172 | } |
1173 | } |
1174 | |
1175 | /* Compute total number of points */ |
1176 | if (pctx->initParm.pointPerVoxel > 0) { |
1177 | factor = pctx->initParm.pointPerVoxel; |
1178 | } else { |
1179 | factor = -1.0/pctx->initParm.pointPerVoxel; |
1180 | } |
1181 | if (pctx->haveScale) { |
1182 | unsigned int sasn; |
1183 | sasn = pctx->initParm.samplesAlongScaleNum; |
1184 | totalNumPoints = AIR_CAST(unsigned int, voxNum * factor * sasn)((unsigned int)(voxNum * factor * sasn)); |
1185 | } else { |
1186 | totalNumPoints = AIR_CAST(unsigned int, voxNum * factor)((unsigned int)(voxNum * factor)); |
1187 | } |
1188 | break; |
1189 | case pullInitMethodRandom: |
1190 | case pullInitMethodHalton: |
1191 | npos = NULL((void*)0); |
1192 | posData = NULL((void*)0); |
1193 | totalNumPoints = pctx->initParm.numInitial; |
1194 | break; |
1195 | default: |
1196 | biffAddf(PULLpullBiffKey, "%s: pullInitMethod %d not handled!", me, |
1197 | pctx->initParm.method); |
1198 | airMopError(mop); return 1; |
1199 | break; |
1200 | } |
1201 | if (pctx->verbose) { |
1202 | printf("%s: initializing/seeding %u pts. . . ", me, totalNumPoints); |
1203 | fflush(stdout__stdoutp); |
1204 | } |
1205 | |
1206 | /* find first scale volume, if there is one; this is used by some |
1207 | seeders to determine placement along the scale axis */ |
1208 | scaleVol = NULL((void*)0); |
1209 | for (ii=0; ii<pctx->volNum; ii++) { |
1210 | if (pctx->vol[ii]->ninScale) { |
1211 | scaleVol = pctx->vol[ii]; |
1212 | break; |
1213 | } |
1214 | } |
1215 | |
1216 | /* Start adding points */ |
1217 | tick = totalNumPoints/1000; |
1218 | point = NULL((void*)0); |
1219 | unsigned int initRorHack = 0; |
1220 | /* This loop would normally be: |
1221 | for (pointIdx = 0; pointIdx < totalNumPoints; pointIdx++) { |
1222 | but because of pctx->flag.nixAtVolumeEdgeSpaceInitRorH we |
1223 | need to be able to decrement pointIdx to force another redo, |
1224 | even if pointIdx==0. So loop index is actually one greater |
1225 | than the index value actually used */ |
1226 | for (pointIdx = 1; pointIdx <= totalNumPoints; pointIdx++) { |
1227 | int E; |
1228 | if (pctx->verbose) { |
1229 | if (tick < 100 || 0 == (pointIdx-1) % tick) { |
1230 | printf("%s", airDoneStr(0, pointIdx-1, totalNumPoints, doneStr)); |
1231 | fflush(stdout__stdoutp); |
1232 | } |
1233 | } |
1234 | if (pctx->verbose > 5) { |
1235 | printf("\n%s: setting up point = %u/%u\n", me, |
1236 | pointIdx-1, totalNumPoints); |
1237 | } |
1238 | /* Create point */ |
1239 | if (!point) { |
1240 | point = pullPointNew(pctx); |
1241 | } |
1242 | /* Filling array according to initialization method */ |
1243 | E = 0; |
1244 | switch(pctx->initParm.method) { |
1245 | case pullInitMethodRandom: |
1246 | case pullInitMethodHalton: |
1247 | /* point index passed here always increments, even if |
1248 | we failed last time because of being at edge */ |
1249 | E = pullPointInitializeRandomOrHalton(pctx, pointIdx-1 + initRorHack, |
1250 | point, scaleVol); |
1251 | if (pctx->flag.nixAtVolumeEdgeSpaceInitRorH) { |
1252 | createFail = !!(point->status & PULL_STATUS_EDGE_BIT(1<< 4)); |
1253 | if (createFail) { |
1254 | initRorHack++; |
1255 | if (initRorHack > 10*totalNumPoints) { |
1256 | biffAddf(PULLpullBiffKey, "%s: (point %u) handling nixAtVolumeEdgeSpaceInitRorH, " |
1257 | "have failed so often (%u > 10*#pnts = %u); something " |
1258 | "must be wrong", me, point->idtag, initRorHack, |
1259 | totalNumPoints); |
1260 | airMopError(mop); return 1; |
1261 | } |
1262 | /* this is a for-loop, post-body increment will always happen; |
1263 | we need to subvert it. */ |
1264 | pointIdx--; |
1265 | } |
1266 | } else { |
1267 | createFail = AIR_FALSE0; |
1268 | } |
1269 | break; |
1270 | case pullInitMethodPointPerVoxel: |
1271 | E = pullPointInitializePerVoxel(pctx, pointIdx-1, point, scaleVol, |
1272 | &createFail); |
1273 | break; |
1274 | case pullInitMethodGivenPos: |
1275 | E = pullPointInitializeGivenPos(pctx, posData, pointIdx-1, point, |
1276 | &createFail); |
1277 | break; |
1278 | } |
1279 | if (E) { |
1280 | biffAddf(PULLpullBiffKey, "%s: trouble trying point %u (id %u)", me, |
1281 | pointIdx-1, point->idtag); |
1282 | airMopError(mop); return 1; |
1283 | } |
1284 | if (createFail) { |
1285 | /* We were not successful in creating a point; not an error */ |
1286 | continue; |
1287 | } |
1288 | |
1289 | /* else, the point is ready for binning */ |
1290 | if (pctx->constraint) { |
1291 | if (pullBinsPointMaybeAdd(pctx, point, NULL((void*)0), &added)) { |
1292 | biffAddf(PULLpullBiffKey, "%s: trouble binning point %u", me, point->idtag); |
1293 | airMopError(mop); return 1; |
1294 | } |
1295 | /* |
1296 | if (4523 == point->idtag) { |
1297 | fprintf(stderr, "!%s(%u): ----- added=%d at %g %g %g %g\n", |
1298 | me, point->idtag, added, |
1299 | point->pos[0], point->pos[1], point->pos[2], point->pos[3]); |
1300 | } |
1301 | */ |
1302 | if (added) { |
1303 | point = NULL((void*)0); |
1304 | } |
1305 | } else { |
1306 | if (pullBinsPointAdd(pctx, point, NULL((void*)0))) { |
1307 | biffAddf(PULLpullBiffKey, "%s: trouble binning point %u", me, point->idtag); |
1308 | airMopError(mop); return 1; |
1309 | } |
1310 | point = NULL((void*)0); |
1311 | } |
1312 | } /* Done looping through total number of points */ |
1313 | if (pctx->verbose) { |
1314 | printf("%s\n", airDoneStr(0, pointIdx-1, totalNumPoints, |
1315 | doneStr)); |
1316 | } |
1317 | if (point) { |
1318 | /* we created a new test point, but it was never placed in the volume */ |
1319 | /* so, HACK: undo pullPointNew . . . */ |
1320 | point = pullPointNix(point); |
Value stored to 'point' is never read | |
1321 | /* pctx->idtagNext -= 1; */ |
1322 | } |
1323 | |
1324 | /* Final check: do we have any points? */ |
1325 | pn = pullPointNumber(pctx); |
1326 | if (!pn) { |
1327 | char stmp1[AIR_STRLEN_MED(256+1)], stmp2[AIR_STRLEN_MED(256+1)]; |
1328 | int guess=AIR_FALSE0; |
1329 | sprintf(stmp1, "%s: seeded 0 points", me)__builtin___sprintf_chk (stmp1, 0, __builtin_object_size (stmp1 , 2 > 1 ? 1 : 0), "%s: seeded 0 points", me); |
1330 | if (pctx->ispec[pullInfoSeedThresh]) { |
1331 | guess=AIR_TRUE1; |
1332 | sprintf(stmp2, " (? bad seedthresh %g ?)",__builtin___sprintf_chk (stmp2, 0, __builtin_object_size (stmp2 , 2 > 1 ? 1 : 0), " (? bad seedthresh %g ?)", pctx->ispec [pullInfoSeedThresh]->zero) |
1333 | pctx->ispec[pullInfoSeedThresh]->zero)__builtin___sprintf_chk (stmp2, 0, __builtin_object_size (stmp2 , 2 > 1 ? 1 : 0), " (? bad seedthresh %g ?)", pctx->ispec [pullInfoSeedThresh]->zero); |
1334 | strcat(stmp1, stmp2)__builtin___strcat_chk (stmp1, stmp2, __builtin_object_size ( stmp1, 2 > 1 ? 1 : 0)); |
1335 | } |
1336 | if (pctx->flag.nixAtVolumeEdgeSpace) { |
1337 | guess=AIR_TRUE1; |
1338 | sprintf(stmp2, " (? flag.nixAtVolumeEdgeSpace true ?)")__builtin___sprintf_chk (stmp2, 0, __builtin_object_size (stmp2 , 2 > 1 ? 1 : 0), " (? flag.nixAtVolumeEdgeSpace true ?)"); |
1339 | strcat(stmp1, stmp2)__builtin___strcat_chk (stmp1, stmp2, __builtin_object_size ( stmp1, 2 > 1 ? 1 : 0)); |
1340 | } |
1341 | if (!guess) { |
1342 | sprintf(stmp2, " (no guess as to why)")__builtin___sprintf_chk (stmp2, 0, __builtin_object_size (stmp2 , 2 > 1 ? 1 : 0), " (no guess as to why)"); |
1343 | strcat(stmp1, stmp2)__builtin___strcat_chk (stmp1, stmp2, __builtin_object_size ( stmp1, 2 > 1 ? 1 : 0)); |
1344 | } |
1345 | biffAddf(PULLpullBiffKey, "%s", stmp1); |
1346 | airMopError(mop); return 1; |
1347 | } |
1348 | if (pctx->verbose) { |
1349 | fprintf(stderr__stderrp, "%s: initialized to %u points (idtagNext = %u)\n", |
1350 | me, pn, pctx->idtagNext); |
1351 | } |
1352 | /* */ |
1353 | if (1) { |
1354 | Nrrd *ntmp; |
1355 | ntmp = nrrdNew(); |
1356 | pullOutputGet(ntmp, NULL((void*)0), NULL((void*)0), NULL((void*)0), 0.0, pctx); |
1357 | nrrdSave("pos-init.nrrd", ntmp, NULL((void*)0)); |
1358 | nrrdNuke(ntmp); |
1359 | } |
1360 | /* */ |
1361 | pctx->tmpPointPtr = AIR_CAST(pullPoint **,((pullPoint **)(calloc(pn, sizeof(pullPoint*)))) |
1362 | calloc(pn, sizeof(pullPoint*)))((pullPoint **)(calloc(pn, sizeof(pullPoint*)))); |
1363 | pctx->tmpPointPerm = AIR_CAST(unsigned int *,((unsigned int *)(calloc(pn, sizeof(unsigned int)))) |
1364 | calloc(pn, sizeof(unsigned int)))((unsigned int *)(calloc(pn, sizeof(unsigned int)))); |
1365 | if (!( pctx->tmpPointPtr && pctx->tmpPointPerm )) { |
1366 | biffAddf(PULLpullBiffKey, "%s: couldn't allocate tmp buffers %p %p", me, |
1367 | AIR_VOIDP(pctx->tmpPointPtr)((void *)(pctx->tmpPointPtr)), AIR_VOIDP(pctx->tmpPointPerm)((void *)(pctx->tmpPointPerm))); |
1368 | airMopError(mop); return 1; |
1369 | } |
1370 | pctx->tmpPointNum = pn; |
1371 | |
1372 | /* now that all points have been added, set their energy to help |
1373 | inspect initial state */ |
1374 | for (binIdx=0; binIdx<pctx->binNum; binIdx++) { |
1375 | bin = pctx->bin + binIdx; |
1376 | for (pointIdx=0; pointIdx<bin->pointNum; pointIdx++) { |
1377 | point = bin->point[pointIdx]; |
1378 | point->energy = _pullPointEnergyTotal(pctx->task[0], bin, point, |
1379 | /* ignoreImage */ |
1380 | !pctx->haveScale, |
1381 | point->force); |
1382 | } |
1383 | } |
1384 | |
1385 | if (pctx->verbose) { |
1386 | printf("%s: all done. ", me); |
1387 | fflush(stdout__stdoutp); |
1388 | } |
1389 | airMopOkay(mop); |
1390 | return 0; |
1391 | } |
1392 | |
1393 | void |
1394 | _pullPointFinish(pullContext *pctx) { |
1395 | |
1396 | airFree(pctx->tmpPointPtr); |
1397 | airFree(pctx->tmpPointPerm); |
1398 | return ; |
1399 | } |