Create Xref-Html Frames                    Remove All Frames
file:d:/code/LRC/Splicer/splicer_code_ver2.2/splicer_data.c        (Tue Mar 14 16:29:12 2000 )


   1: /*
   2:   splicer_data.c
   3: 
   4:   data i/o and manipulation functions
   5: */
   6: #include <stdlib.h>
   7: #include <stdio.h>
   8: #include <search.h>
   9: #include <malloc.h>
  10: #include <stdlib.h>
  11: #include <math.h>
  12: #include <fcntl.h>
  13: #include <Xm/Text.h>
  14: #include <Xm/TextF.h>
  15: #include <X11/cursorfont.h>
  16: #include <sys/types.h>
  17: /*#include <sys/uil.h>*/
  18: #include <unistd.h>
  19: #include "splicer-creation-c.h"
  20: #include "splicer_vars.h"
  21: 
  22: 
  23: #define ODPKEYLEN (20)
  24: HashInfo  **hashinfo;
  25: extern  int hash_num;
  26: 
  27: int SpRead(fptr,dataptr)
  28: FILE  *fptr;
  29: DataFile  *dataptr;
  30: {
  31:   int value;
  32:   switch (dataptr->in_format)
  33:   {
  34:     case MST95REPORT:
  35:       value=SpReadMST95report(fptr,dataptr);
  36:       break;
  37:     case TKREPORT:
  38:       value=SpReadTKreport(fptr,dataptr);
  39:       break;
  40:     case ODPOTHER:
  41:                 case ODPOTHER1:
  42:                 case ODPOTHER2:
  43:                 case ODPOTHER3:
  44:                 case ODPOTHER4:
  45:                 case ODPOTHER5:
  46:       value=SpReadOtherOdp(fptr,dataptr);
  47:       break;
  48:                 case JANUSCLEAN:
  49:                 case JANUSORIG:
  50:                         value=SpReadJanus(fptr,dataptr);
  51:                         break;
  52:     default:
  53:       value=True;
  54:   }
  55:   return(value);
  56: }
  57: 
  58: void  SpAffine(ptr,affineinfo,flag)
  59: Hole  *ptr;
  60: AffineFile  affineinfo;
  61: int flag;
  62: {
  63:   int i;
  64:   float last_offset;
  65:   Core  *coreptr;
  66:   char    *odpkey;
  67:   char    *odpptr=odpkey,key_to_find[ODPKEYLEN+1];
  68:   HashInfo  *hashptr;
  69:   ENTRY   *found_item,item,*hsearch();
  70:   char  *name;
  71:   int fd,close();
  72: 
  73: 
  74: /* if no hash table, read stored file */
  75:   if(flag==CREATE_HASH)
  76:   {
  77:     if((hashinfo=SpReadAffineTable(affineinfo.filename,&hash_num))== NULL || message.error==True)
  78:     {
  79:       message.error=True;
  80:       return;
  81:     }
  82:     else
  83:     {
  84:                         if((charptr=(char*)calloc((int)strlen(affineinfo.filename)+50,CHAR_SIZE))==NULL)
  85:                                 SpBadMemAlloc("SpAffine 1c");
  86:       (void)sprintf(charptr,"\nAffine Table %s read",affineinfo.filename);
  87:                         have_affine = DO;
  88:       SpUpdateReport(charptr);
  89:       free(charptr);
  90: 
  91:                         XtSetSensitive(pushButtonOpenAffine,False);
  92:     }
  93:   
  94:   }
  95:         else
  96:         {
  97:         } 
  98: }
  99: 
 100: int SpEvalEquation(data_val,cull_equ)
 101: float   data_val;
 102: Equation  cull_equ;
 103: {
 104:   int qual1,qual2,qual;
 105: 
 106:   qual1=qual2=qual=GOOD;
 107:   if(cull_equ.sign1 == LESS_THAN && data_val<cull_equ.value1)
 108:     qual1 =BAD_CULL1;
 109:   else if(cull_equ.sign1 == LESS_THAN_OR_EQUAL_TO &&
 110:         data_val <= cull_equ.value1)
 111:     qual1 =BAD_CULL1;
 112:   else if(cull_equ.sign1 == GREATER_THAN && data_val>cull_equ.value1)
 113:     qual1 =BAD_CULL1;
 114:   else if(cull_equ.sign1 == GREATER_THAN_OR_EQUAL_TO &&
 115:       data_val>=cull_equ.value1)
 116:     qual1 =BAD_CULL1;
 117:   else if(cull_equ.sign1 == EQUAL_TO && data_val == cull_equ.value1)
 118:     qual1 =BAD_CULL1;
 119: 
 120:   if(cull_equ.join == ONLY)
 121:     qual=qual1;
 122:   else
 123:   {
 124:     if(cull_equ.sign2 == LESS_THAN && data_val<cull_equ.value2)
 125:       qual2 =BAD_CULL2;
 126:     else if(cull_equ.sign2 == LESS_THAN_OR_EQUAL_TO &&
 127:           data_val <= cull_equ.value2)
 128:       qual2 =BAD_CULL2;
 129:     else if(cull_equ.sign2 == GREATER_THAN && data_val>cull_equ.value2)
 130:       qual2 =BAD_CULL2;
 131:     else if(cull_equ.sign2 == GREATER_THAN_OR_EQUAL_TO &&
 132:           data_val>=cull_equ.value2)
 133:       qual2 =BAD_CULL2;
 134:     else if(cull_equ.sign2 == EQUAL_TO && data_val == cull_equ.value2)
 135:       qual2 =BAD_CULL2;
 136: 
 137:     if(cull_equ.join == OR)
 138:       qual=qual1|qual2;
 139:   }
 140: 
 141:   return(qual);
 142: }
 143: 
 144: 
 145: void SpCullTable(dataptr,name,flag)
 146: DataFile        *dataptr;
 147: char  *name;
 148: int flag;
 149: {
 150:   int   i,j,k,l;
 151:   char    *odpkey;
 152:   char    *odpptr=odpkey,key_to_find[ODPKEYLEN+1];
 153:         XmString        xmstring;
 154:         XEvent          event;
 155:   HashInfo  *hashptr;
 156:   Core    *coreptr;
 157:   ENTRY   *found_item,item,*hsearch();
 158: 
 159: /* if no hash table, read stored file */
 160:   if(flag==CREATE_HASH)
 161:   {
 162: 
 163:     if((hashinfo=SpReadCullTable(name,&hash_num))== NULL)
 164:     {
 165:       message.error=True;
 166:                         message.fatal=False;
 167:                         message.caller=NONE;
 168:                         message.type=XmDIALOG_WARNING;
 169:                         message.default_button=XmDIALOG_OK_BUTTON;
 170:       if((message.label=(char*)calloc((int)strlen(name)+100,CHAR_SIZE))==NULL)
 171:         SpBadMemAlloc("SpCullTable 1");
 172:       (void)sprintf(message.label,"Error reading Cull Table %s", name);
 173:       SpManageMessage(message);
 174:       return;
 175:     }
 176:     else
 177:     {
 178:       if((charptr=(char*)calloc((int)strlen(name)+100,CHAR_SIZE))==NULL)
 179:         SpBadMemAlloc("SpCullTable 1b");
 180:       (void)sprintf(charptr,"\nCull Table %s read",name);
 181:       SpUpdateReport(charptr);
 182:       free(charptr);
 183:     }
 184:   
 185:   }
 186: 
 187:   /* search hash table for values */
 188:         for(k=0; k<dataptr->numholes; ++k)
 189:         {
 190:     for(i=0;i<dataptr->holes[k]->numcores;i++)
 191:     {
 192: 
 193:                         if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
 194:                                         SpBadMemAlloc("SpCullTable 1");
 195:                         (void)sprintf(charptr,"\nData : Culling using cull table; hole %c.", dataptr->holes[k]->name);
 196:                         if(i == 0) {
 197:                           SpUpdateReport(charptr);
 198:                         }
 199:                         (void)sprintf(charptr,"\nData : Culling using cull table; hole %c core %d", 
 200:                                           dataptr->holes[k]->name, dataptr->holes[k]->core[i]->num);
 201:                         xmstring=XmStringCreateLocalized(&charptr[1]);
 202:                         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
 203:                         XmStringFree(xmstring);
 204:                         free(charptr);
 205:                         XmUpdateDisplay(messageBoxWorking);
 206:                         /* check to see if the stop read button was pushed
 207:                         */
 208:                         while(XCheckMaskEvent(XtDisplay(messageBoxWorking), ButtonPressMask, &event)) {
 209:                           if(event.xany.window == XtWindow(messageBoxWorking)) {
 210:                             XtDispatchEvent(&event);
 211:                             message.error = True;
 212:                             message.fatal=False;
 213:                             message.default_button=XmDIALOG_OK_BUTTON;
 214:                             message.type=XmDIALOG_WARNING;
 215:                             message.caller=NONE;
 216:                             if((message.label=(char*)calloc(500,CHAR_SIZE))==NULL)
 217:                                         SpBadMemAlloc("SpCullTable");
 218:                             (void)sprintf(message.label,"Data input has been stopped.\n");
 219:                             (void)strcat(message.label, "An attempt to clear has been made but program may be unstable.");
 220:                             return;
 221:                           }
 222:                           else {
 223:                           }
 224:                         }
 225: 
 226:       for(j=0;j<dataptr->holes[k]->core[i]->numvalues;j++)
 227:       {
 228:                           coreptr=dataptr->holes[k]->core[i];
 229:                           for(l=0; l<hash_num; ++l)
 230:                           {
 231:                             if(dataptr->leg == hashinfo[l]->leg &&
 232:                                dataptr->site == hashinfo[l]->site &&
 233:                                dataptr->holes[k]->name == hashinfo[l]->hole &&
 234:                                coreptr->num == hashinfo[l]->core &&
 235:                                strcmp(coreptr->value[j]->section, hashinfo[l]->section) == 0)
 236:                             {
 237:                               if(fabs(coreptr->value[j]->top_int - hashinfo[l]->top_int) <= CULLTABLEDEPTHCHECK) 
 238:                               {
 239:                                 coreptr->value[j]->quality=coreptr->value[j]->quality|BAD_CULLTABLE;
 240:                               }
 241:                             }
 242:                           }
 243:       }
 244:     }
 245:   }
 246:   if(flag==DESTROY_HASH>0)
 247:   {
 248:     for(i=0;i<hash_num;i++)
 249:     {
 250:       if(hashinfo[i])
 251:       {
 252:         free(hashinfo[i]);
 253:         hashinfo[i]=NULL;
 254:       }
 255:     }
 256:     hash_num=0;
 257:     if(hashinfo)
 258:     {
 259:       free(hashinfo);
 260:       hashinfo=NULL;
 261:     }
 262:     hdestroy();
 263:   }
 264: }
 265: 
 266: void  SpCull(dataptr,type,cullinfo,flag)
 267: DataFile  *dataptr;
 268: int   type;
 269: Cull  cullinfo;
 270: int flag;
 271: {
 272:   int i,j,k;
 273:   Core  *coreptr;
 274:   Value *valueptr;
 275:         XmString  xmstring;
 276:         XEvent    event;
 277: 
 278:   if(cullinfo.top> 0) /* remove top portion of core */
 279:   {
 280:             if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
 281:                                         SpBadMemAlloc("SpCull");
 282:             (void)sprintf(charptr,"\nData : Culling core tops.");
 283:             SpUpdateReport(charptr);
 284:             xmstring=XmStringCreateLocalized(&charptr[1]);
 285:             XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
 286:             XmStringFree(xmstring);
 287:             free(charptr);
 288:             XmUpdateDisplay(messageBoxWorking);
 289: 
 290:             for(k=0; k<dataptr->numholes; ++k) 
 291:             {
 292:     for(i=0;i<dataptr->holes[k]->numcores; i++)
 293:     {
 294:       coreptr=dataptr->holes[k]->core[i];
 295:                         if(coreptr->numvalues > 0) 
 296:                         {
 297:                             j = 0;
 298:                 while(strcmp(coreptr->value[j]->section, "1")==0 &&
 299:             coreptr->value[j]->top_int < cullinfo.top)
 300:                             {
 301:           coreptr->value[j]->quality=coreptr->value[j]->quality|BAD_TOP;
 302:                                         ++j;
 303:                                         if(j >= coreptr->numvalues) {
 304:                                           break;
 305:                                         }
 306:                             }
 307:       }
 308:     }
 309:              }
 310:   }
 311:  
 312:         /* check to see if the stop read button was pushed
 313:         */
 314:         while(XCheckMaskEvent(XtDisplay(messageBoxWorking), ButtonPressMask, &event)) {
 315:           if(event.xany.window == XtWindow(messageBoxWorking)) {
 316:             XtDispatchEvent(&event);
 317:             message.error = True;
 318:             message.fatal=False;
 319:             message.default_button=XmDIALOG_OK_BUTTON;
 320:             message.type=XmDIALOG_WARNING;
 321:             message.caller=NONE;
 322:             if((message.label=(char*)calloc(500,CHAR_SIZE))==NULL)
 323:                                 SpBadMemAlloc("SpCull");
 324:             (void)sprintf(message.label,"Data input has been stopped.\n");
 325:             (void)strcat(message.label, "An attempt to clear has been made but program may be unstable.");
 326:             return;
 327:           }
 328:           else {
 329:           }
 330:         }
 331: 
 332:   if(cullinfo.by_core_num)  /* remove cores > given number */
 333:   {
 334:              if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
 335:                                         SpBadMemAlloc("SpCull");
 336:             (void)sprintf(charptr,"\nData : Culling cores.");
 337:             SpUpdateReport(charptr);
 338:             xmstring=XmStringCreateLocalized(&charptr[1]);
 339:             XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
 340:             XmStringFree(xmstring);
 341:             free(charptr);
 342:             XmUpdateDisplay(messageBoxWorking);
 343: 
 344:              for(k=0; k<dataptr->numholes; ++k)
 345:              {
 346:     for(i=0;i<dataptr->holes[k]->numcores;i++)
 347:     {
 348:       if(dataptr->holes[k]->core[i]->num > cullinfo.max_core)
 349:       {
 350:         coreptr=dataptr->holes[k]->core[i];
 351:         for(j=0;j<coreptr->numvalues;j++)
 352:           coreptr->value[j]->quality=coreptr->value[j]->quality|BAD_CORE_NUM;
 353:       }
 354:     }
 355:               }
 356:   }
 357: 
 358:   if(cullinfo.method==CULL_PARAMETERS || cullinfo.method == CULL_PARAMETER_AND_TABLE)
 359:   {
 360:             for(k=0; k<dataptr->numholes; ++k) 
 361:             {
 362:                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
 363:                                         SpBadMemAlloc("SpCull");
 364:                 (void)sprintf(charptr,"\nData : Culling using parameters; hole %c.", dataptr->holes[k]->name);
 365:                 SpUpdateReport(charptr);
 366:                 xmstring=XmStringCreateLocalized(&charptr[1]);
 367:                 XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
 368:                 XmStringFree(xmstring);
 369:                 free(charptr);
 370:                 XmUpdateDisplay(messageBoxWorking);
 371: 
 372:                 /* check to see if the stop read button was pushed
 373:                 */
 374:                 while(XCheckMaskEvent(XtDisplay(messageBoxWorking), ButtonPressMask, &event)) {
 375:                   if(event.xany.window == XtWindow(messageBoxWorking)) {
 376:                     XtDispatchEvent(&event);
 377:                     message.error = True;
 378:                     message.fatal=False;
 379:                     message.default_button=XmDIALOG_OK_BUTTON;
 380:                     message.type=XmDIALOG_WARNING;
 381:                     message.caller=NONE;
 382:                     if((message.label=(char*)calloc(500,CHAR_SIZE))==NULL)
 383:                                         SpBadMemAlloc("SpCull");
 384:                     (void)sprintf(message.label,"Data input has been stopped.\n");
 385:                     (void)strcat(message.label, "An attempt to clear has been made but program may be unstable.");
 386:                     return;
 387:                   }
 388:                   else {
 389:                   }
 390:                 }
 391: 
 392:     for(i=0;i<dataptr->holes[k]->numcores;i++)
 393:     {
 394:       coreptr=dataptr->holes[k]->core[i];
 395:       for(j=0;j<coreptr->numvalues;j++) /* loop through data */
 396:       {
 397:         valueptr=coreptr->value[j];
 398:         if(type==GRAPE)
 399:           valueptr->quality= valueptr->quality|SpEvalEquation(*valueptr->data,cullinfo.grape);
 400:         else if(type==PWAVE)
 401:         {
 402:           valueptr->quality= valueptr->quality|SpEvalEquation(*valueptr->data,cullinfo.pwave);
 403:                                         if(dataptr->in_format == MST95REPORT) 
 404:                                         {
 405:             if(valueptr->pwave->sig_strength < cullinfo.pwave_signal_max)
 406:               valueptr->quality=valueptr->quality|BAD_PWAVE_SIGNAL;
 407:                                         }
 408:         }
 409:         else if(type==SUSCEPTIBILITY)
 410:           valueptr->quality=valueptr->quality| SpEvalEquation(*valueptr->data,cullinfo.susceptibility);
 411:         else if(type==NATURALGAMMA)
 412:           valueptr->quality=valueptr->quality|SpEvalEquation(*valueptr->data,cullinfo.naturalgamma);
 413:         else if(type==REFLECTANCEMST)
 414:           valueptr->quality= valueptr->quality|SpEvalEquation(*valueptr->data,cullinfo.reflectance);
 415:                                 else if(type==OTHERTYPE)
 416:                                         valueptr->quality=valueptr->quality|SpEvalEquation(*valueptr->data,cullinfo.otherodp);
 417:         else
 418:           valueptr->quality=valueptr->quality|SpEvalEquation(*valueptr->data,cullinfo.otherodp);
 419:       }
 420:     }
 421:              }
 422:   }
 423:   if(cullinfo.method==CULL_TABLE || cullinfo.method == CULL_PARAMETER_AND_TABLE)
 424: 
 425:     SpCullTable(dataptr,cullinfo.filename,flag);
 426: }
 427: 
 428: void  SpSmooth(ptr)
 429: Hole  *ptr;
 430: {
 431:   int i,j,k,l,m,n,num_interp=0,inc,datptr_cnt,max_depths=0,num_depths=0,this_num=0,end_cnt,highfound,lowfound;
 432:   float halfwidth,*weight,target,end_depth;
 433:   float *datptr,*sm_datptr,start_depth;
 434:   double  rint();
 435:   Core  *coreptr;
 436:   void  gauss_weights();
 437: 
 438:   /* use gaussian filter */
 439:   if(smooth.method==GAUSSIAN)
 440:   {
 441:     /* must use an odd number of weights */
 442:     if(smooth.width%2==0)
 443:       smooth.width+=1;
 444:     halfwidth=(int)((smooth.width-1)/2);
 445:     /* get filter weights */
 446:     if((weight=(float*)calloc(smooth.width+1,sizeof(float)))==NULL)
 447:       SpBadMemAlloc("SpSmooth");
 448:     gauss_weights(smooth.width,weight);
 449:     /* allocate storage arrays */
 450:     if(smooth.width_units==POINTS)
 451:     {
 452:       sm_datptr=NULL;
 453:       if((datptr=(float*)calloc(smooth.width+1,sizeof(float)))==NULL)
 454:                                 SpBadMemAlloc("SpSmooth");
 455:     }
 456:     else
 457:     {
 458:       max_depths=0;
 459:       for(i=0;i<ptr->numcores;i++)
 460:       {
 461:         coreptr=ptr->core[i];
 462:         this_num=(coreptr->value[coreptr->numvalues-1]->sb_depth-coreptr->value[0]->sb_depth)*100;
 463:         if(this_num> max_depths) max_depths=this_num;
 464:       }
 465:       max_depths+=2;
 466:       if((sm_datptr=(float*)calloc(max_depths,sizeof(float)))==NULL)
 467:                                 SpBadMemAlloc("SpSmooth");
 468:       if((datptr=(float*)calloc(max_depths,sizeof(float)))==NULL)
 469:                                 SpBadMemAlloc("SpSmooth");
 470:     }
 471: 
 472:     /* loop through cores */
 473:     for(i=0;i<ptr->numcores;i++)
 474:     {
 475:       coreptr=ptr->core[i];
 476:       coreptr->smooth_status = NONE;
 477:       if(smooth.width_units==POINTS)
 478:       {
 479:         /* loop through data (first and last "halfwidth" values are same as raw data if good! */
 480:         for(j=0;j<halfwidth && j<coreptr->numvalues;j++)
 481:         {
 482:           if(coreptr->value[j]->quality == GOOD)
 483:           {
 484:             coreptr->value[j]->sm_data=*coreptr->value[j]->data;
 485:             coreptr->value[j]->smooth_ok = SMTAIL;
 486:           }
 487:           else
 488:           {
 489:             coreptr->value[j]->smooth_ok = SMBADDATA;
 490:           }
 491:         }
 492: 
 493:         if(j>= coreptr->numvalues)
 494:         {
 495:           coreptr->smooth_status = SMTOOFEWPTS;
 496:         }
 497:         else
 498:         {
 499:           /* loop through data until at last half width */
 500:           for(;j<coreptr->numvalues-halfwidth;j++)
 501:           {
 502:             /* let smooth be ok until proven otherwise */
 503:             coreptr->value[j]->smooth_ok = SMOK;
 504:             inc=j-halfwidth;    /* first value in smoothing */
 505:             /* raw value at this point must be good */
 506:             if(coreptr->value[j]->quality!=GOOD)
 507:             {
 508:               coreptr->value[j]->smooth_ok = SMBADDATA;
 509:             }
 510:             /* fill data arrays */
 511:             for(k=inc,num_interp=0,datptr_cnt=0;datptr_cnt<smooth.width && k<coreptr->numvalues &&
 512:                                                         !(coreptr->value[j]->quality);k++,datptr_cnt++)
 513:             {
 514:               if(coreptr->value[k]->quality==GOOD)
 515:               {
 516:                 datptr[datptr_cnt]=*coreptr->value[k]->data;
 517:               }
 518:               else      /* interpolate data point */
 519:               {
 520:                 /* find next lower point in width range */
 521:                 for(l=k-1;l>=inc && coreptr->value[l]->quality!=GOOD;l--);
 522:                 if(l<inc)       /* no lower point in range */
 523:                 {
 524:                   coreptr->value[j]->smooth_ok = SMTOOFEWPTS;
 525:                 }
 526:                 else
 527:                 {
 528:                   /* find next higher point in width range */
 529:                   for(m=k+1;m<=j+halfwidth && coreptr->value[m]->quality!=GOOD;m++);
 530:                   if(m>j+halfwidth)     /* no higher point in range */
 531:                   {
 532:                     coreptr->value[j]->smooth_ok = SMTOOFEWPTS;
 533:                   }
 534:                   else
 535:                   {
 536:                     datptr[datptr_cnt]=*coreptr->value[l]->data+(*coreptr->value[m]->data -
 537:                                                                 *coreptr->value[l]->data)*
 538:                                 (coreptr->value[m]->sb_depth-coreptr->value[l]->sb_depth)/
 539:                                                         coreptr->value[k]->sb_depth;
 540:                     num_interp++;
 541:                   }
 542:                 }
 543:               }
 544:             }
 545:             if(num_interp>halfwidth)
 546:             {
 547:               coreptr->value[j]->smooth_ok = SMBADCALC;
 548:             }
 549:             /* compute smoothed value */
 550:             if(coreptr->value[j]->smooth_ok < SMOK)
 551:             {
 552:             }
 553:             else if(!coreptr->value[j]->quality)
 554:             {
 555:               coreptr->value[j]->sm_data=0.0;
 556:               for(k=0;k<smooth.width;k++)
 557:                 coreptr->value[j]->sm_data+=datptr[k]*weight[k+1];
 558:             }
 559:             else
 560:             {
 561:               coreptr->value[j]->smooth_ok = SMBADCALC;
 562:             }
 563:           }
 564: 
 565:           if(j<coreptr->numvalues)
 566:           {
 567:             /* loop through last half width values */
 568:             for(;j<coreptr->numvalues;j++)
 569:             {
 570:               if(coreptr->value[j]->quality == GOOD)
 571:               {
 572:                 coreptr->value[j]->sm_data=*coreptr->value[j]->data;
 573:                 coreptr->value[j]->smooth_ok = SMTAIL;
 574:               }
 575:               else
 576:               {
 577:                 coreptr->value[j]->smooth_ok = SMBADDATA;
 578:               }
 579:             }
 580:           }
 581: 
 582:           /* check if have some smoothed points
 583:           */
 584:           n = 0;
 585:           for(j=0; j<coreptr->numvalues; ++j)
 586:           {
 587:             if(coreptr->value[j]->smooth_ok == SMOK || coreptr->value[j]->smooth_ok == SMTAIL)
 588:             {
 589:               ++n;
 590:             }
 591:           }
 592:           if(n < TOOFEWSMOOTHED)
 593:           {
 594:             coreptr->smooth_status = SMTOOFEWPTS;
 595:           }
 596:           if(coreptr->smooth_status == NONE) {
 597:             coreptr->smooth_status = SMOK;
 598:           }
 599:         }
 600:       }
 601: 
 602:       else if(smooth.width_units==DEPTH)
 603:       {
 604:         /* find first & last good points */
 605:         for(j=0;j<coreptr->numvalues && coreptr->value[j]->quality!=GOOD ;j++);
 606:         for(k=coreptr->numvalues-1;k>=0 && coreptr->value[k]->quality!=GOOD;k--);
 607:         end_cnt=k;
 608:         if(end_cnt<0 || j>=coreptr->numvalues)
 609:         {
 610:           coreptr->smooth_status = SMTOOFEWPTS;
 611:         }
 612:         else
 613:         {
 614:           start_depth=coreptr->value[j]->sb_depth*100.0;
 615:           end_depth=coreptr->value[end_cnt]->sb_depth*100.0;
 616:           num_depths=1+end_depth-start_depth;
 617:           if(num_depths<=halfwidth)
 618:           {
 619:             coreptr->smooth_status = SMTOOFEWPTS;
 620:           }
 621:           else if(num_depths>max_depths)
 622:           {
 623:             coreptr->smooth_status = SMTOOFEWPTS;
 624:           }
 625:           else
 626:           {
 627:             /* interpolate 1 cm array of entire core */
 628:             datptr[l=0]=*coreptr->value[j]->data;
 629:             for(m=j,l++,target=start_depth+1;target<end_depth && l<max_depths;target++,l++)
 630:             {
 631:               /* find value >= to target value */
 632:               highfound=lowfound=False;
 633:               while(m<coreptr->numvalues - 1 && k>=0 && !(lowfound&highfound))
 634:               {
 635:                 if(!highfound && !(target<=rint((double)(coreptr->value[m]->sb_depth*100))
 636:                                                         && coreptr->value[m]->quality==GOOD))
 637:                   m++;
 638:                 else if(!highfound)
 639:                 {
 640:                   highfound=True;
 641:                   k=m;
 642:                 }
 643:                 else
 644:                 {
 645:                   if(!(target>rint((double)(coreptr->value[k]->sb_depth*100))&&
 646:                                         coreptr->value[k]->quality==GOOD))
 647:                     k--;
 648:                   else
 649:                     lowfound=True;
 650:                 }
 651:               }
 652:               if(m>=coreptr->numvalues || k<0)
 653:               {
 654:                 coreptr->smooth_status = SMTOOFEWPTS;
 655:               }
 656:               else {
 657:                 if(target==rint((double)(coreptr->value[m]->sb_depth*100)))       /* exact match */
 658:                                         datptr[l]=*coreptr->value[m]->data;
 659:                 else /* interpolate */
 660:                   datptr[l]=*coreptr->value[k]->data+(*coreptr->value[m]->data -*coreptr->value[k]->data)*
 661:                                                         (target/100.0-coreptr->value[k]->sb_depth)/
 662:                                         (coreptr->value[m]->sb_depth-coreptr->value[k]->sb_depth);
 663:               }
 664:             }
 665:             if(l>max_depths)
 666:             {
 667:               coreptr->smooth_status = SMTOOFEWPTS;
 668:             }
 669:             if(coreptr->smooth_status == NONE)
 670:             {
 671:               datptr[l]=*coreptr->value[end_cnt]->data;
 672:               /* smooth data array */
 673:               /* loop through data (first and last "halfwidth" values are same as raw data */
 674:               for(j=0;j<halfwidth;j++)
 675:                 sm_datptr[j]=datptr[j];
 676:               /* compute smoothed value */
 677:               for(;j<num_depths-halfwidth;j++)
 678:               {
 679:                 sm_datptr[j]=0.0;
 680:                 for(k=0,l=j-halfwidth+1;k<smooth.width;k++,l++)
 681:                   sm_datptr[j]+=datptr[l]*weight[k+1];
 682:               }
 683:               /* loop through last half width values */
 684:               for(;j<num_depths;j++)
 685:                 sm_datptr[j]=datptr[j];
 686:               /* fill in real smoothed array */
 687:               for(j=0;j<coreptr->numvalues;j++)
 688:               {
 689:                 if(coreptr->value[j]->quality != GOOD)
 690:                 {
 691:                   coreptr->value[j]->smooth_ok = SMBADDATA;
 692:                 }
 693:                 else
 694:                 {
 695:                   if(rint((double)(coreptr->value[j]->sb_depth*100.0))<(start_depth+halfwidth))
 696:                   {
 697:                     coreptr->value[j]->sm_data=*coreptr->value[j]->data;
 698:                                                coreptr->value[j]->smooth_ok = SMTAIL;
 699:                   }
 700:                   else if(rint((double)(coreptr->value[j]->sb_depth*100.0))>(end_depth-halfwidth))
 701:                   {
 702:                     coreptr->value[j]->sm_data=*coreptr->value[j]->data;
 703:                                               coreptr->value[j]->smooth_ok = SMTAIL;
 704:                   }
 705:                   else
 706:                   {
 707:                     k=(int)(rint((double)(coreptr->value[j]->sb_depth*100.0))-start_depth);
 708:                     coreptr->value[j]->sm_data=sm_datptr[k];
 709:                     coreptr->value[j]->smooth_ok = SMOK;
 710:                   }
 711:                 }
 712:               }
 713:               coreptr->smooth_status = SMOK;
 714:             }
 715:           }
 716:         }
 717:       }
 718:     }
 719: 
 720: 
 721:     if(sm_datptr) 
 722:     {
 723:       free(sm_datptr);
 724:       sm_datptr=NULL;
 725:     }
 726:     if(datptr)
 727:     {
 728:       free(datptr);
 729:       weight=NULL;
 730:     }
 731:     if(weight)
 732:     {
 733:       free(weight);
 734:       weight=NULL;
 735:     }
 736:   }
 737: 
 738:   /* if smooth method other */
 739:   else
 740:   {
 741:   }
 742: 
 743: }
 744:   
 745: void  SpDecimate(ptr,deci_num)
 746: Hole  *ptr;
 747: int deci_num;
 748: {
 749:   int i,j;
 750:   Core  *coreptr;
 751: 
 752:   for(i=0;i<ptr->numcores; i++)
 753:   {
 754:     coreptr=ptr->core[i];
 755:     for(j=0;j<coreptr->numvalues;j++)
 756:     {
 757:       if(j%deci_num!=0)
 758:         coreptr->value[j]->quality=coreptr->value[j]->quality|DECIMATED;
 759:     }
 760:   }
 761: }
 762: 
 763: int current_file=0,lineno=0,current_hole_num=0;
 764: char  *nameptr;
 765: FILE  *fptr;
 766: 
 767: int SpOutputData(client_data)
 768: XtPointer client_data;
 769: {
 770:   char    *filename,*out_prefix,*out_suffix;
 771:   XmString  xmstring;
 772:   FILE    *outptr;
 773:   int SpWriteData();
 774:   
 775: /* open file if necessary */
 776:   if(current_hole_num<data[dset]->numholes)
 777:   {
 778:   /* find current file name */
 779:     out_prefix=XmTextFieldGetString(textFieldOutputPrefix);
 780:     out_suffix=XmTextFieldGetString(textFieldOutputSuffix);
 781:                 if((filename=(char*)calloc((int)strlen(out_prefix) + (int)strlen(out_suffix) + (int)strlen(outdata_dirname) + 20,CHAR_SIZE))==NULL)
 782:                                   SpBadMemAlloc("SpOutputData");
 783:     (void)sprintf(filename,"%s%s%d%c.%s",outdata_dirname,out_prefix,data[dset]->site,data[dset]->holes[current_hole_num]->name,
 784:         out_suffix);
 785:     XtFree(out_prefix);
 786:     XtFree(out_suffix);
 787:   /* open file */
 788:     if((outptr=fopen(filename,"w"))==NULL)
 789:     {
 790:       message.error=True;
 791:       message.fatal=False;
 792:       message.caller=OUTPUTDATA;
 793:                         message.type=XmDIALOG_WARNING;
 794:                         message.default_button=XmDIALOG_OK_BUTTON;
 795:       if((message.label=(char*)calloc((int)strlen(filename)+50,CHAR_SIZE))==NULL)
 796:         SpBadMemAlloc("SpOutputData 1");
 797:       (void)sprintf(message.label,"Cannot write to output file %s.",filename);
 798:       message.default_button=XmDIALOG_OK_BUTTON;
 799:       message.type=XmDIALOG_ERROR;
 800:       SpManageMessage(message);
 801:     }
 802:     else
 803:     {
 804:   /* update message in working dialog */
 805:       
 806:       if((charptr=(char*)calloc((int)strlen(filename)+50,CHAR_SIZE))==NULL)
 807:         SpBadMemAlloc("SpOutputData 2");
 808:       (void)sprintf(charptr,"Output : Writing to file %s ",filename);
 809:       xmstring=XmStringCreateLocalized(charptr);
 810:       XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring,NULL);
 811:       XmStringFree(xmstring);
 812:       free(charptr);
 813:     }
 814:   /* write this hole */
 815:     (void)SpWriteData(outptr,data[dset]->holes[current_hole_num]);
 816:     current_hole_num++;
 817:     fclose(outptr);
 818:                 free(filename);
 819:   }
 820:   else
 821:   {
 822:   /* all holes written */
 823:     current_hole_num=0;
 824:     XtUnmanageChild(messageBoxWorking);
 825:     return(True);
 826:   }
 827:   return(False);
 828: }
 829: int SpInputData(client_data)
 830: XtPointer client_data;
 831: {
 832:   int i,j,hashflag, len, err, col, skip;
 833:   Boolean switched=False;
 834:   Hole  *tmphole;
 835:         String str;
 836:   XmString  xmstring;
 837:         int FindMinMax(), 
 838:             CheckDepthInDescendingOrder(),
 839:             CheckCoreAndDepthOrder(), 
 840:             MakeSplice(), 
 841:             CheckHowManyCulled();
 842:         void SetMinMax(),
 843:              MakeNewAffineTable(),
 844:              MapHoleToAffineTable(),
 845:              MapCoreToAffineTable(),
 846:              CheckAffineTableMissingHole(),
 847:              DrawDrawingAreaEdit(),
 848:              DrawDrawingAreaView(),
 849:              PlotSpliceVsAge();
 850: 
 851:   if(current_file==0 && !done_reading)
 852:   {
 853:                 reason_for_redraw = NONE;
 854:     done_reading=False;
 855:     if(smooth.method!=NONE)
 856:       done_smooth=False;
 857:     else
 858:       done_smooth=True;
 859:     if(decimate_value>1)
 860:       done_decimate=False;
 861:     else
 862:       done_decimate=True;
 863:     if(cull.method!=NONE)
 864:       done_cull=False;
 865:     else
 866:       done_cull=True;
 867:     if(affine.usetable)
 868:       done_affine=False;
 869:     else
 870:       done_affine=True;
 871: 
 872:                 /* if data format is ODP Other get the column number for data value
 873:                 */
 874:                 if(openfileinfo.in_data_format == ODPOTHER || openfileinfo.in_data_format == ODPOTHER1 ||
 875:                    openfileinfo.in_data_format == ODPOTHER2 || openfileinfo.in_data_format == ODPOTHER3 ||
 876:                    openfileinfo.in_data_format == ODPOTHER4 || openfileinfo.in_data_format == ODPOTHER5)
 877:                 {
 878:                   str = XmTextGetString(textFieldOpenFormatOtherValueColumn);
 879:                   openfileinfo.other_format_value_col = atoi(str);
 880:                   XtFree(str);
 881: 
 882:                   /* make the format
 883:                   */
 884:                   (void)sprintf(openfileinfo.other_format, "");
 885:                   switch (openfileinfo.in_data_format)
 886:                   {
 887:                        case    ODPOTHER:
 888:                        case    ODPOTHER1:
 889:                                (void)strcpy(openfileinfo.other_format, "%d %d %c %d %c %s %f %f %f");
 890:                                col = 9;
 891:                                break;
 892:                        case    ODPOTHER2:
 893:                                (void)strcpy(openfileinfo.other_format, "%d %c %d %c %s %f %f %f");
 894:                                col = 8;
 895:                                break;
 896:                        case    ODPOTHER3:
 897:                                (void)strcpy(openfileinfo.other_format, "%d %c %d %s %f %f %f");
 898:                                col = 7;
 899:                                break;
 900:                        case    ODPOTHER4:
 901:                                (void)strcpy(openfileinfo.other_format, "%d %c %d %s %f %f");
 902:                                col = 6;
 903:                                break;
 904:                        case    ODPOTHER5:
 905:                                (void)strcpy(openfileinfo.other_format, "%d %d %c %d %c %s %f %f");
 906:                                col = 8;
 907:                                break;
 908:                        default:
 909:                                message.error=True;
 910:                                message.fatal=False;
 911:                                if((message.label=(char*)calloc(100,CHAR_SIZE))==NULL)
 912:                                         SpBadMemAlloc("SpInputData");
 913:                                (void)sprintf(message.label,"Could not make the format for ODP other; no match for format type.\n");
 914:                                message.type=XmDIALOG_ERROR;
 915:                                message.caller=NONE;
 916:                                message.default_button=XmDIALOG_OK_BUTTON;
 917:                                current_file=lineno=current_hole_num=0;
 918:                                XtUnmanageChild(messageBoxWorking);
 919:                                SpManageMessage(message);
 920:                                return(True);
 921:                   }
 922:                   if((skip = openfileinfo.other_format_value_col - col - 1) <= 0) {
 923:                   }
 924:                   else {
 925:                     for(i=1; i<=skip; ++i) {
 926:                       (void)strcat(openfileinfo.other_format, " %*s");
 927:                     }
 928:                   }
 929:                   (void)strcat(openfileinfo.other_format, " %f");
 930:                 }
 931: 
 932:                 /* allocate space for data set 
 933:                 */
 934:                 ++dataset_cnt;
 935:                 dset = dataset_cnt - 1;
 936:                 if(dataset_cnt > 1) {
 937:                    if((charptr= (char*)realloc((char*)data,(dataset_cnt*sizeof(DataFile*))))==NULL) {
 938:                                 SpBadMemAlloc("SpInputData");
 939:                    }
 940:                    else {
 941:                                 data=(DataFile**)charptr; 
 942:                    }
 943:                 }
 944:                 else if(dataset_cnt == 1) {
 945:                   if((data = (DataFile**)calloc(dataset_cnt, sizeof(DataFile*)))==NULL) {
 946:                     SpBadMemAlloc("SpInputData");
 947:                   }
 948:                 }
 949:                 if((data[dset] = (DataFile*)calloc(1, sizeof(DataFile)))==NULL) {
 950:                   SpBadMemAlloc("SpInputData");
 951:                 }
 952: 
 953:                 data[dset]->in_format = openfileinfo.in_data_format;
 954:                 data[dset]->type = openfileinfo.in_data_type;
 955:                 data[dset]->numfiles = openfileinfo.num_in_files;
 956:     data[dset]->readerrors=0;
 957:                 data[dset]->decimate_value = decimate_value;
 958:                 if((data[dset]->name=(char**)calloc(openfileinfo.num_in_files,sizeof(char*)))==NULL) {
 959:                   SpBadMemAlloc("SpInputData");
 960:                 }
 961:                 for(i=0; i<openfileinfo.num_in_files; ++i) {
 962:                   if((data[dset]->name[i]=(char*)calloc(strlen(openfileinfo.in_file_names[i])+5,CHAR_SIZE))==NULL) {
 963:                     SpBadMemAlloc("SpInputData");
 964:                   }
 965:                   (void)sprintf(data[dset]->name[i], "%s", openfileinfo.in_file_names[i]);
 966:                   free(openfileinfo.in_file_names[i]);
 967:                   openfileinfo.in_file_names[i] = NULL;
 968:                 }
 969: 
 970:     current_hole_num=0;
 971:     data[dset]->holes=NULL;
 972: 
 973:   }
 974: /* if done reading, process data */
 975:   else if(done_reading && !message.error)
 976:   {
 977:     if(current_hole_num<data[dset]->numholes)
 978:     {
 979:                         if(err=CheckDepthInDescendingOrder(dset) == YES) {
 980:                           current_file=lineno=current_hole_num=0;
 981:                           done_decimate=done_cull=done_reading=False;
 982:                           if(dataset_cnt == 1) {
 983:                             SpCleanUp(INPUTDATA);
 984:                           }
 985:                           else if(dataset_cnt > 1) {
 986:                             SpFreeData(data[dset]);
 987:                             if(data[dset])
 988:                             {
 989:                               free(data[dset]);
 990:                               data[dset]=NULL;
 991:                             }
 992:                             --dataset_cnt;
 993:                             dset = dataset_cnt - 1;
 994:                             if(have_splice == DO) {
 995:                               if(XtIsManaged(XtParent(drawingAreaView))) {
 996:                                 reason_for_redraw = DRAW_EVERYTHING;
 997:                                 DrawDrawingAreaView(drawingAreaView, (XtPointer)NULL, (XtPointer)NULL);
 998:                               }
 999:                             }
1000:                             if(XtIsManaged(XtParent(drawingAreaEdit))) {
1001:                               reason_for_redraw = DRAW_EVERYTHING;
1002:                               DrawDrawingAreaEdit(drawingAreaEdit, (XtPointer)NULL, (XtPointer)NULL);
1003:                             }
1004:                           }
1005:                           XtUnmanageChild(messageBoxWorking);
1006:                           return(True);
1007:                         }
1008: 
1009:       i=current_hole_num;
1010:       if(!done_cull)
1011:       {
1012:                                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1013:                                         SpBadMemAlloc("SpInputData 1");
1014:                                 (void)sprintf(charptr,"\nData : Culling.");
1015:                                 xmstring=XmStringCreateLocalized(&charptr[1]);
1016:                                 XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1017:                                 XmStringFree(xmstring);
1018:                                 free(charptr);
1019:                                 XmUpdateDisplay(messageBoxWorking);
1020:                                
1021:         hashflag=CREATE_HASH;
1022:         SpCull(data[dset],data[dset]->type,cull,hashflag);
1023:                                 err = CheckHowManyCulled(dset);
1024:         done_cull=True;
1025:         current_hole_num=-1;
1026:         if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1027:           SpBadMemAlloc("SpInputData 1");
1028:         (void)sprintf(charptr,"\nData : Done culling.");
1029:         xmstring=XmStringCreateLocalized(&charptr[1]);
1030:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1031:         XmStringFree(xmstring);
1032:         free(charptr);
1033:       }
1034:       else if(!done_smooth)
1035:       {
1036:         if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1037:           SpBadMemAlloc("SpInputData 2");
1038:         (void)sprintf(charptr,"\nData : Smoothing data hole %c.",data[dset]->holes[i]->name);
1039:         SpUpdateReport(charptr);
1040:         xmstring=XmStringCreateLocalized(&charptr[1]);
1041:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1042:         XmStringFree(xmstring);
1043:         free(charptr);
1044:                                 if(i == 0) {
1045:                                   if(smooth.width_units == DEPTH && smooth.width < MINSMOOTHWIDTH * average_depth_step) {
1046:                                     if((charptr=(char*)calloc(150,CHAR_SIZE))==NULL)
1047:                                         SpBadMemAlloc("SmoothData 2");
1048:                                     (void)sprintf(charptr, "The width of the filter is too small. Please create a filter as wide or wider than %dcm.",
1049:                                                    MINSMOOTHWIDTH * average_depth_step);
1050:                                     SpManageWarningBox(charptr);
1051:                                     free(charptr);
1052:                                     smooth.method = NONE;
1053:                                   }
1054:                                   else if(smooth.width_units == POINTS && smooth.width < MINSMOOTHWIDTH) {
1055:                                     if((charptr=(char*)calloc(150,CHAR_SIZE))==NULL)
1056:                                         SpBadMemAlloc("SmoothData 3");
1057:                                     (void)sprintf(charptr, "The width of the filter is too small. Please create a filter as wide or wider than %d pts.",
1058:                                                      MINSMOOTHWIDTH);
1059:                                     SpManageWarningBox(charptr);
1060:                                     free(charptr);
1061:                                     smooth.method = NONE;
1062:                                   }
1063:                                 }
1064: 
1065:         if(smooth.method!=NONE)
1066:           SpSmooth(data[dset]->holes[i]);
1067:         if(i+1==data[dset]->numholes || smooth.method==NONE)
1068:         {
1069:           current_hole_num=-1;
1070:           done_smooth=True;
1071:         }
1072:       }
1073:       else if(!done_decimate)
1074:       {
1075:                                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1076:                                         SpBadMemAlloc("SpInputData 3");
1077:         (void)sprintf(charptr,"\nData : Decimating data hole %c.",data[dset]->holes[i]->name);
1078:         SpUpdateReport(charptr);
1079:         xmstring=XmStringCreateLocalized(&charptr[1]);
1080:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1081:         XmStringFree(xmstring);
1082:         free(charptr);
1083:         if(decimate_value>1)
1084:           SpDecimate(data[dset]->holes[i],decimate_value);
1085:         if(i+1==data[dset]->numholes || decimate_value<=1)
1086:         {
1087:           current_hole_num=-1;
1088:           done_decimate=True;
1089:         }
1090:       }
1091:       else if(done_affine == False)
1092:       {
1093:                                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1094:                                         SpBadMemAlloc("SpInputData 4");
1095:         (void)sprintf(charptr,"\nData : Applying affine table for hole %c.",data[dset]->holes[i]->name);
1096:         SpUpdateReport(charptr);
1097:         xmstring=XmStringCreateLocalized(&charptr[1]);
1098:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1099:         XmStringFree(xmstring);
1100:         free(charptr);
1101:         if(i==0)
1102:           hashflag=CREATE_HASH;
1103:         else if(i+1==data[dset]->numholes)
1104:            hashflag=DESTROY_HASH;
1105:         else
1106:           hashflag=0;
1107:         if(affine.usetable)
1108:           SpAffine(data[dset]->holes[i],affine,hashflag);
1109:         if(i+1==data[dset]->numholes || !affine.usetable)
1110:         {
1111:           current_hole_num=-1;
1112:           done_affine=True;
1113:         }
1114:       }
1115:                         else if(affine.usetable == True && dataset_cnt > 1)
1116:                         {
1117:                           done_affine=True;
1118:                           if(i+1==data[dset]->numholes)
1119:                           {
1120:                                   current_hole_num=-1;
1121:                           }
1122:                         }
1123:   
1124:       
1125:     current_hole_num++;
1126:     }
1127:     /* done reading and processing data */
1128:     if(!message.error)
1129:     {
1130:       if(done_affine&&done_decimate&&done_smooth&&done_cull&&done_reading)
1131:       {
1132:                                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1133:                                         SpBadMemAlloc("SpInputData 4");
1134:                                 (void)sprintf(charptr,"\n");
1135:                                 SpUpdateReport(charptr);
1136:                                 free(charptr);
1137: 
1138:         XtSetSensitive(pushButtonDataBase,FALSE);
1139:                                 if(dataset_cnt == 1) {
1140:           XtSetSensitive(pushButtonOpenSplicerTable,True);
1141:                                 }
1142:         XtSetSensitive(pushButtonOpenStrat,True);
1143: 
1144:                            /*check to see if all holes could be smoothed. here??
1145:                                 
1146:                                 if(smooth.method == GAUSSIAN || smooth.method == OTHER) {
1147:                                   for(i=0; i<data[dset]->numholes; ++i) {
1148:                                     for(j=0; j<data[dset]->holes[i]->numcores; ++j) {
1149:                                     }
1150:                                   }
1151:                                 }
1152:                            */
1153:                           have_data = DO; 
1154: 
1155:                                 /* set the default open data directory */
1156:                                 XtFree(open_data_directory);
1157:                                 len = (int)strlen(current_path);
1158:                                 if((open_data_directory=(char*)calloc(len+10,CHAR_SIZE))==NULL)
1159:                                         SpBadMemAlloc("SpInputData 4a");
1160:                                 if(len == 0) {
1161:                                 }
1162:                                 else if(strcmp(&current_path[len-1], "/") != 0) {
1163:                                   (void)sprintf(open_data_directory, "%s/", current_path);
1164:                                 }
1165:                                 else {
1166:                                   (void)sprintf(open_data_directory, "%s", current_path);
1167:                                 }
1168: 
1169:                                 if(data[dset]->numholes > 1) {
1170:                                   XtSetSensitive(pushButtonComposite,True);
1171:                                   XtSetSensitive(cascadeButtonSplice,True);
1172:                                   XtSetSensitive(pushButtonSaveData,True);
1173:                                 }
1174:                               /*  XtSetSensitive(pushButtonDisplay,True); */
1175:                                 XtSetSensitive(cascadeButtonSave,True);
1176:                                 XtSetSensitive(pushButtonSaveCull,True);
1177:                                 XtSetSensitive(pushButtonViewOffsets,True);
1178:                                 XtSetSensitive(cascadeButtonClear,True);
1179:                                 XtSetSensitive(pushButtonClearAll,True);
1180:                               /* XtSetSensitive(pushButtonClearComposite,True); */
1181:                                 XtSetSensitive(cascadeButtonDataManip, True);
1182:                                 XmListDeleteAllItems(listOpenSelected);
1183: 
1184:                                 if(smooth.method == NONE) {
1185:                                   XmToggleButtonSetState(toggleButtonPlotUnsmooth, True, NULL);
1186:                                   XmToggleButtonSetState(toggleButtonPlotSmooth, False, NULL);
1187:                                   XmToggleButtonSetState(toggleButtonPlotBoth, False, NULL);
1188:                                   XtSetSensitive(toggleButtonPlotSmooth,FALSE);
1189:                                   XtSetSensitive(toggleButtonPlotUnsmooth,FALSE);
1190:                                   XtSetSensitive(toggleButtonPlotBoth,FALSE); 
1191:                                 }
1192:                                 else if(smooth.method == GAUSSIAN || smooth.method == OTHER) {
1193:                                   XtSetSensitive(toggleButtonPlotSmooth,True);
1194:                                   XtSetSensitive(toggleButtonPlotUnsmooth,True);
1195:                                   XtSetSensitive(toggleButtonPlotBoth,True);
1196:                                   if(smooth.plot == UNSMOOTHED) {
1197:                                     XmToggleButtonSetState(toggleButtonPlotUnsmooth, True, NULL); 
1198:                                     XmToggleButtonSetState(toggleButtonPlotSmooth, False, NULL);
1199:                                     XmToggleButtonSetState(toggleButtonPlotBoth, False, NULL);
1200:                                   }
1201:                                   else if(smooth.plot == SMOOTHED) {
1202:                                     XmToggleButtonSetState(toggleButtonPlotUnsmooth, False, NULL); 
1203:                                     XmToggleButtonSetState(toggleButtonPlotSmooth, True, NULL);
1204:                                     XmToggleButtonSetState(toggleButtonPlotBoth, False, NULL);
1205:                                   }
1206:                                   else if(smooth.plot == SMOOTHEDBOTH) {
1207:                                     XmToggleButtonSetState(toggleButtonPlotUnsmooth, False, NULL); 
1208:                                     XmToggleButtonSetState(toggleButtonPlotSmooth, False, NULL);
1209:                                     XmToggleButtonSetState(toggleButtonPlotBoth, True, NULL);
1210:                                   }
1211:                                 }
1212: 
1213:                                 if((err = FindMinMax(dset)) > 0) {
1214:                                   SpManageWarningBox("Error; Could not find the min and max values of this data set");
1215:                                   if(data[dset]->type == GRAPE) {
1216:                                     data[dset]->min = GRAPEMIN;
1217:                                     data[dset]->max = GRAPEMAX;
1218:                                   }
1219:                                   else if(data[dset]->type == PWAVE) {
1220:                                     data[dset]->min = PWAVEMIN;
1221:                                     data[dset]->max = PWAVEMAX;
1222:                                   }
1223:                                   else if(data[dset]->type == SUSCEPTIBILITY) {
1224:                                     data[dset]->min = SUSCMIN;
1225:                                     data[dset]->max = SUSCMAX;
1226:                                   }
1227:                                   else if(data[dset]->type == NATURALGAMMA) {
1228:                                     data[dset]->min = NGAMMAMIN;
1229:                                     data[dset]->max = NGAMMAMAX;
1230:                                   }
1231:                                   else if(data[dset]->type == REFLECTANCEMST) { 
1232:                                     data[dset]->min = REFLECTMIN;
1233:                                     data[dset]->max = REFLECTMAX;
1234:                                   }
1235:                                   else if(data[dset]->type == OTHERTYPE) {
1236:                                     data[dset]->min = OTHERMIN;
1237:                                     data[dset]->max = OTHERMAX;
1238:                                   }
1239:                                   else {
1240:                                   }
1241:                                 }
1242:                                 else {
1243:                                   data[dset]->min = minvar;
1244:                                   data[dset]->max = maxvar;
1245:                                 }
1246:                                 SetMinMax(dset);
1247:                                 if(affine.usetable == False && dataset_cnt == 1) {
1248:                                   (void)MakeNewAffineTable(&affinetable);
1249:                                   (void)MapHoleToAffineTable(&affinetable, dset);
1250:                                   (void)MapCoreToAffineTable(&affinetable, dset);
1251:                                 }
1252:                                 /* note that after read one data set there is always
1253:                                    an affine table whether read or created new
1254:                                 */
1255:                                 else if(dataset_cnt > 1) {
1256:                                   CheckAffineTableMissingHole(&affinetable, dset);
1257:                                   MapHoleToAffineTable(&affinetable, dset);
1258:                                   CheckAffineTableMissingCore(&affinetable, dset);
1259:                                   MapCoreToAffineTable(&affinetable, dset);
1260:                                   for(i=0; i<dset; ++i) {
1261:                                     MapHoleToAffineTable(&affinetable, i);
1262:                                     MapCoreToAffineTable(&affinetable, i);
1263:                                   }
1264:                                 }
1265:  
1266:                                 if(data[dset]->type == GRAPE) {
1267:                                   xmstring=XmCvtCTToXmString("Grape");
1268:                                 }
1269:                                 else if(data[dset]->type == PWAVE) {
1270:                                   xmstring=XmCvtCTToXmString("Pwave");
1271:                                 }
1272:                                 else if(data[dset]->type == SUSCEPTIBILITY) {
1273:                                   xmstring=XmCvtCTToXmString("Susceptibility");
1274:                                 }
1275:                                 else if(data[dset]->type == NATURALGAMMA) {
1276:                                   xmstring=XmCvtCTToXmString("Natural Gamma");
1277:                                 }
1278:                                 else if(data[dset]->type == REFLECTANCEMST) {
1279:                                   xmstring=XmCvtCTToXmString("Reflectance");
1280:                                 }
1281:                                 else if(data[dset]->type == OTHERTYPE) {
1282:                                   xmstring=XmCvtCTToXmString("Other");
1283:                                 }
1284:                                 else {
1285:                                   xmstring=XmCvtCTToXmString("Other");
1286:                                 }
1287:                                 if(dataset_cnt == 1) {
1288:                                   XtManageChild(optionMenuDataSet);
1289:                                   XtManageChild(pushButtonDataSet1);
1290:                                   XtVaSetValues(pushButtonDataSet1,XmNlabelString,xmstring,NULL);
1291:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet1, NULL);
1292:                                 }
1293:                                 else if(dataset_cnt == 2) {
1294:                                   XtManageChild(pushButtonDataSet2);
1295:                                   XtVaSetValues(pushButtonDataSet2,XmNlabelString,xmstring,NULL);
1296:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet2, NULL);
1297:                                 }
1298:                                 else if(dataset_cnt == 3) {
1299:                                   XtManageChild(pushButtonDataSet3);
1300:                                   XtVaSetValues(pushButtonDataSet3,XmNlabelString,xmstring,NULL);
1301:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet3, NULL);
1302:                                 }
1303:                                 else if(dataset_cnt == 4) {
1304:                                   XtManageChild(pushButtonDataSet4);
1305:                                   XtVaSetValues(pushButtonDataSet4,XmNlabelString,xmstring,NULL);
1306:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet4, NULL);
1307:                                 }
1308:                                 else if(dataset_cnt == 5) {
1309:                                   XtManageChild(pushButtonDataSet5);
1310:                                   XtVaSetValues(pushButtonDataSet5,XmNlabelString,xmstring,NULL);
1311:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet5, NULL);
1312:                                 }
1313:                                 else if(dataset_cnt == 6) {
1314:                                   XtManageChild(pushButtonDataSet6);
1315:                                   XtVaSetValues(pushButtonDataSet6,XmNlabelString,xmstring,NULL);
1316:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet6, NULL);
1317:                                 }
1318:                                 else if(dataset_cnt == 7) {
1319:                                   XtManageChild(pushButtonDataSet7);
1320:                                   XtVaSetValues(pushButtonDataSet7,XmNlabelString,xmstring,NULL);
1321:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet7, NULL);
1322:                                 }
1323:                                 else if(dataset_cnt == 8) {
1324:                                   XtManageChild(pushButtonDataSet8);
1325:                                   XtVaSetValues(pushButtonDataSet8,XmNlabelString,xmstring,NULL);
1326:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet8, NULL);
1327:                                 }
1328:                                 else if(dataset_cnt == 9) {
1329:                                   XtManageChild(pushButtonDataSet9);
1330:                                   XtVaSetValues(pushButtonDataSet9,XmNlabelString,xmstring,NULL);
1331:                                   XtVaSetValues(optionMenuDataSet, XmNmenuHistory, pushButtonDataSet9, NULL);
1332:                                 }
1333:                                 else {
1334:                                 }
1335:                                 XmStringFree(xmstring);
1336: 
1337:                                 XtUnmanageChild(messageBoxWorking);
1338: 
1339:                                 /* if this is first data set create a report output filename using site name
1340:                                    this assumes that any additional data sets are from same site
1341:                                    figure out that path for this when know what the affine path is
1342:                                 */
1343:                                 if(dataset_cnt == 1) {
1344:                                   if(report_filename) {
1345:                                     XtFree(report_filename);
1346:                                     report_filename = NULL;
1347:                                   }
1348:                                   if((report_filename=(char*)calloc(50,CHAR_SIZE))==NULL)
1349:                                                 SpBadMemAlloc("SpInputData 7"); 
1350:                                   (void)sprintf(report_filename, "%d.rpt", data[dset]->site);
1351:                                 }
1352: 
1353:                                 if(have_splice == DO) {
1354:                                   MakeSplice(dset, &spcomp);
1355:                                   if(XtIsManaged(XtParent(drawingAreaView))) {
1356:                                     reason_for_redraw = DRAW_EVERYTHING;
1357:                                     DrawDrawingAreaView(drawingAreaView, (XtPointer)NULL, (XtPointer)NULL);
1358:                                   }
1359:                                 }
1360:                                 if(XtIsManaged(XtParent(drawingAreaEdit))) {
1361:                                   reason_for_redraw = DRAW_EVERYTHING;
1362:                                   DrawDrawingAreaEdit(drawingAreaEdit, (XtPointer)NULL, (XtPointer)NULL);
1363:                                 }
1364:                                 if(are_agemodelling == YES) {
1365:                                   if(have_time_series == DO) {
1366:                                     have_splicetoage_tie = DONT;
1367:                                     have_timeseries_tie = DONT;
1368:                                   }
1369:                                   PlotSpliceVsAge();
1370:                                 }
1371:       }
1372:       return(done_affine&&done_decimate&&done_smooth&&done_cull&&done_reading); 
1373:     }
1374:   }
1375: /* if all data read, set holes and start processing next time */
1376:   if(!message.error && current_file >= data[dset]->numfiles && !datafileopen) /* all data read */
1377:   {
1378:     current_file=0;
1379: 
1380:     /* sort holes alpha/numerically */
1381:     for(i=0;i<data[dset]->numholes-1;i++)
1382:     {
1383:       switched=False;
1384:       for(j=i+1;!switched && j<data[dset]->numholes;j++)
1385:       {
1386:         if(data[dset]->holes[j]->name < data[dset]->holes[i]->name)
1387:         {
1388:           tmphole=data[dset]->holes[i];
1389:           data[dset]->holes[i]=data[dset]->holes[j];
1390:           data[dset]->holes[j]=tmphole;
1391:           switched=True;
1392:           i--;
1393:         }
1394:       }
1395:     }
1396:     if(!message.error)
1397:     {
1398:                         SiteAveDepth();
1399:                       
1400:       done_reading=True;
1401:       if((charptr=(char*)calloc(200,CHAR_SIZE))==NULL)
1402:         SpBadMemAlloc("SpInputData 7");
1403:       (void)sprintf(charptr,"\nData : Done reading files. Preparing to process...");
1404:       SpUpdateReport(charptr);
1405:       xmstring=XmStringCreateLocalized(&charptr[1]);
1406:       XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring,NULL);
1407:       XmStringFree(xmstring);
1408:       free(charptr);
1409:       return(False);
1410:     }
1411:   }
1412: /* find current filename */
1413:   else if(!message.error && !datafileopen)
1414:   {
1415:     nameptr=data[dset]->name[current_file++];
1416:     if((fptr=fopen(nameptr,"r"))==NULL)
1417:     {
1418:       message.error=True;
1419:       message.fatal=False;
1420:       message.default_button=XmDIALOG_OK_BUTTON;
1421:       message.type=XmDIALOG_ERROR;
1422:       message.caller=SPINPUTDATA;
1423:       if((message.label=(char*)calloc(100+(int)strlen(nameptr),CHAR_SIZE))==NULL)
1424:           SpBadMemAlloc("SpInputData 8");
1425:       (void)sprintf(message.label,"Error opening input file %s\n",nameptr);
1426:     }
1427:     else
1428:     {
1429:       lineno=0;
1430:       datafileopen=True;
1431:       if((charptr=(char*)calloc(100+(int)strlen(nameptr),CHAR_SIZE))==NULL)
1432:         SpBadMemAlloc("SpInputData 9");
1433:       (void)sprintf(charptr,"Data : Reading file %s (line=%d, total errors=%d)     ",
1434:                                       nameptr,lineno,data[dset]->readerrors);
1435:       xmstring=XmStringCreateLocalized(charptr);
1436:       XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring,NULL);
1437:       XmStringFree(xmstring);
1438:       free(charptr);
1439: 
1440:                         /* if have header get num of lines and read that many from current file
1441:                         */
1442:                         if(data[dset]->in_format != JANUSORIG && XmToggleButtonGetState(toggleButtonHeaderYes) == True) {
1443:                           str = XmTextGetString(textFieldNHeader);
1444:                           skip = atoi(str);
1445:                           XtFree(str);
1446:                           for(i=1; i<=skip; ++i) {
1447:                             if(fgets(buffer,999,fptr)==NULL) {
1448:                               /* error; reached end of file
1449:                               */
1450:                             }
1451:                           }
1452:                         }
1453: 
1454:                         /* if format type is Janus Orig then read current file until record
1455:                            reads <PRE><!--START OF OUTPUT--> then read one more to skip header
1456:                            if don't reach this record then error
1457:                            note that if there was an error getting data then the nest line will
1458:                            have some message stating this. fine out what that is.
1459:                         */
1460:                         if(data[dset]->in_format == JANUSORIG) {
1461:                           while(fgets(buffer,999,fptr)!=NULL) {
1462:                             if(strcmp(buffer, "<PRE><!--START OF OUTPUT-->\n") == 0) {
1463:                               if(fgets(buffer,999,fptr)==NULL) {
1464:                                 /* error
1465:                                 */     
1466:                               }
1467:                               break;
1468:                             } 
1469:                           }
1470:                         }
1471:     }
1472:   }
1473: /* read some data */
1474:   if(!message.error && datafileopen)
1475:   {
1476:     if(SpRead(fptr, data[dset]))
1477:     {
1478:     /* end of file found */
1479:       fclose(fptr);
1480:       datafileopen=False;
1481:       if((charptr=(char*)calloc(200+(int)strlen(nameptr),CHAR_SIZE))==NULL)
1482:         SpBadMemAlloc("SpInputData 10");
1483:                         if(data[dset]->numholes == 0) {
1484:                           (void)sprintf(charptr,"\nUnable to read input file  %s",nameptr);
1485:                           message.error = TRUE;
1486:                           if((message.label=(char*)calloc(50+(int)strlen(nameptr),CHAR_SIZE))==NULL)
1487:                                         SpBadMemAlloc("SpInputData 8");
1488:                             (void)sprintf(message.label,"Unable to read input file %s\n",nameptr);
1489:                         }
1490:                         else {
1491:         (void)sprintf(charptr,"\nRead file %s (total lines =%d, total errors=%d)",nameptr,lineno,data[dset]->readerrors);
1492:                         }
1493:       SpUpdateReport(charptr);
1494:       free(charptr);
1495:     }
1496:     else
1497:     /* not end of file */
1498:     {
1499:       if(++lineno % 500 == 0)
1500:       {
1501:                           if((charptr=(char*)calloc(200+(int)strlen(nameptr),CHAR_SIZE))==NULL) 
1502:                                   SpBadMemAlloc("SpInputData 11");
1503:         (void)sprintf(charptr,"Data : Reading file %s (line=%d, total errors=%d)",nameptr,lineno,data[dset]->readerrors);
1504:         xmstring=XmStringCreateLocalized(charptr);
1505:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring,NULL);
1506:         XmStringFree(xmstring);
1507:         free(charptr);
1508:       }
1509: 
1510:                         if(data[dset]->readerrors > TOOMANYREADERRORS) {
1511:                           message.error=True;
1512:                           message.fatal=False;
1513:                           if((message.label=(char*)calloc(500 + (int)strlen(nameptr),CHAR_SIZE))==NULL)
1514:                                         SpBadMemAlloc("SpInputData");
1515:                           (void)sprintf(message.label,"%d read errors have occured. \nAre in file %s at line %d\n", 
1516:                                             data[dset]->readerrors, nameptr, lineno);
1517:                           message.type=XmDIALOG_ERROR;
1518:                           message.caller=NONE;
1519:                           message.default_button=XmDIALOG_OK_BUTTON;
1520:                           current_file=lineno=current_hole_num=0;
1521:                           fclose(fptr);
1522:                           datafileopen=False;
1523:                           if(dataset_cnt == 1) {
1524:                             SpCleanUp(INPUTDATA);
1525:                           }
1526:                           else if(dataset_cnt > 1) {
1527:                             SpFreeData(data[dset]);
1528:                             if(data[dset])
1529:                             {
1530:                               free(data[dset]);
1531:                               data[dset]=NULL;
1532:                             }
1533:                             --dataset_cnt;
1534:                             dset = dataset_cnt - 1;
1535:                             if(have_splice == DO) {
1536:                               if(XtIsManaged(XtParent(drawingAreaView))) {
1537:                                 reason_for_redraw = DRAW_EVERYTHING;
1538:                                 DrawDrawingAreaView(drawingAreaView, (XtPointer)NULL, (XtPointer)NULL);
1539:                               }
1540:                             }
1541:                             if(XtIsManaged(XtParent(drawingAreaEdit))) {
1542:                               reason_for_redraw = DRAW_EVERYTHING;
1543:                               DrawDrawingAreaEdit(drawingAreaEdit, (XtPointer)NULL, (XtPointer)NULL);
1544:                             }
1545:                           }
1546:                           XtUnmanageChild(messageBoxWorking);
1547:                           SpManageMessage(message);
1548:                           return(True);
1549:                         }
1550:     }
1551:   }
1552: /* an error occurred somewhere... Close working box and clean up */
1553:   if(message.error)
1554:   {
1555:     current_file=lineno=current_hole_num=0;
1556:                 datafileopen=False;
1557:                 if(dataset_cnt == 1) {
1558:       SpCleanUp(INPUTDATA);
1559:                 }
1560:                 else if(dataset_cnt > 1) {
1561:                   SpFreeData(data[dset]);
1562:                   if(data[dset])
1563:                   {
1564:                     free(data[dset]);
1565:                     data[dset]=NULL;
1566:                   }
1567:                   --dataset_cnt;
1568:                   dset = dataset_cnt - 1;
1569:                   if(have_splice == DO) {
1570:                     if(XtIsManaged(XtParent(drawingAreaView))) {
1571:                       reason_for_redraw = DRAW_EVERYTHING;
1572:                       DrawDrawingAreaView(drawingAreaView, (XtPointer)NULL, (XtPointer)NULL);
1573:                     }
1574:                   }
1575:                   if(XtIsManaged(XtParent(drawingAreaEdit))) {
1576:                     reason_for_redraw = DRAW_EVERYTHING;
1577:                     DrawDrawingAreaEdit(drawingAreaEdit, (XtPointer)NULL, (XtPointer)NULL);
1578:                   }
1579:                 }
1580:     XtUnmanageChild(messageBoxWorking);
1581:                 message.fatal=False;
1582:                 message.caller=NONE;
1583:                 message.type=XmDIALOG_ERROR;
1584:                 message.default_button=XmDIALOG_OK_BUTTON;
1585:     SpManageMessage(message); 
1586:     return(True);
1587:   }
1588:   else
1589:     return(False);
1590: }
1591: 
1592: int SpInputSplicerTable(client_data)
1593: XtPointer client_data;
1594: {
1595:   XmString  xmstring;
1596:   int i,j,k,status, sm, dum1, dum2, SpReadSplicerTable(), FindValueInCoreToSplice();
1597:   Core  *coreptr;
1598:   Value *valueptr;
1599:   char  *ptr;
1600:         void DrawDrawingAreaView(), CheckSpliceTableOffsets(), PlotSpliceVsAge();
1601: 
1602:   if(!splicer_read_done)
1603:   {
1604:     if ((fptr=fopen(splicertable.filename,"r"))==NULL)
1605:     {
1606:       message.error=True;
1607:                         message.fatal=False;
1608:                         message.caller=NONE;
1609:                         message.type=XmDIALOG_WARNING;
1610:                         message.default_button=XmDIALOG_OK_BUTTON;
1611:                         if((message.label=(char*)calloc((int)strlen(splicertable.filename)+50,CHAR_SIZE))==NULL)
1612:                                 SpBadMemAlloc("SpInputSplicerTable 1");
1613:       (void)sprintf(message.label,"Error opening input file %s\n",splicertable.filename);
1614:       SpManageMessage(message);
1615:       return(True);
1616:     }
1617:     else
1618:     {
1619:                         if((charptr=(char*)calloc((int)strlen(splicertable.filename)+50,CHAR_SIZE))==NULL)
1620:                                 SpBadMemAlloc("SpInputSplicerTable 1");
1621:       (void)sprintf(charptr,"\nSplicer table file %s used.\n",splicertable.filename);
1622:       SpUpdateReport(charptr);
1623:       free(charptr);
1624:                         XmUpdateDisplay(messageBoxWorking);
1625:     /* set up splicer table */
1626:       splicertable.alloc_cnt=ALLOC_INT;
1627:       splicertable.data_cnt=1; /* first value isn't read from table */
1628:       sptable_cnt=0;
1629:       if((splicertable.data=(SplicerTableInfo*)calloc(splicertable.alloc_cnt,sizeof(SplicerTableInfo)))==NULL)
1630:         SpBadMemAlloc("SpInputSplicerTable");
1631:     /* read splicer table */
1632:       while(!splicer_read_done)
1633:       {
1634:         if(splicertable.data_cnt+1>=splicertable.alloc_cnt)
1635:         {
1636:           if((ptr=(char*)realloc((char*)splicertable.data,(splicertable.alloc_cnt+=ALLOC_INT)*sizeof(SplicerTableInfo)))==NULL)
1637:             SpBadMemAlloc("SpInputSplicerTable");
1638:           else
1639:             splicertable.data=(SplicerTableInfo*)ptr;
1640:         }
1641:         if((status=SpReadSplicerTable(fptr,splicertable.data,&splicertable.data_cnt))==EOF)
1642:             splicer_read_done=True;
1643:         else if(!(status==9 || status==19)) /* error reading */
1644:         {
1645:           fclose(fptr);
1646:           free(splicertable.data);
1647:           XtUnmanageChild(messageBoxWorking);
1648:           message.error=True;
1649:                                         message.fatal=False;
1650:           if((message.label=(char*)calloc((int)strlen(splicertable.filename)+100,CHAR_SIZE))==NULL)
1651:             SpBadMemAlloc("SpInputSplicerTable");
1652:           (void)sprintf(message.label,"Error reading splicer table %s.",splicertable.filename);
1653:                                         message.caller=NONE;
1654:                                         message.type=XmDIALOG_ERROR;
1655:                                         message.default_button=XmDIALOG_OK_BUTTON;
1656:           SpManageMessage(message);
1657:           return(True);
1658:         }
1659:       }
1660:       fclose(fptr);
1661: 
1662:                         if((charptr=(char*)calloc((int)strlen(splicertable.filename)+200,CHAR_SIZE))==NULL)
1663:                                 SpBadMemAlloc("SpInputSplicerTable 3");
1664:       (void)sprintf(charptr,"Splicer : Read splicer table file %s (total ties %d)",splicertable.filename,
1665:           (int)splicertable.data_cnt/2);
1666:       SpUpdateReport(charptr);
1667:                         XmUpdateDisplay(messageBoxWorking);
1668:       xmstring=XmStringCreateLocalized(charptr);
1669:       XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1670:       XmStringFree(xmstring);
1671:       free(charptr);
1672:     }
1673:   }
1674:   else if(!splicer_table_done)  /* fill in splicer table values */
1675:   {
1676:   /* get first data value */
1677:     if(sptable_cnt==0)
1678:     {
1679:       for(i=0;i<data[dset]->numholes && data[dset]->holes[i]->name != splicertable.data[1].hole;i++);
1680: 
1681: 
1682:       if(i<data[dset]->numholes)
1683:       {
1684:         for(j=0;j<data[dset]->holes[i]->numcores && splicertable.data[1].core!=data[dset]->holes[i]->core[j]->num;j++);
1685:         if(j<data[dset]->holes[i]->numcores)
1686:         {
1687:         /* find first "good" value */
1688:           coreptr=data[dset]->holes[i]->core[j];
1689:           for(k=0;k<coreptr->numvalues && coreptr->value[k]->quality!=GOOD;k++);
1690:         /* set splicertable values for top of cores */
1691:           if(k<coreptr->numvalues)
1692:           {
1693:             spcomp.numcores=0;
1694:             valueptr=coreptr->value[k];
1695:             splicertable.data[0].hole=splicertable.data[1].hole;
1696:             splicertable.data[0].core=splicertable.data[1].core;
1697:             splicertable.data[0].core_type=valueptr->type;
1698:             (void)strcpy(splicertable.data[0].section,valueptr->section);
1699:             splicertable.data[0].top_int=valueptr->top_int;
1700:             splicertable.data[0].bot_int=valueptr->bot_int;
1701:             splicertable.data[0].mbsf=valueptr->sb_depth;
1702:             splicertable.data[0].mcd=valueptr->sb_depth +(splicertable.data[1].mcd-splicertable.data[1].mbsf);
1703:           }
1704:           else
1705:             message.error=SPL_NO_CORE_VALUES;
1706:         }
1707:         else
1708:           message.error=SPL_MISSING_CORE;
1709:       }
1710:       else
1711:         message.error=SPL_MISSING_CORE;
1712: 
1713:                         if(message.error == SPL_NO_CORE_VALUES || message.error == SPL_MISSING_CORE)
1714:                         {
1715:                           spcomp.numcores=0;
1716:                           splicertable.data[0].hole=splicertable.data[1].hole;
1717:                           splicertable.data[0].core=splicertable.data[1].core;
1718:                           splicertable.data[0].core_type=splicertable.data[1].core_type;
1719:                           (void)strcpy(splicertable.data[0].section,"1");
1720:                           splicertable.data[0].top_int=0.0;
1721:                           splicertable.data[0].bot_int=0.0;
1722:                           splicertable.data[0].mbsf=0.0;
1723:                           splicertable.data[0].mcd=splicertable.data[0].mbsf +(splicertable.data[1].mcd-splicertable.data[1].mbsf);
1724:                         }
1725:       else if(message.error)
1726:       {
1727:         XtUnmanageChild(messageBoxWorking);
1728:                           if((message.label=(char*)calloc(100,CHAR_SIZE))==NULL)
1729:                                   SpBadMemAlloc("SpInputSplicerTable 3");
1730:         (void)sprintf(message.label,"Error finding match for top of first core!");
1731:         if(splicertable.data)
1732:         {
1733:           free(splicertable.data);
1734:           splicertable.data=NULL;
1735:         }
1736:                                 message.fatal=False;
1737:                                 message.caller=NONE;
1738:                                 message.type=XmDIALOG_WARNING;
1739:                                 message.default_button=XmDIALOG_OK_BUTTON;
1740:         SpManageMessage(message);
1741:         return(message.error);
1742:       }
1743:     }
1744: /* write  data for a tie */
1745: /* loop through all good data between sptable_cnt & sptablecnt+1, then add 2 to sptablecnt */ 
1746:     if(sptable_cnt<splicertable.data_cnt)
1747:     {
1748:     /* find correct hole */
1749:       for(i=0;i<data[dset]->numholes && splicertable.data[sptable_cnt].hole!=data[dset]->holes[i]->name;i++);
1750:       if(i<data[dset]->numholes)
1751:       {
1752:       /* find correct core */
1753:         for(j=0;j<data[dset]->holes[i]->numcores && splicertable.data[sptable_cnt].core!=data[dset]->holes[i]->core[j]->num;j++);
1754:         if(j<data[dset]->holes[i]->numcores)
1755:         {
1756:         /* find first value for this core*/
1757:           coreptr=data[dset]->holes[i]->core[j];
1758:           for(k=0;k<coreptr->numvalues && coreptr->value[k]->sb_depth < splicertable.data[sptable_cnt].mbsf; k++);
1759:                      
1760:         /* get "good" values until bottom of tied core*/
1761:           if(k<coreptr->numvalues)
1762:           {
1763:             spcomp.hole[spcomp.numcores]=i;
1764:             spcomp.core[spcomp.numcores]=j;
1765:             spcomp.Depthoffset[spcomp.numcores]=splicertable.data[sptable_cnt].mcd-splicertable.data[sptable_cnt].mbsf;
1766:             spcomp.numpercore[spcomp.numcores]=0;
1767:                                                 spcomp.map_to_table[spcomp.numcores] = sptable_cnt;
1768:                                                 if(spcomp.numcores > 0) {
1769:                                                   if(strcmp(splicertable.data[sptable_cnt].type_of_splice, "tie") == 0) {
1770:                                                     spcomp.splice_how[spcomp.numcores] = REAL;
1771:                                                   }
1772:                                                   else if(strcmp(splicertable.data[sptable_cnt].type_of_splice, "interp") == 0) {
1773:                                                     spcomp.splice_how[spcomp.numcores] = INTERPOLATED;
1774:                                                     spcomp.interpolated_spl_depth[spcomp.numcores] = splicertable.data[sptable_cnt].mcd;
1775: 
1776:                                                     /* note that if find real value at 'depth' then splicearraynum comes back
1777:                                                        with indicy of real point. but if interpolated a point then splicearraynum
1778:                                                        is the indicy of next real point.
1779:                                                     */
1780:                                                     if(smooth.method == GAUSSIAN || smooth.method == OTHER) {
1781:                                                       sm == YES;
1782:                                                     }
1783:                                                     else {
1784:                                                       sm = NO;
1785:                                                     }
1786:                                                     (void)FindValueInCoreToSplice(dset, sm, spcomp.interpolated_spl_depth[spcomp.numcores], 
1787:                                                             spcomp.hole[spcomp.numcores], spcomp.core[spcomp.numcores],
1788:                                                             &dum1, &dum2, 
1789:                                                             &spcomp.interpolated_value[spcomp.numcores], &spcomp.interpolated_sm_value[spcomp.numcores]);
1790:                                                   }
1791:                                                   else if(strcmp(splicertable.data[sptable_cnt].type_of_splice, "append") == 0) {
1792:                                                     spcomp.splice_how[spcomp.numcores] = APPEND;
1793:                                                   }
1794:                                                   else {
1795:                                                     spcomp.splice_how[spcomp.numcores] = NONE;
1796:                                                   }
1797:                                                 }
1798:                                                 else {
1799:                                                   spcomp.splice_how[spcomp.numcores] = NONE;
1800:                                                 }
1801:             for(;k<coreptr->numvalues && coreptr->value[k]->sb_depth <= splicertable.data[sptable_cnt+1].mbsf; k++)
1802:             {
1803:               valueptr=coreptr->value[k];
1804:               if(valueptr->quality == GOOD)
1805:               {
1806:                 spcomp.MapToOrig[spcomp.numcores][spcomp.numpercore[spcomp.numcores]]=k;
1807:                 spcomp.sb_depth[spcomp.numcores][spcomp.numpercore[spcomp.numcores]]=valueptr->sb_depth+spcomp.Depthoffset[spcomp.numcores];
1808:                                                                 spcomp.var[spcomp.numcores][spcomp.numpercore[spcomp.numcores]]=*valueptr->data;
1809:                                                                 spcomp.numpercore[spcomp.numcores]++;
1810:               }
1811:             }
1812:                                                 ++spcomp.numcores;
1813:           }
1814:           else
1815:             message.error=SPL_NO_CORE_VALUES;
1816:         }
1817:         else
1818:           message.error=SPL_MISSING_CORE;
1819:                           if((charptr=(char*)calloc(200,CHAR_SIZE))==NULL)
1820:                                 {
1821:                                   SpBadMemAlloc("SpInputSplicerTable 4");
1822:                                 }
1823:         SpUpdateReport(charptr);
1824:         xmstring=XmStringCreateLocalized(&charptr[1]);
1825:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1826:         XmStringFree(xmstring);
1827:         free(charptr);
1828:         sptable_cnt+=2;
1829:       }
1830:       else 
1831:                         {
1832:         message.error=SPL_MISSING_HOLE;
1833:                                 sptable_cnt+=2;
1834:                         }
1835:       if(message.error == True)
1836:       {
1837:                           if((message.label=(char*)calloc(100,CHAR_SIZE))==NULL)
1838:                                   SpBadMemAlloc("SpInputSplicerTable 4");
1839:         (void)sprintf(message.label,"Error building splicer table!");
1840:         XtUnmanageChild(messageBoxWorking);
1841:         if(splicertable.data)
1842:         {
1843:           free(splicertable.data);
1844:           splicertable.data=NULL;
1845:         }
1846:         sptable_cnt=0;
1847:                                 message.fatal=False;
1848:                                 message.caller=NONE;
1849:                                 message.type=XmDIALOG_WARNING;
1850:                                 message.default_button=XmDIALOG_OK_BUTTON;
1851:         SpManageMessage(message);
1852:         return(message.error);
1853:       }
1854:     }
1855:     else
1856:       splicer_table_done=True;
1857:   }
1858:   
1859: /* check if work is done */
1860:   if(splicer_read_done&&splicer_table_done)
1861:   {
1862:                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1863:                              SpBadMemAlloc("SpInputSplicerTable 4");
1864:                 (void)sprintf(charptr,"\n");
1865:                 SpUpdateReport(charptr);
1866:                 free(charptr);
1867: 
1868:     XtUnmanageChild(messageBoxWorking);
1869:     have_splice=DO;
1870:                 XtSetSensitive(pushButtonSaveSplicerTable,True);
1871:                 XtSetSensitive(pushButtonSaveSplicerData,True);
1872:                 XtSetSensitive(pushButtonOpenSplicerTable,False);
1873:                 XtSetSensitive(pushButtonClearSplice,True);
1874:                 XtSetSensitive(cascadeButtonSplice,True);
1875:                 XtSetSensitive(pushButtonSpliceUndoLast, True);
1876:                 if(XtIsManaged(XtParent(drawingAreaView))) {
1877:                   reason_for_redraw = DRAW_EVERYTHING;
1878:                   DrawDrawingAreaView(drawingAreaView, (XtPointer)NULL, (XtPointer)NULL);
1879:                 }
1880:                 if(are_agemodelling == YES && ((agemodel_cnt == 1 && agemodel[0].aveage > 0.0) || agemodel_cnt > 1)) {
1881:                   XtSetSensitive(pushButtonPlotSpliceVsAge, True);
1882:                   XtSetSensitive(pushButtonSaveSpliceToAge, True);
1883:                   XtSetSensitive(pushButtonOpenAgeSignal, True);
1884:                   XtSetSensitive(pushButtonOpenTimeSeries, True);
1885:                   PlotSpliceVsAge();
1886:                 }
1887: 
1888:                 if(message.error == SPL_MISSING_HOLE || message.error == SPL_MISSING_CORE || message.error == SPL_NO_CORE_VALUES) { 
1889:                   (void)sprintf(buffer,"Warning; the entire splice record could not be built.");
1890:                   SpManageWarningBox(buffer);
1891:                 } 
1892: 
1893:                 if(have_affine == DO) {
1894:                   CheckSpliceTableOffsets();
1895:                 }
1896:                 else {
1897:                   (void)sprintf(buffer, "Warning: You do not have an affine table.");
1898:                   SpManageWarningBox(buffer);
1899:                 }
1900: 
1901: 
1902:     return(True);
1903: 
1904:   }
1905:   else
1906:     return(False);
1907: }
1908: 
1909: int SpInputStrat(client_data)
1910: XtPointer client_data;
1911: {
1912:         char            string[100];
1913:   XmString  xmstring;
1914:   StratFile *stratptr;
1915:   StratData *thisptr;
1916:   int i,j,found=0,SpReadStrat();
1917:   Core  *coreptr;
1918:         void DrawDrawingAreaEdit(), DrawDrawingAreaView(), DrawDrawingAreaAgeDepth(), 
1919:              MapStratToAffine(), FindStratDepthOffset();
1920: 
1921:   stratptr=strat[strat_file_cnt-1];
1922:   if(!stratfileopen)
1923:   {
1924:                 io_wait_cursor = XCreateFontCursor(XtDisplay(formFileSelection), XC_watch);
1925:                 if(io_wait_cursor != BadAlloc && io_wait_cursor != BadFont && io_wait_cursor != BadValue) {
1926:                   XDefineCursor(XtDisplay(formFileSelection), XtWindow(formFileSelection), io_wait_cursor);
1927:                 }
1928:     if ((fptr=fopen(stratptr->filename,"r"))==NULL)
1929:     {
1930:       message.error=True;
1931:                         if((message.label=(char*)calloc((int)strlen(stratptr->filename)+100,CHAR_SIZE))==NULL)
1932:                                 SpBadMemAlloc("SpInputstrat 1");
1933:       (void)sprintf(message.label,"Error opening input file %s\n",stratptr->filename);
1934:                         message.fatal=False;
1935:                         message.caller=NONE;
1936:                         message.type=XmDIALOG_WARNING;
1937:                         message.default_button=XmDIALOG_OK_BUTTON;
1938:       SpManageMessage(message);
1939:       return(True);
1940:     }
1941:     else
1942:     {
1943:                         if((charptr=(char*)calloc((int)strlen(stratptr->filename)+(int)strlen(strat_type[stratptr->type])+100,CHAR_SIZE))==NULL)
1944:                                 SpBadMemAlloc("SpInputstrat 2");
1945:       (void)sprintf(charptr,"\nStrat file %s read.(%s)",stratptr->filename,
1946:         strat_type[stratptr->type]);
1947:       SpUpdateReport(charptr);
1948:       free(charptr);
1949:       stratfileopen=True;
1950:       if((stratptr->data= (StratData*)calloc((stratptr->alloc_cnt=ALLOC_INT),sizeof(StratData)))==NULL)
1951:         SpBadMemAlloc("SpInputstrat");
1952:       stratptr->data_cnt=0;
1953:     }
1954:   }
1955:   if(stratptr->data_cnt+1 >= stratptr->alloc_cnt)
1956:   {
1957:       if((charptr= (char*)realloc(stratptr->data,(stratptr->alloc_cnt+=ALLOC_INT)*sizeof(StratData)))==NULL)
1958:         SpBadMemAlloc("SpInputstrat");
1959:       else
1960:         stratptr->data=(StratData*)charptr;
1961:   }
1962:   stratfileopen=SpReadStrat(fptr,&stratptr->data[stratptr->data_cnt]);
1963:   if(stratfileopen)
1964:   {
1965:     if(stratptr->data_cnt % 500 == 0)
1966:     {
1967:                         if((charptr=(char*)calloc((int)strlen(stratptr->filename)+100,CHAR_SIZE))==NULL)
1968:                                 SpBadMemAlloc("SpInputstrat 2");
1969:       (void)sprintf(charptr,"Strat : Reading Strat file %s (line number %d)",stratptr->filename,
1970:           stratptr->data_cnt);
1971:       xmstring=XmStringCreateLocalized(charptr);
1972:       XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
1973:       XmStringFree(xmstring);
1974:       free(charptr);
1975:     }
1976:     stratptr->data_cnt++;
1977:     return(False);
1978:   }
1979:   else
1980:   {
1981:                 if((charptr=(char*)calloc(100,CHAR_SIZE))==NULL)
1982:                               SpBadMemAlloc("SpInputStrat");
1983:                 (void)sprintf(charptr,"\n");
1984:                 SpUpdateReport(charptr);
1985:                 free(charptr);
1986: 
1987:     if(fptr) fclose(fptr);
1988:     XtUnmanageChild(messageBoxWorking);
1989:     have_strat=DO;
1990:                 MapStratToAffine();
1991:                 FindStratDepthOffset();
1992:                 AgeDepthMinMax();
1993:                 XtSetSensitive(pushButtonViewAgeDepth,True);
1994:                 XtSetSensitive(pushButtonSaveStrat,True);
1995:                 /* XtSetSensitive(pushButtonClearStrat,True); */
1996:              
1997:                 XmListDeleteAllItems(listAgeDepthStrat);
1998:                 for(i=0; i<strat_file_cnt; ++i) {
1999:                   if(strat[i]->type == DIATOMS) {
2000:                     (void)sprintf(string, "Diatom");
2001:                     for(j=0; j<strat[i]->data_cnt; ++j) {
2002:                       strat[i]->data[j].type = DIATOMS;
2003:                     }
2004:                   }
2005:                   else if(strat[i]->type == RADIOLARIA) {
2006:                     (void)sprintf(string, "Radiolaria");
2007:                     for(j=0; j<strat[i]->data_cnt; ++j) {
2008:                       strat[i]->data[j].type = RADIOLARIA;
2009:                     }
2010:                   }
2011:                   else if(strat[i]->type == FORAMINIFERA) {
2012:                     (void)sprintf(string, "Foraminifera");
2013:                     for(j=0; j<strat[i]->data_cnt; ++j) {
2014:                       strat[i]->data[j].type = FORAMINIFERA;
2015:                     }
2016:                   }
2017:                   else if(strat[i]->type == NANNOFOSSILS) {
2018:                     (void)sprintf(string, "Nannofossils");
2019:                     for(j=0; j<strat[i]->data_cnt; ++j) {
2020:                       strat[i]->data[j].type = NANNOFOSSILS;
2021:                     }
2022:                   }
2023:                   else if(strat[i]->type == PALEOMAG) {
2024:                     (void)sprintf(string, "Paleomag");
2025:                     for(j=0; j<strat[i]->data_cnt; ++j) {
2026:                       strat[i]->data[j].type = PALEOMAG;
2027:                     }
2028:                   }
2029:                   else {
2030:                     (void)sprintf(string, "unknown");
2031:                   }
2032:                   xmstring = XmStringCreateSimple(string);
2033:                   XmListAddItem(listAgeDepthStrat, xmstring, 0);
2034:                   XmListSelectPos(listAgeDepthStrat, 0, False);
2035:                   XmStringFree(xmstring);
2036:                 }
2037:                 (void)sprintf(string, "");
2038: 
2039:                 for(i=0; i<strat_file_cnt; ++i) {
2040:                   agedepth_use_type[i] = YES;
2041:                 }
2042:                 XtSetSensitive(formAgeDepthControls, True);
2043:                 if(XtIsManaged(XtParent(drawingAreaAgeDepth))) {
2044:                   DrawDrawingAreaAgeDepth(drawingAreaAgeDepth, (XtPointer)NULL, (XtPointer)NULL);
2045:                 }
2046:                 if(have_data == DO) {
2047:                   if(XtIsManaged(XtParent(drawingAreaEdit))) {
2048:                     reason_for_redraw = DRAW_EVERYTHING;
2049:                     DrawDrawingAreaEdit(drawingAreaEdit, (XtPointer)NULL, (XtPointer)NULL);
2050:                   }
2051:                   if(are_splicing == YES) {
2052:                     if(XtIsManaged(XtParent(drawingAreaView))) {
2053:                       reason_for_redraw = DRAW_EVERYTHING;
2054:                       DrawDrawingAreaView(drawingAreaView, (XtPointer)NULL, (XtPointer)NULL);
2055:                     }
2056:                   }
2057:                 }
2058:                 if(io_wait_cursor) {
2059:                   XUndefineCursor(XtDisplay(formFileSelection), XtWindow(formFileSelection));
2060:                   XFreeCursor(XtDisplay(formFileSelection), io_wait_cursor);
2061:                 }
2062:     return(True);
2063:   }
2064: }
2065: 
2066: int currentstrat_file=0;
2067: int strat_out_open=False;
2068: SpOutputStrat()
2069: {
2070:   int   i,SpWriteStrat();
2071:   XmString  xmstring;
2072:   if(!strat_out_open)
2073:   {
2074:     if((fptr=fopen(outstrat.filename,"w"))==NULL)
2075:     {
2076:       message.error=True;
2077:                         if((message.label=(char*)calloc((int)strlen(outstrat.filename)+100,CHAR_SIZE))==NULL)
2078:                                 SpBadMemAlloc("SpOutputStrat 1");
2079:       (void)sprintf(message.label,"Error Opening output strat file %s.",outstrat.filename);
2080:                         message.fatal=False;
2081:                         message.caller=NONE;
2082:                         message.type=XmDIALOG_WARNING;
2083:                         message.default_button=XmDIALOG_OK_BUTTON;
2084:       SpManageMessage(message);
2085:       return(True);
2086:     }
2087:     else
2088:     {
2089:       strat_out_open=True;
2090:                         if((charptr=(char*)calloc((int)strlen(outstrat.filename)+100,CHAR_SIZE))==NULL)
2091:                                 SpBadMemAlloc("SpOutputStrat 2");
2092:       (void)sprintf(charptr,"\nOutput strat file %s.",outstrat.filename);
2093:       SpUpdateReport(charptr);
2094:       free(charptr);
2095:     }
2096:   }
2097:   if(currentstrat_file<strat_file_cnt)
2098:   {
2099:     for(i=0;i<strat[currentstrat_file]->data_cnt;i++)
2100:       (void)SpWriteStrat(fptr,&strat[currentstrat_file]->data[i]);  
2101:                 if((charptr=(char*)calloc((int)strlen(strat[currentstrat_file]->filename)+100,CHAR_SIZE))==NULL)
2102:                                 SpBadMemAlloc("SpOutputStrat 3");
2103:     (void)sprintf(charptr,"Strat: Output data from input file %s.",strat[currentstrat_file]->filename);
2104:     xmstring=XmStringCreateLocalized(&charptr[1]);
2105:     XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
2106:     XmStringFree(xmstring);
2107:     free(charptr);
2108:     currentstrat_file++;
2109:     return(False);
2110:   }
2111:   else
2112:   {
2113:     fclose(fptr);
2114:     strat_out_open=False;
2115:     currentstrat_file=0;
2116:     XtUnmanageChild(messageBoxWorking);
2117:     return(True);
2118:   }
2119: }
2120: 
2121: void SpFreeData(dataptr)
2122: DataFile  *dataptr;
2123: {
2124:   int i,j,k;
2125: 
2126:   for(i=0;i<dataptr->numfiles;i++)
2127:   {
2128:     if(dataptr->name[i] && (int)strlen(dataptr->name[i])>0)
2129:     {
2130:       XtFree(dataptr->name[i]);
2131:       dataptr->name[i]=NULL;
2132:     }
2133:   }
2134:   for(i=0;dataptr->holes && dataptr->holes[i] && i<dataptr->numholes;i++)
2135:   {
2136:     for(j=0;dataptr->holes[i]->core && j<dataptr->holes[i]->numcores;j++)
2137:     {
2138:       for(k=0;dataptr->holes[i]->core[j]->value && k< dataptr->holes[i]->core[j]->allocvalues;k++)
2139:       {
2140:         if(dataptr->type==GRAPE && dataptr->holes[i]->core[j]->value[k]->grape)
2141:           free(dataptr->holes[i]->core[j]->value[k]->grape);
2142:         else if(dataptr->type==PWAVE && dataptr->holes[i]->core[j]->value[k]->pwave)
2143:           free(dataptr->holes[i]->core[j]->value[k]->pwave);
2144:         else if(dataptr->type==NATURALGAMMA && dataptr->holes[i]->core[j]->value[k]->naturalgamma)
2145:           free(dataptr->holes[i]->core[j]->value[k]->naturalgamma);
2146:         else if(dataptr->type==SUSCEPTIBILITY && dataptr->holes[i]->core[j]->value[k]->susceptibility)
2147:           free(dataptr->holes[i]->core[j]->value[k]->susceptibility);
2148:         else if(dataptr->type==REFLECTANCEMST && dataptr->holes[i]->core[j]->value[k]->reflectanceMST)
2149:           free(dataptr->holes[i]->core[j]->value[k]->reflectanceMST);
2150:         free(dataptr->holes[i]->core[j]->value[k]);
2151:       }
2152:       free(dataptr->holes[i]->core[j]->value);
2153:       free(dataptr->holes[i]->core[j]);
2154:     }
2155:     free(dataptr->holes[i]);
2156:   }
2157:   if(dataptr->holes)
2158:   {
2159:     free(dataptr->holes);
2160:     dataptr->holes=NULL;
2161:   }
2162:   if(dataptr->name && (int)strlen((char*)dataptr->name)>0)
2163:   {
2164:     free(dataptr->name);
2165:     dataptr->name=NULL;
2166:   }
2167:   if(dataptr->holes_used && (int)strlen(dataptr->holes_used)>0)
2168:   {
2169:     free(dataptr->holes_used);
2170:     dataptr->holes_used=NULL;
2171:   }
2172:   dataptr->readerrors=0;
2173:   dataptr->numholes=0;
2174:   dataptr->numfiles=0;
2175:   return;
2176: }
2177: 
2178: SpOutputAgeModel()
2179: {
2180:         int             i, SpWriteAgeModel();
2181:         XmString        xmstring;
2182: 
2183:         if((fptr=fopen(outagemodel_filename,"w"))==NULL)
2184:         {
2185:               message.error=True;
2186:               if((message.label=(char*)calloc((int)strlen(outagemodel_filename)+100,CHAR_SIZE))==NULL)
2187:                                 SpBadMemAlloc("SpOutputAgeModel 1");
2188:               (void)sprintf(message.label,"Error Opening output age model file %s.",outagemodel_filename);
2189:               message.fatal=False;
2190:               message.caller=NONE;
2191:               message.type=XmDIALOG_WARNING;
2192:               message.default_button=XmDIALOG_OK_BUTTON;
2193:               SpManageMessage(message);
2194:               return(True);
2195:         }
2196:         else
2197:         {
2198:               if((charptr=(char*)calloc((int)strlen(outagemodel_filename)+100,CHAR_SIZE))==NULL)
2199:                                SpBadMemAlloc("SpOutputAgeModel 2");
2200:               (void)sprintf(charptr,"\nOutput age model file %s.\n",outagemodel_filename);
2201:               SpUpdateReport(charptr);
2202:               free(charptr);
2203: 
2204:               /* write the agemodel table to report
2205:               */
2206:               sprintf(buffer, "\nAge Model Table\n");
2207:               SpUpdateReport(buffer);
2208:               for(i=0; i<agemodel_cnt; ++i) {
2209:                 sprintf(buffer,"%10.2f%10.2f%10.3f     %s %s\n",
2210:                       agemodel[i].avembsf, agemodel[i].avemcd, agemodel[i].aveage, agemodel[i].name, agemodel[i].code);
2211:                 SpUpdateReport(buffer);
2212:               }
2213:               SpUpdateReport("\n");
2214:         }
2215: 
2216:         if((charptr=(char*)calloc((int)strlen(outagemodel_filename)+100,CHAR_SIZE))==NULL)
2217:                                 SpBadMemAlloc("SpOutputAgeModel 3");
2218:         (void)sprintf(charptr,"Age Model: Saving age model to file %s.", outagemodel_filename);
2219:         xmstring=XmStringCreateLocalized(&charptr[1]);
2220:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
2221:         XmStringFree(xmstring);
2222:         free(charptr);
2223:         XmUpdateDisplay(messageBoxWorking);
2224: 
2225:         (void)SpWriteAgeModel(fptr);
2226:         if((charptr=(char*)calloc((int)strlen(outagemodel_filename)+100,CHAR_SIZE))==NULL)
2227:                                 SpBadMemAlloc("SpOutputAgeModel 3");
2228:         (void)sprintf(charptr,"Age model save done.");
2229:         xmstring=XmStringCreateLocalized(&charptr[1]);
2230:         XtVaSetValues(messageBoxWorking,XmNmessageString,xmstring, NULL);
2231:         XmStringFree(xmstring);
2232:         free(charptr);
2233:         fclose(fptr);
2234:         XtUnmanageChild(messageBoxWorking);
2235:         return(True);
2236: }
2237: 
2238: 
2239: SpInputAgeModel()
2240: {
2241:         int             i, j, k, found, unfound, mbsferr, mcderr, SpReadAgeModel();
2242:         char            string[500];
2243:         XmString        xmstring;
2244:         void DrawDrawingAreaAgeDepth(), PlotSpliceVsAge();
2245: 
2246:         if((fptr=fopen(