(file) Return to gapfill.c CVS log (file) (dir) Up to [Development] / JSOC / proj / libs / interpolate

  1 arta  1.1 #include <stdio.h>
  2           #include <stdlib.h>
  3           #include <time.h>
  4           #include <string.h>
  5           #include <math.h>
  6           #include <mkl.h>
  7           #include <omp.h>
  8 arta  1.10 #include <sys/param.h>
  9 arta  1.1  #include "cholesky_down.h"
 10            #include "gapfill.h"
 11 arta  1.10 
 12 arta  1.1  
 13            #define minval(x,y) (((x) < (y)) ? (x) : (y))
 14            #define maxval(x,y) (((x) < (y)) ? (y) : (x))
 15            
 16 arta  1.10 #define kInterpDataDir "proj/libs/interpolate/data"
 17            
 18 arta  1.1  struct work_struct {
 19             double *a,*rh,*a1b,*a1r,*a1x;
 20             int *wgood,*wbad;
 21            };
 22            
 23            void malloc_work(
 24            // Malloc work space for each thread
 25              int nsample,
 26              struct work_struct *work
 27            )
 28            {
 29              int malign=32;
 30            
 31              work->wgood=(int *)(MKL_malloc(nsample*sizeof(int),malign));
 32              work->wbad=(int *)(MKL_malloc(nsample*sizeof(int),malign));
 33              work->a=(double *)(MKL_malloc(nsample*nsample*sizeof(double),malign));
 34              work->rh=(double *)(MKL_malloc(nsample*sizeof(double),malign));
 35              work->a1b=(double *)(MKL_malloc(nsample*sizeof(double),malign));
 36              work->a1r=(double *)(MKL_malloc(nsample*sizeof(double),malign));
 37              work->a1x=(double *)(MKL_malloc(2*nsample*sizeof(double),malign));
 38            }
 39 arta  1.1  
 40            void free_work(
 41            // Free the workspace
 42              int nsample,
 43              struct work_struct *work
 44            )
 45            {
 46              MKL_free(work->wgood);
 47              MKL_free(work->wbad);
 48              MKL_free(work->a);
 49              MKL_free(work->rh);
 50              MKL_free(work->a1b);
 51              MKL_free(work->a1r);
 52              MKL_free(work->a1x);
 53            }
 54            
 55            int init_fill(
 56              int method, // Interpolation method
 57              double pnoise, // Level of photon noise for trade-off
 58              int order, // Interpolation order. Generally odd.
 59              int targetx, // Target point in x (normally (order-1)/2)
 60 arta  1.1    int targety, // Target point in y (normally (order-1)/2)
 61              struct fill_struct *pars, // Structure to save setup information etc.
 62 arta  1.10   char **filenamep, // Pointer to name of file to read covariance from.
 63                                // Set to actual file used if method > 0.
 64              const char *path // to data files read by this function.
 65 arta  1.1  )
 66            {
 67              double *acor;
 68              int nx=80;
 69              int malign=32;
 70              double t0,t1;
 71              FILE *fileptr;
 72              int i,j;
 73              int *offx,*offy,ox,oy;
 74              int nsample,inoise;
 75              double regul,pmin;
 76              double *a0,*rh0,*a0t,*rh0t;
 77              int info;
 78              char uplo[] = "U";
 79 arta  1.10   char buf[PATH_MAX];
 80 arta  1.1  
 81              pars->order=order;
 82            
 83              t0=dsecnd();
 84              switch (method) {
 85              case 0:
 86                pars->filename=strdup(*filenamep);
 87                break;
 88              case 8:
 89 arta  1.10     snprintf(buf, sizeof(buf), "%s/%s/acor1_08_80.txt", path, kInterpDataDir);
 90                pars->filename=strdup(buf);
 91 arta  1.1      break;
 92              case 9:
 93 arta  1.10     snprintf(buf, sizeof(buf), "%s/%s/acor1_09_80.txt", path, kInterpDataDir);
 94                pars->filename=strdup(buf);
 95 arta  1.1      break;
 96              case 10:
 97 arta  1.10     snprintf(buf, sizeof(buf), "%s/%s/acor1_10_80.txt", path, kInterpDataDir);
 98                pars->filename=strdup(buf);
 99 arta  1.1      break;
100              case 11:
101 arta  1.10     snprintf(buf, sizeof(buf), "%s/%s/acor1_11_80.txt", path, kInterpDataDir);
102                pars->filename=strdup(buf);
103 arta  1.1      break;
104              default:
105                printf("Unknown method in init_fill.\n");
106                return 1;
107                break;
108              }
109              fileptr = fopen (pars->filename,"r");
110              if (fileptr==NULL) {
111                printf("File not found in init_fill.\n");
112                return 1;
113              }
114              if (method != 0) {
115                if (filenamep != NULL) {
116                  *filenamep=strdup(pars->filename);
117                }
118              }
119              acor=(double *)(MKL_malloc(nx*nx*sizeof(double),malign));
120            //fread ((char*)acor,sizeof(double),nx*nx,fileptr);
121              for (i=0;i<nx*nx;i++) fscanf(fileptr,"%lf",acor+i);
122              fclose(fileptr);
123              t0=dsecnd()-t0;
124 schou 1.8  //printf("x0 %f\n",t0);
125 arta  1.1  
126              regul=pnoise*pnoise;
127              inoise=1;
128              pmin=regul*inoise;
129            
130              nsample=order*order;
131              t1=dsecnd();
132              offx=(int *)(MKL_malloc(nsample*sizeof(int),malign));
133              offy=(int *)(MKL_malloc(nsample*sizeof(int),malign));
134              for (i=0;i<nsample;i++) {
135                offx[i]=(i%order)-targetx;
136                offy[i]=(i/order)-targety;
137              }
138            // Set up complete matrix
139              pars->a0=(double *)(MKL_malloc(nsample*nsample*sizeof(double),malign));
140              pars->a00=(double *)(MKL_malloc(nsample*nsample*sizeof(double),malign));
141              pars->a0t=(double *)(MKL_malloc(nsample*nsample*sizeof(double),malign));
142              a0=pars->a0;
143              a0t=pars->a0t;
144              for (i=0;i<nsample;i++) {
145                for (j=0;j<nsample;j++) {
146 arta  1.1        ox=((offx[j]-offx[i])+nx) % nx;
147                  oy=((offy[j]-offy[i])+nx) % nx;
148                  a0[i+nsample*j]=acor[ox+nx*oy];
149                  a0t[i+nsample*j]=acor[ox+nx*oy];
150                }
151                a0[i+nsample*i]=a0[i+nsample*i]+regul;
152              }
153            // save copy of matrix
154              memcpy(pars->a00,a0,nsample*nsample*sizeof(double));
155              pars->acort00=acor[0];
156              pars->rh0=(double *)(MKL_malloc(nsample*sizeof(double),malign));
157              pars->rh0t=(double *)(MKL_malloc(nsample*sizeof(double),malign));
158              rh0=pars->rh0;
159              rh0t=pars->rh0t;
160              for (i=0;i<nsample;i++) {
161                rh0[i]=acor[(-offx[i]+nx) % nx+nx*((-offy[i]+nx) % nx)];
162                rh0t[i]=acor[(-offx[i]+nx) % nx+nx*((-offy[i]+nx) % nx)];
163                if ((offx[i]==0) && (offy[i]==0)) rh0[i]=rh0[i]+pmin;
164              }
165            // Decompose complete matrix
166              dpotrf(uplo,&nsample,pars->a0,&nsample,&info); // Cholesky decomposition
167 arta  1.1  
168              MKL_free(acor);
169              MKL_free(offx);
170              MKL_free(offy);
171            
172            // Variables used in further calculations. Avoids multiple mallocs.
173            //pars->wgood=(int *)(MKL_malloc(nsample*sizeof(int),malign));
174            //pars->wbad=(int *)(MKL_malloc(nsample*sizeof(int),malign));
175            
176              pars->hashmod=8191; // Hash table size
177              pars->hashcount=(int *)(MKL_malloc(pars->hashmod*sizeof(int),malign));
178              pars->hashtable=(struct fill_hash_struct **)(MKL_malloc(pars->hashmod*sizeof(struct fill_hash_struct *),malign));
179              pars->locks=(omp_lock_t *)(MKL_malloc(pars->hashmod*sizeof(omp_lock_t),malign));
180              pars->complocks=(omp_lock_t *)(MKL_malloc(pars->hashmod*sizeof(omp_lock_t),malign));
181            
182              for (i=0;i<pars->hashmod;i++) {
183                pars->hashcount[i]=0;
184            // Initialize to null pointers
185                pars->hashtable[i]=(struct fill_hash_struct *)NULL;
186                omp_init_lock(&(pars->locks[i]));
187                omp_init_lock(&(pars->complocks[i]));
188 arta  1.1    }
189              pars->ndiff=0;
190            
191              t1=dsecnd()-t1;
192 schou 1.8  //printf("x1 %f\n",t1);
193 arta  1.1  
194              return 0;
195            }
196            
197            int free_fill(
198            struct fill_struct *pars
199            )
200            {
201              int i;
202              struct fill_hash_struct *ptr,*oldptr;
203              
204 schou 1.8  /*
205 arta  1.1    printf("Hashmod: %d\n",pars->hashmod);
206              printf("Ndiff: %d\n",pars->ndiff);
207              for (i=0;i<pars->hashmod;i++) {
208                printf("%d %d\n",i,pars->hashcount[i]);
209              }
210 schou 1.6  */
211 schou 1.8  /*
212 arta  1.1    for (i=0;i<pars->hashmod;i++) {
213                ptr=(pars->hashtable[i]);
214                while (ptr != NULL) {
215 schou 1.7        printf("# %d %d %d\n",i,ptr->nbad,ptr->nhit);
216 arta  1.1        ptr=ptr->next;
217                }
218              }
219 schou 1.8  */
220 schou 1.3  
221              for (i=0;i<pars->hashmod;i++) {
222                omp_destroy_lock(&(pars->locks[i]));
223                omp_destroy_lock(&(pars->complocks[i]));
224              }
225            
226 arta  1.1    MKL_free(pars->a0);
227              MKL_free(pars->a00);
228              MKL_free(pars->a0t);
229              MKL_free(pars->rh0);
230              MKL_free(pars->rh0t);
231            
232              MKL_free(pars->locks);
233              MKL_free(pars->complocks);
234            
235            // Now free hash table and contents
236            
237              MKL_free(pars->hashcount);
238              for (i=0;i<pars->hashmod;i++) {
239                ptr=(pars->hashtable[i]);
240                while (ptr != NULL) {
241                  oldptr=ptr;
242                  MKL_free(ptr->wbad);
243                  MKL_free(ptr->coeff);
244                  ptr=ptr->next;
245                  MKL_free(oldptr);
246                }
247 arta  1.1    }
248              MKL_free(pars->hashtable);
249              free(pars->filename);
250            
251              return 0; // Currently no error conditions
252            
253            }
254            
255            int find_entry(
256              struct fill_struct *pars,
257              int hash0,
258              int hash,
259              int nbad,
260              int *wbad,
261              struct fill_hash_struct **ptr_out
262            )
263            {
264              int found;
265              int ident,i;
266              struct fill_hash_struct *ptr;
267              
268 arta  1.1    found=0;
269              *ptr_out=NULL;
270            
271            // Prevent update while starting traverse
272              omp_set_lock(&(pars->locks[hash]));
273              ptr=pars->hashtable[hash];
274              omp_unset_lock(&(pars->locks[hash]));
275            
276              while (ptr!=NULL) { // Not at end of table
277                if ((hash0==ptr->hash0) && (nbad==ptr->nbad)) {
278            // Original hash and number of elements is correct, so there is hope
279                  ident=1;
280                  for (i=0;i<nbad;i++) {
281                    if (wbad[i] != ptr->wbad[i]) {
282                      ident=0;
283                      break; // Out of for loop. Known not to match.
284                    }
285                  }
286                  if (ident != 0) { // Success
287 schou 1.7  #pragma omp atomic
288 arta  1.1          ptr->nhit++;
289                    found=1;
290                    *ptr_out=ptr;
291                    break; // Out of while loop. No need to test the rest.
292                  } // if
293                } // if
294                ptr=ptr->next;
295              } // while
296            
297              return found;
298            } // find_entry
299            
300            double fill_point(
301            struct fill_struct *pars,
302            int *mask,
303            double *vals,
304            float *cnorm,
305            float *ierror,
306            struct work_struct *work
307            )
308            {
309 arta  1.1    double t1,t2,t3,t4,t5,t6,t7,t8/*,t9*/;
310              int nsample;
311              int ngood,nbad;
312              int *wgood,*wbad;
313              int i,info,j;
314              char uplo[] = "U";
315              int ione = 1;
316              int itwo = 2;
317              int malign=32;
318              double *a,*a0,*rh0,/* *rh,*a1b,*/bta1b,/**a1r,*/bta1r,c,*coeff,*a0t,*a00,*a1x;
319              float fillval;
320              int hash0,hash,found;
321              struct fill_hash_struct *ptr;
322              double ierror2; // interpolation error squared
323              int unlocked;
324              int nleft;
325              double tdown,tbrute;
326              double sum;
327            
328              t1=0.0;t2=0.0;t3=0.0;t4=0.0;t5=0.0;t6=0.0;t7=0.0;t8=0.0;//t9=0.0;
329            
330 arta  1.1    t1=dsecnd();
331            
332              nsample=(pars->order)*(pars->order);
333              
334            // Make work copies
335              a0=pars->a0;
336              a00=pars->a00;
337              a0t=pars->a0t;
338              rh0=pars->rh0;
339            
340              wgood=work->wgood;
341              wbad=work->wbad;
342            
343              ngood=0;
344              nbad=0;
345              hash0=0;
346              for (i=0;i<nsample;i++) {
347                if (mask[i]==0) {
348                  wgood[ngood]=i;
349                  ngood=ngood+1;
350                }
351 arta  1.1      if (mask[i]!=0) {
352                  hash0=hash0+i;
353                  wbad[nbad]=i;
354                  nbad=nbad+1;
355                }
356              }
357              hash=hash0%pars->hashmod;
358            
359              unlocked=0;
360            
361              found=find_entry(pars,hash0,hash,nbad,wbad,&ptr);
362            
363              if (found == 0) {
364                unlocked=omp_test_lock(&(pars->complocks[hash])); // Capture lock status
365                if (unlocked==0) omp_set_lock(&(pars->complocks[hash]));
366            
367            // Rerun search. Someone may have updated while waiting for lock
368                found=find_entry(pars,hash0,hash,nbad,wbad,&ptr);
369                if (found!=0) {
370            // Clear lock
371                  omp_unset_lock(&(pars->complocks[hash]));
372 arta  1.1        found=2; // Indicate collision
373                }
374              }
375            
376              t1=dsecnd()-t1;
377            
378              if (found == 0) { // Got to calculate new coefficients
379            
380            //printf("New %d %d\n",omp_get_thread_num(),hash);
381            // malloc new entry
382            //for (i=0;i<nsample;i++) printf(" %d",mask[i]);
383            //printf("\n");
384                ptr=(struct fill_hash_struct *)(MKL_malloc(sizeof(struct fill_hash_struct),malign));
385                ptr->next=pars->hashtable[hash]; // Point to next element
386            // Set other variables
387                ptr->nbad=nbad;
388                ptr->hash0=hash0;
389                ptr->nhit=1;
390                ptr->wbad=(int *)(MKL_malloc(nbad*sizeof(int),malign));
391                for (i=0;i<nbad;i++) ptr->wbad[i]=wbad[i];
392                coeff=(double *)(MKL_malloc(ngood*sizeof(double),malign));
393 arta  1.1      pars->hashcount[hash]++; // Increment count for this hash
394            #pragma omp atomic
395                pars->ndiff++; // Increment count for total
396                ptr->coeff=coeff; // Point to new coefficients
397            
398            // Point to work arrays
399                a=work->a;
400                //rh=work->rh;
401                //a1b=work->a1b;
402                //a1r=work->a1r;
403                a1x=work->a1x;
404            
405            // Calculate new coefficients
406            // First estimate time for each option
407                tdown=0.0;
408                nleft=nsample;
409                for (i=nsample-1;i>=0;i--) {
410                  if (mask[i]!=0) {
411                    tdown=tdown+(nleft-i-1)*(nleft-i-1);
412                    nleft=nleft-1;
413                  }
414 arta  1.1      }
415                tdown=3.9e-9*tdown;
416                tbrute=4e-11*(ngood+0.0)*(ngood+0.0)*(ngood+0.0);
417            
418            // Constants in if statement based on timings
419            //  if (nbad < (1.50*sqrt(nsample)-6)) {
420                if (tdown<tbrute) {
421                  t2=dsecnd();
422            // Get new decomposition by downsampling old one
423            // Copy decomposed matrix.
424            // This dominates dcholesky_down when only removing a few points.
425            // Only need to copy relevant part of matrix
426            //    for (i=0;i<nsample;i++) for (j=0;j<=i;j++) a[i*nsample+j]=a0[i*nsample+j];
427                  dlacpy(uplo,&nsample,&nsample,a0,&nsample,a,&nsample);
428                  t2=dsecnd()-t2;
429                  t3=dsecnd();
430            
431            // Get decomposition of reduced matrix
432                  dcholesky_down_mask(uplo, &nsample, a, &nsample, mask, &info);
433                  t3=dsecnd()-t3;
434                } // if downsampling
435 arta  1.1      else {
436                  t4=dsecnd();
437            // Calculate brute force from original matrix
438            // Pick good points
439                  for (i=0;i<ngood;i++) for (j=0;j<=i;j++) a[i*nsample+j]=a00[wgood[i]*nsample+wgood[j]];
440                  t4=dsecnd()-t4;
441                  t5=dsecnd();
442            
443            // Get decomposition of reduced matrix
444                  dpotrf(uplo,&ngood,a,&nsample,&info); // Cholesky decomposition
445                  t5=dsecnd()-t5;
446                } // Brute force
447            
448                t6=dsecnd();
449            
450            /*
451                for (i=0;i<ngood;i++) a1b[i]=1.;
452                for (i=0;i<ngood;i++) a1r[i]=rh0[wgood[i]];
453                dpotrs(uplo,&ngood,&ione,a,&nsample,a1b,&nsample,&info);
454                dpotrs(uplo,&ngood,&ione,a,&nsample,a1r,&nsample,&info);
455                bta1b=0.;
456 arta  1.1      for (i=0;i<ngood;i++) bta1b=bta1b+a1b[i];
457                bta1r=0.0;
458                for (i=0;i<ngood;i++) bta1r=bta1r+a1r[i];
459                c=(bta1r-1.)/bta1b;
460                for (i=0;i<ngood;i++) coeff[i]=a1r[i]-c*a1b[i];
461                ptr->cnorm=dnrm2(&ngood,coeff,&ione);
462            */
463            
464            // Combine a1b and a1r and make single call to dpotrs
465                for (i=0;i<ngood;i++) a1x[i]=1.;
466                for (i=0;i<ngood;i++) a1x[i+nsample]=rh0[wgood[i]];
467                dpotrs(uplo,&ngood,&itwo,a,&nsample,a1x,&nsample,&info);
468                bta1b=0.;
469                for (i=0;i<ngood;i++) bta1b=bta1b+a1x[i];
470                bta1r=0.0;
471                for (i=0;i<ngood;i++) bta1r=bta1r+a1x[i+nsample];
472                c=(bta1r-1.)/bta1b;
473                for (i=0;i<ngood;i++) coeff[i]=a1x[i+nsample]-c*a1x[i];
474                ptr->cnorm=(float)dnrm2(&ngood,coeff,&ione);
475            
476                t6=dsecnd()-t6;
477 arta  1.1      t7=dsecnd();
478            
479            // Now get interpolation error
480                ierror2=0.0;
481                for (i=0;i<ngood;i++) ierror2=ierror2+coeff[i]*rh0[wgood[i]];
482                ierror2=pars->acort00-2*ierror2;
483            // Now calculate Sum_wood[i,j] coeff_i A0t_ij coeff_j
484                for (j=0;j<ngood;j++) {
485            /*
486                  sum=0.0;
487                  for (i=0;i<ngood;i++) {
488                    sum=sum+a0t[nsample*wgood[j]+wgood[i]]*coeff[i];
489                  }
490                  ierror2=ierror2+sum*coeff[j];
491            */
492            // a0t is symmetric, so this is more efficient
493                  sum=0.0;
494                  for (i=0;i<j;i++) {
495                    sum=sum+a0t[nsample*wgood[j]+wgood[i]]*coeff[i];
496                  }
497                  ierror2=ierror2+coeff[j]*(2*sum+coeff[j]*a0t[nsample*wgood[j]+wgood[j]]);
498 arta  1.1      }
499                ptr->ierror=(float)sqrt(ierror2/pars->acort00);
500            
501            // Stick new entry at beginning of linked list
502            // Prevent others from starting to traverse
503                omp_set_lock(&(pars->locks[hash]));
504                pars->hashtable[hash]=ptr;
505            #pragma omp flush
506                omp_unset_lock(&(pars->locks[hash]));
507            
508            // Done with computation
509                omp_unset_lock(&(pars->complocks[hash]));
510            
511                t7=dsecnd()-t7;
512            
513            // Could store coefficients in the other 7 rotations of the mask.
514            // Beware that the time for cholesky_down depends strongly on which
515            // one is calculated. See timep.pro for calculation (t2s is a good predictor).
516              } // End of calculating new coefficients
517            
518              t8=dsecnd();
519 arta  1.1    fillval=(float)ddot(&ngood,ptr->coeff,&ione,vals,&ione);
520              *cnorm=ptr->cnorm;
521              *ierror=ptr->ierror;
522            
523              t8=dsecnd()-t8;
524            
525            //printf("%d %d %d %d %d %f %f %f %f %f %f %f %f\n",hash,unlocked,found,omp_get_thread_num(),nbad,t1,t2,t3,t4,t5,t6,t7,t8);
526              return fillval;
527            }
528            
529            int fgap_fill(
530              struct fill_struct *pars,
531              float *im,
532              int nx,
533              int ny,
534              int nlead,
535              unsigned char *mask,
536              float *cnorm,
537              float *ierror
538            )
539            {
540 arta  1.1    const unsigned char maskgood=0; // Value of good entries in masks
541              const unsigned char maskfill=1; // Value of entries to be filled
542              const unsigned char masknofill=2; // Value of entries not to be filled
543              int malign=32;
544            //const int ione = 1;
545              int i,j,i1,j1,i0,j0,k;
546              int order,order2;
547              int ngood,nfill;
548              double *im1;
549              int *mask1;
550              float cnorm1,ierror1;
551              int nsample;
552              struct work_struct work;
553 schou 1.2    int nofill; // Number of pixels with maskfill=1 that could not be filled.
554 arta  1.1    //double t0;
555              
556              order=pars->order;
557              order2=order/2;
558              nsample=order*order;
559              
560            /*
561              int *fcount;
562              fcount=(int *)(MKL_malloc(ny*sizeof(int),malign));
563              t0=dsecnd();
564            #pragma omp parallel for private (i,j,nfill)
565              for (j=0; j<ny; j++) {
566                nfill=0;
567                for (i=0; i<nx; i++) {
568                  if (mask[j*nlead+i]==maskfill) nfill++;
569                }
570                fcount[j]=nfill;
571              }
572              printf("Count: %f\n",dsecnd()-t0);
573              MKL_free(fcount);
574            */
575 arta  1.1  
576            nfill=0;
577 schou 1.2  nofill=0;
578 arta  1.1  #pragma omp parallel default(none) \
579              private (im1,mask1,i,i0,i1,j,j0,j1,k,cnorm1,ierror1,ngood/*,t0*/)     \
580            shared(pars,im,nx,ny,nlead,mask,cnorm,ierror) \
581            shared(malign,order,order2) \
582            private(work) shared(nsample) \
583 schou 1.2  reduction(+:nfill) \
584            reduction(+:nofill)
585 arta  1.1  { // Needed to define parallel region
586            
587              im1=(double *)(MKL_malloc(order*order*sizeof(double),malign));
588              mask1=(int *)(MKL_malloc(order*order*sizeof(int),malign));
589            
590              malloc_work(nsample,&work);
591            //printf("malloc %d %lx %lx\n",omp_get_thread_num(),im1,mask1);
592            
593            //#pragma omp for schedule(dynamic,1)
594            //for (j=0; j<ny; j++) {
595            //  for (i=0; i<nx; i++) {
596            #pragma omp for schedule(dynamic,256)
597              for (k=0;k<nx*ny;k++) {{
598                    //t0=dsecnd();
599                i=k%nx;
600                j=k/nx;
601                  j0=j-order2;
602                  if (mask[j*nlead+i]==maskgood) {
603                    cnorm1=1.0f; // Random noise is 1
604                    ierror1=0.0f; // Interpolation error is 0
605                  }
606 arta  1.1        if (mask[j*nlead+i]==maskfill) { // Fill if mask=1. Skip for mask>1.
607                    i0=i-order2;
608                    ngood=0;
609                    for (j1=j0;j1<(j0+order);j1++) {
610                      for (i1=i0;i1<(i0+order);i1++) {
611                        if ((i1>=0) && (i1<nx) && (j1>=0) && (j1<ny)) {
612                          mask1[i1-i0+(j1-j0)*order]=mask[i1+j1*nlead];
613                          if (mask[j1*nlead+i1]==maskgood) {
614                            im1[ngood]=im[i1+j1*nlead];
615                            ngood=ngood+1;
616                          }
617                        } // Inside original image
618                        else { // Outside original image
619                          mask1[i1-i0+(j1-j0)*order]=1; // Point is missing
620                        }
621                      }
622                    }
623                    if (ngood != 0) { // Have at least one good point
624                       im[j*nlead+i]=(float)fill_point(pars,mask1,im1,&cnorm1,&ierror1,&work);
625                    } 
626                    else { // Otherwise quietly leave unchanged, except set errors
627 arta  1.1            cnorm1=0.0f;
628 schou 1.5            ierror1=2.0f;
629 schou 1.2            nofill=nofill+1;
630 arta  1.1          }
631                    nfill=nfill+1;
632                  } // end if mask==1
633                  if (mask[j*nlead+i]==masknofill) { // Don't fill.
634                    cnorm1=0.0f;
635 schou 1.5          ierror1=2.0f;
636 arta  1.1        }
637                  cnorm[j*nlead+i]=cnorm1;
638                  ierror[j*nlead+i]=ierror1;
639            //    cnorm[j*nlead+i]=dsecnd()-t0;
640            //    ierror[j*nlead+i]=omp_get_thread_num();
641                } // for i
642              } // for j
643            //printf("free %d %lx %lx\n",omp_get_thread_num(),im1,mask1);
644              MKL_free(im1);
645              MKL_free(mask1);
646              free_work(nsample,&work);
647            //printf("done %d %lx %lx\n",omp_get_thread_num(),im1,mask1);
648            } // End of parallel region
649 schou 1.8  //printf("nfill nofill %d %d\n",nfill,nofill);
650 arta  1.1  
651 schou 1.2    if (nofill != 0) {
652                return 1; // Could not fill all pixels
653              }
654              else {
655                return 0; // All is good
656              }
657 arta  1.1  }
658 schou 1.9  
659            char *gapfill_version() // Returns CVS version of gapfill.c
660            {
661 arta  1.10   return strdup("$Id: gapfill.c,v 1.9 2010/09/02 18:29:49 schou Exp $");
662 schou 1.9  }
663            
664            

Karen Tian
Powered by
ViewCVS 0.9.4