Esempio n. 1
0
t_texture const	*load_texture(t_sub file_name, uint32_t flags)
{
	t_hmap *const	cache = texture_cache();
	char			key[sizeof(uint32_t) + file_name.length];
	t_texture		*texture;

	*(uint32_t*)key = flags;
	ft_memcpy(key + sizeof(uint32_t), file_name.str, file_name.length);
	if ((texture = ft_hmapget(cache, SUBV(key)).value) != NULL)
	{
		ft_logf(LOG_DEBUG, "Cached texture: %ts", file_name);
		return (texture);
	}
	texture = ft_hmapput(cache, SUBV(key), NULL, sizeof(t_texture)).value;
	texture->get = &texture_bilinear;
	if (!ft_load_img(file_name, &texture->img))
	{
		ft_logf(LOG_VERBOSE, "Failed to load '%ts'", file_name);
		ft_hmaprem(cache, SUBV(key), NULL);
		return (NULL);
	}
	if (flags & TEXTURE_GAMMA)
		correct_gamma(&texture->img);
	ft_logf(LOG_VERBOSE, "Texture file '%ts' loaded", file_name);
	return (texture);
}
Esempio n. 2
0
local void gravsub(nodeptr q)
{
    real drab, phii, mor3;
    vector ai, quaddr;
    real dr5inv, phiquad, drquaddr;

    if (q != (long) qmem) {              /* cant use memorized data? */
        SUBV(dr, Pos(q), pos0);                 /*   then compute sep.      */
	DOTVP(drsq, dr, dr);			/*   and sep. squared       */
    }
    drsq += eps*eps;                            /* use standard softening   */
    drab = rsqrt(drsq);
    phii = Mass(q) / drab;
    mor3 = phii / drsq;
    MULVS(ai, dr, mor3);
    phi0 -= phii;                               /* add to total grav. pot.  */
    ADDV(acc0, acc0, ai);                       /* ... and to total accel.  */
    if (usequad && Type(q) == CELL) {           /* if cell, add quad term   */
      cellptr SAFE c= TC(q);
        dr5inv = 1.0/(drsq * drsq * drab);      /*   form dr^-5             */
        MULMV(quaddr, Quad(c), dr);             /*   form Q * dr            */
        DOTVP(drquaddr, dr, quaddr);            /*   form dr * Q * dr       */
        phiquad = -0.5 * dr5inv * drquaddr;     /*   get quad. part of phi  */
        phi0 = phi0 + phiquad;                  /*   increment potential    */
        phiquad = 5.0 * phiquad / drsq;         /*   save for acceleration  */
        MULVS(ai, dr, phiquad);                 /*   components of acc.     */
        SUBV(acc0, acc0, ai);                   /*   increment              */
        MULVS(quaddr, quaddr, dr5inv);   
        SUBV(acc0, acc0, quaddr);               /*   acceleration           */
    }
}
Esempio n. 3
0
int main(int argc, string argv[])
{
  string prog, coords, itags[MaxBodyFields], otags[MaxBodyFields];
  stream xstr, ostr;
  bodyptr btab = NULL, bp;
  int nbody;
  real tnow;
  vector cmpos, cmvel, cmacc;

  initparam(argv, defv);
  exprs[0] = getparam("weight");
  prog = mktemp((string) copxstr("/tmp/sm_XXXXXX", sizeof(char)));
  buildmap(prog, names, exprs, types, NULL, Precision, NDIM, TRUE);
  xstr = execmap(prog);
  if (get_tag_ok(xstr, "History"))
    skip_item(xstr);
  get_history(xstr);
  ostr = stropen(getparam("out"), "w");
  put_history(ostr);
  coords = getparam("coords");
  new_field(&WeightField, RealType, "Weight");
  new_field(&WeightField + 1, NULL, NULL);
  while (get_snap(xstr, &btab, &nbody, &tnow, itags, TRUE, NULL)) {
    if (scanopt(coords, PosTag) && set_member(itags, PosTag)) {
      snapcmpos(cmpos, btab, nbody, WeightField.offset);
      for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
	SUBV(Pos(bp), Pos(bp), cmpos);
      }
      eprintf("[%s: centroid position: %f,%f,%f]\n", getprog(),
	      cmpos[0], cmpos[1], cmpos[2]);
    }
    if (scanopt(coords, VelTag) && set_member(itags, VelTag)) {
      snapcmvel(cmvel, btab, nbody, WeightField.offset);
      for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
	SUBV(Vel(bp), Vel(bp), cmvel);
      }
      eprintf("[%s: centroid velocity: %f,%f,%f]\n", getprog(),
	      cmvel[0], cmvel[1], cmvel[2]);
    }
    if (scanopt(coords, AccTag) && set_member(itags, AccTag)) {
      snapcmacc(cmacc, btab, nbody, WeightField.offset);
      for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
	SUBV(Acc(bp), Acc(bp), cmacc);
      }
      eprintf("[%s: cen. acceleration: %f,%f,%f]\n", getprog(),
	      cmacc[0], cmacc[1], cmacc[2]);
    }
    del_tag(otags, itags, "Weight");
    put_snap(ostr, &btab, &nbody, &tnow, otags);
  }
  strclose(ostr);
  if (unlink(prog) != 0)
    error("%s: can't unlink %s\n", getprog(), prog);
  return (0);
}
Esempio n. 4
0
bool isInBetw(vector pt, vector begin, vector end) {
    float dot, crossLength, eBLength;
    vector eB, pB, cross;
    SUBV(eB, end, begin);
    SUBV(pB, pt, begin);
    DOTVP(dot, eB, pB);
    CROSSVP(cross, eB, pB);
    ABSV(eBLength, eB);
    ABSV(crossLength, cross);
    return (crossLength < 0.0001f && dot >= 0.0000f && dot < eBLength * eBLength);
}
Esempio n. 5
0
void snapcenter(bodyptr btab, int nbody, int woff)
{
  vector cmpos, cmvel;
  bodyptr bp;

  snapcmpos(cmpos, btab, nbody, woff);
  snapcmvel(cmvel, btab, nbody, woff);
  for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
    SUBV(Pos(bp), Pos(bp), cmpos);
    SUBV(Vel(bp), Vel(bp), cmvel);
  }
}
Esempio n. 6
0
bool subdivp(register nodeptr p, real dsq, long ProcessId)
{
   SUBV(Local[ProcessId].dr, Pos(p), Local[ProcessId].pos0);
   DOTVP(Local[ProcessId].drsq, Local[ProcessId].dr, Local[ProcessId].dr);
   Local[ProcessId].pmem = p;
   return (tolsq * Local[ProcessId].drsq < dsq);
}
Esempio n. 7
0
local bool subdivp(nodeptr n)
{
  cellptr SAFE q = TC(n);
    SUBV(dr, PosC(q), pos0);			/* compute displacement     */
    DOTVP(drsq, dr, dr);			/* and find dist squared    */
    qmem = q;					/* remember we know them    */
    return (drsq < Rcrit2(q));			/* apply standard rule      */
}
Esempio n. 8
0
int point_in_triangle(vec2d A, vec2d B, vec2d C, vec2d P)
{
  vec2d v0; SUBV(v0, C, A);
  vec2d v1; SUBV(v1, B, A);
  vec2d v2; SUBV(v2, P, A);
  
  double dot00; DOTVP(dot00, v0, v0);
  double dot01; DOTVP(dot01, v0, v1);
  double dot02; DOTVP(dot02, v0, v2);
  double dot11; DOTVP(dot11, v1, v1);
  double dot12; DOTVP(dot12, v1, v2);
  
  double invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
  double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  
  return (u > 0.0) && (v > 0.0) && (u + v < 1.0);
}
Esempio n. 9
0
t_texture const	*load_texture1(uint32_t color, uint32_t flags)
{
	t_hmap *const	cache = texture_cache();
	uint32_t		key[2];
	t_texture		*tmp;

	key[0] = flags;
	key[1] = color;
	if ((tmp = ft_hmapget(cache, SUBV(key)).value) != NULL)
		return (tmp);
	tmp = ft_hmapput(cache, SUBV(key), NULL,
		sizeof(t_texture) + sizeof(uint32_t)).value;
	ft_logf(LOG_DEBUG, "Solid texture created: #%.8x", color);
	*tmp = (t_texture){&texture_solid, (t_img){ENDOF(tmp), 1, 1}};
	*tmp->img.data = color;
	if (flags & TEXTURE_GAMMA)
		correct_gamma(&tmp->img);
	return (tmp);
}
Esempio n. 10
0
// Same overall approach taken from Blender mathutils library.
float * intersect_ray_tri(vector v1, vector v2, vector v3, vector ray, vector origin) {
    float det, inv_det, u, v, t, absv;
    vector dir, e1, e2, tvec, qvec, pvec;
    NORMV(dir, ray);
    SUBV(e1, v2, v1);
    SUBV(e2, v3, v1);
    CROSSVP(pvec, dir, e2);
    DOTVP(det, e1, pvec);
    if (det > -0.000001f && det < 0.000001f) {
        return 0;
    }

    inv_det = 1.0f / det;
    SUBV(tvec, origin, v1);
    DOTVP(u, tvec, pvec);
    u = u * inv_det;
    if(u < 0.0f || u > 1.0f){
        return 0;
    }
    CROSSVP(qvec, tvec, e1);

    DOTVP(v, dir, qvec);
    v = v * inv_det;

    if (v < 0.0f || u + v > 1.0f) {
        return 0;
    }

    DOTVP(t, e2, qvec);
    t = t * inv_det;
    MULVS(dir, dir, t);
    ADDV(pvec, origin, dir);
    float *result = new float[3];
    result[0] = pvec[0];
    result[1] = pvec[1];
    result[2] = pvec[2];
    return result;
}
Esempio n. 11
0
local void centersnap(Body *btab, int nb)
{
    real mtot;
    vector cmphase[2], tmp;
    Body *bp;

    mtot = 0.0;
    CLRV(cmphase[0]);
    CLRV(cmphase[1]);
    for (bp = btab; bp < btab + nb; bp++) {
	mtot = mtot + Mass(bp);
	MULVS(tmp, Phase(bp)[0], Mass(bp));
	ADDV(cmphase[0], cmphase[0], tmp);
	MULVS(tmp, Phase(bp)[1], Mass(bp));
	ADDV(cmphase[1], cmphase[1], tmp);
    }
    MULVS(cmphase[0], cmphase[0], 1.0/mtot);
    MULVS(cmphase[1], cmphase[1], 1.0/mtot);
    for (bp = btab; bp < btab + nb; bp++) {
	SUBV(Phase(bp)[0], Phase(bp)[0], cmphase[0]);
	SUBV(Phase(bp)[1], Phase(bp)[1], cmphase[1]);
    }
}
Esempio n. 12
0
void gravsub(register nodeptr p, long ProcessId)
{
    real drabs, phii, mor3;
    vector ai;

    if (p != Local[ProcessId].pmem) {
        SUBV(Local[ProcessId].dr, Pos(p), Local[ProcessId].pos0);
        DOTVP(Local[ProcessId].drsq, Local[ProcessId].dr, Local[ProcessId].dr);
    }

    Local[ProcessId].drsq += epssq;
    drabs = sqrt((double) Local[ProcessId].drsq);
    phii = Mass(p) / drabs;
    Local[ProcessId].phi0 -= phii;
    mor3 = phii / Local[ProcessId].drsq;
    MULVS(ai, Local[ProcessId].dr, mor3);
    ADDV(Local[ProcessId].acc0, Local[ProcessId].acc0, ai);
    if(Type(p) != BODY) {                  /* a body-cell/leaf interaction? */
       Local[ProcessId].mynbcterm++;
#ifdef QUADPOLE
       dr5inv = 1.0/(Local[ProcessId].drsq * Local[ProcessId].drsq * drabs);
       MULMV(quaddr, Quad(p), Local[ProcessId].dr);
       DOTVP(drquaddr, Local[ProcessId].dr, quaddr);
       phiquad = -0.5 * dr5inv * drquaddr;
       Local[ProcessId].phi0 += phiquad;
       phiquad = 5.0 * phiquad / Local[ProcessId].drsq;
       MULVS(ai, Local[ProcessId].dr, phiquad);
       SUBV(Local[ProcessId].acc0, Local[ProcessId].acc0, ai);
       MULVS(quaddr, quaddr, dr5inv);
       SUBV(Local[ProcessId].acc0, Local[ProcessId].acc0, quaddr);
#endif
    }
    else {                                      /* a body-body interaction  */
       Local[ProcessId].myn2bterm++;
    }
}
Esempio n. 13
0
int main( int argc , char * argv[] )
{
   int ninp , ids , nv , iv,jv,kv , ivout , new_nvals , have_fdr = 0, nfdr = 0 ;
   THD_3dim_dataset * new_dset=NULL , * dset ;
   char buf[256] ;
   double angle;

   /*----- identify program -----*/
#if 0
   printf ("\n\nProgram %s \n", PROGRAM_NAME);
   printf ("Last revision: %s \n\n", LAST_MOD_DATE);
#endif

   /*** read input options ***/


   mainENTRY("3dbucket main"); machdep(); PRINT_VERSION("3dbucket") ;
   set_obliquity_report(0); /* silence obliquity */
   
   /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/

   { int new_argc ; char ** new_argv ;
     addto_args( argc , argv , &new_argc , &new_argv ) ;
     if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
   }

   AFNI_logger("3dbucket",argc,argv) ;

   BUCK_read_opts( argc , argv ) ;

   /*** create new dataset (empty) ***/
   ninp = BUCK_dsar->num ;
   if( ninp < 1 ){
      fprintf(stderr,"*** No input datasets?\n") ; exit(1) ;
   }

   new_nvals = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ) new_nvals += NSUBV(ids) ;

   if( BUCK_verb ) printf("-verb: output will have %d sub-bricks\n",new_nvals) ;

   new_dset = EDIT_empty_copy( DSUB(0) ) ;

   /* 23 May 2005: check for axis consistency */
   /* 06 Feb 2008: and see if there are fdrcurves to perpetuate */

   if( DSUB(0)->dblk->brick_fdrcurve ) have_fdr = 1 ;
   for( iv=1 ; iv < ninp ; iv++ ){
     if( !EQUIV_DATAXES(new_dset->daxes,DSUB(iv)->daxes) )
       fprintf(stderr,"++ WARNING: %s grid mismatch with %s\n",
               DSET_BRIKNAME(DSUB(0)) , DSET_BRIKNAME(DSUB(iv)) ) ;
     if( DSUB(iv)->dblk->brick_fdrcurve ) have_fdr = 1 ;
     angle = dset_obliquity_angle_diff(new_dset, DSUB(iv), -1.0);
     if (angle > 0.0) {
       WARNING_message(
          "dataset %s has an obliquity difference of %f degress with %s\n",
          new_dset ,
          angle, DSUB(iv) );
     }
   }

   /*  if( ninp == 1 ) */   tross_Copy_History( DSUB(0) , new_dset ) ;
   tross_Make_History( "3dbucket" , argc,argv , new_dset ) ;

   EDIT_dset_items( new_dset ,
                      ADN_prefix        , BUCK_output_prefix ,
                      ADN_directory_name, BUCK_session ,
                      ADN_type          , BUCK_type ,
                      ADN_func_type     , ISANATTYPE(BUCK_type) ? ANAT_BUCK_TYPE
                                                                : FUNC_BUCK_TYPE,
                      ADN_ntt           , 0 ,
                      ADN_nvals         , new_nvals ,
                    ADN_none ) ;

   /* can't re-write existing dataset, unless glueing is used */

   if (! BUCK_glue){
     if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ){
       fprintf(stderr,"*** Fatal error: file %s already exists!\n",
               DSET_HEADNAME(new_dset) ) ;
       exit(1) ;
     }
   } else {   /* if glueing is used, make the 'new'
                 dataset have the same idcode as the old one */

      new_dset->idcode = DSUB(0) -> idcode ;  /* copy the struct */
   }

   THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ;

   /* if there are fdr curves, allocate space    06 Feb 2008 [rickr] */
   if( have_fdr ){
      new_dset->dblk->brick_fdrcurve = (floatvec **)calloc(sizeof(floatvec *),
                                                           new_nvals) ;
      if( !new_dset->dblk->brick_fdrcurve ){
         fprintf(stderr,"** failed to alloc %d fdrcurves\n",new_nvals);
         exit(1);
      }
      if( BUCK_verb ) printf("-verb: adding fdrcurve list\n");

      new_dset->dblk->brick_mdfcurve = (floatvec **)calloc(sizeof(floatvec *),
                         /* 22 Oct 2008 */                 new_nvals) ;
   }

   /*** loop over input datasets ***/

   if( ninp > 1 ) myXtFree( new_dset->keywords ) ;

   ivout = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ){
      dset = DSUB(ids) ;
      nv   = NSUBV(ids) ;

      if( ! BUCK_dry ){
         DSET_load(dset) ;  CHECK_LOAD_ERROR(dset) ;
      }
      /** loop over sub-bricks to output **/

      for( iv=0 ; iv < nv ; iv++ ){
         jv = SUBV(ids,iv) ;                /* which sub-brick to use */

         if( ! BUCK_dry ){
            EDIT_substitute_brick( new_dset , ivout ,
                                   DSET_BRICK_TYPE(dset,jv) , DSET_ARRAY(dset,jv) ) ;

            /*----- preserve label when one exists --- Modified March 2010 ZSS*/
            if (DSET_HAS_LABEL(dset, jv) ) 
              sprintf (buf, "%s", DSET_BRICK_LABEL(dset,jv));
            else
              sprintf(buf,"%.12s[%d]",DSET_PREFIX(dset),jv) ;
            EDIT_dset_items( new_dset , ADN_brick_label_one+ivout, buf , ADN_none ) ;

#if 0
            sprintf(buf,"%s[%d]",DSET_FILECODE(dset),jv) ;
            EDIT_dset_items(
              new_dset, ADN_brick_keywords_replace_one+ivout, buf, ADN_none ) ;
#endif

            EDIT_dset_items(
              new_dset ,
                ADN_brick_fac_one            +ivout, DSET_BRICK_FACTOR(dset,jv),
#if 0
                ADN_brick_keywords_append_one+ivout, DSET_BRICK_KEYWORDS(dset,jv) ,
#endif
              ADN_none ) ;

            /** possibly write statistical parameters for this sub-brick **/

            kv = DSET_BRICK_STATCODE(dset,jv) ;

            if( FUNC_IS_STAT(kv) ){ /* input sub-brick has stat params */

               int npar = FUNC_need_stat_aux[kv] , lv ;
               float * par = (float *) malloc( sizeof(float) * (npar+2) ) ;
               float * sax = DSET_BRICK_STATAUX(dset,jv) ;
               par[0] = kv ;
               par[1] = npar ;
               for( lv=0 ; lv < npar ; lv++ )
                  par[lv+2] = (sax != NULL) ? sax[lv] : 0.0 ;

               EDIT_dset_items(new_dset ,
                                ADN_brick_stataux_one+ivout , par ,
                               ADN_none ) ;
               free(par) ;

            /* 2: if the input dataset has statistical parameters */

            } else if( ISFUNC(dset)                        &&   /* dset has stat */
                       FUNC_IS_STAT(dset->func_type)       &&   /* params        */
                       jv == FUNC_ival_thr[dset->func_type]  ){ /* thr sub-brick */

               int npar , lv ;
               float * par , * sax ;
               kv  = dset->func_type ;
               npar = FUNC_need_stat_aux[kv] ;
               par  = (float *) malloc( sizeof(float) * (npar+2) ) ;
               sax  = dset->stat_aux ;
               par[0] = kv ;
               par[1] = npar ;
               for( lv=0 ; lv < npar ; lv++ )
                  par[lv+2] = (sax != NULL) ? sax[lv] : 0.0 ;

               EDIT_dset_items(new_dset ,
                                ADN_brick_stataux_one+ivout , par ,
                               ADN_none ) ;
               free(par) ;
            }

            /** append any fdrcurve **/
            if( have_fdr ){
               /* fixed iv->jv (ick!), noticed by dglen  16 Mar 2010 [rickr] */
               if(dset->dblk->brick_fdrcurve && dset->dblk->brick_fdrcurve[jv]){
                  COPY_floatvec(new_dset->dblk->brick_fdrcurve[ivout],
                                    dset->dblk->brick_fdrcurve[jv]) ;
                  nfdr++;
               }
               else new_dset->dblk->brick_fdrcurve[ivout] = NULL ;

               if(dset->dblk->brick_mdfcurve && dset->dblk->brick_mdfcurve[jv]){
                  COPY_floatvec(new_dset->dblk->brick_mdfcurve[ivout],
                                    dset->dblk->brick_mdfcurve[jv]) ;
               }
               else new_dset->dblk->brick_mdfcurve[ivout] = NULL ;
            }

            /** print a message? **/

            if( BUCK_verb ) printf("-verb: copied %s[%d] into %s[%d]\n" ,
                                   DSET_FILECODE(dset) , jv ,
                                   DSET_FILECODE(new_dset) , ivout ) ;
         } else {
            printf("-dry: would copy %s[%d] into %s[%d]\n" ,
                    DSET_FILECODE(dset) , jv ,
                    DSET_FILECODE(new_dset) , ivout ) ;
         }

         ivout++ ;
      }

      /** loop over all bricks in input dataset and
          unload them if they aren't going into the output
          (not required, but is done to economize on memory) **/

      if( ! BUCK_dry && nv < DSET_NVALS(dset) ){

         for( kv=0 ; kv < DSET_NVALS(dset) ; kv++ ){  /* all input sub-bricks */
            for( iv=0 ; iv < nv ; iv++ ){             /* all output sub-bricks */
               jv = SUBV(ids,iv) ;
               if( jv == kv ) break ;                 /* input matches output */
            }
            if( iv == nv ){
               mri_free( DSET_BRICK(dset,kv) ) ;
#if 0
               if( BUCK_verb ) printf("-verb: unloaded unused %s[%d]\n" ,
                                      DSET_FILECODE(dset) , kv ) ;
#endif
            }
         }
      }

   } /* end of loop over input datasets */

   if( ! BUCK_dry ){
      if( BUCK_verb ){
         if( have_fdr ) fprintf(stderr,"-verb: added %d of %d fdr curves\n",
                                nfdr, new_nvals);
         fprintf(stderr,"-verb: loading statistics\n") ;
      }
      THD_load_statistics( new_dset ) ;
      if( BUCK_glue ) putenv("AFNI_DECONFLICT=OVERWRITE") ;
      if( BUCK_glue && BUCK_ccode >= 0 )
        THD_set_write_compression(BUCK_ccode) ; /* 16 Mar 2010 */
      THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
      if( BUCK_verb ) fprintf(stderr,"-verb: wrote output: %s\n",DSET_BRIKNAME(new_dset)) ;
   }

   exit(0) ;
}
Esempio n. 14
0
int main( int argc , char * argv[] )
{
   int ninp , ids , nv , iv,jv,kv , ivout , new_nvals ;
   THD_3dim_dataset * new_dset=NULL , * dset ;
   char buf[256] ;

  /*----- Identify software -----*/
#if 0
  printf ("\n\n");
  printf ("Program: %s \n", PROGRAM_NAME);
  printf ("Author:  %s \n", PROGRAM_AUTHOR);
  printf ("Initial Release:  %s \n", PROGRAM_INITIAL);
  printf ("Latest Revision:  %s \n", PROGRAM_LATEST);
  printf ("\n");
#endif


   /*** read input options ***/

   if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) B2F_Syntax() ;

   mainENTRY("3dbuc2fim main"); machdep(); AFNI_logger(PROGRAM_NAME,argc,argv);
   PRINT_VERSION("3dbuc2fim") ; AUTHOR(PROGRAM_AUTHOR);

   B2F_read_opts( argc , argv ) ;

   /*** create new dataset (empty) ***/
   ninp = B2F_dsar->num ;
   if( ninp < 1 ){
      fprintf(stderr,"*** No input datasets?\n") ; exit(1) ;
   }

   new_nvals = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ) new_nvals += NSUBV(ids) ;

   /*----- Check for acceptable number of sub-bricks -----*/
   if (new_nvals < 1)
     { fprintf(stderr,"*** Less than 1 sub-brick specified\n") ; exit(1) ; }
   if (new_nvals > 2)
     { fprintf(stderr,"*** More than 2 sub-bricks specified\n") ; exit(1) ; }


   if( B2F_verb ) printf("-verb: output will have %d sub-bricks\n",new_nvals) ;

   new_dset = EDIT_empty_copy( DSUB(0) ) ;

   if( ninp == 1 ) tross_Copy_History( DSUB(0) , new_dset ) ;
   tross_Make_History( "3dbuc2fim" , argc,argv , new_dset ) ;

   /*-----  Set default value for function type. This will be changed later,
            if the second sub-brick has a statistic type.  -----*/
   if (new_nvals == 1)
     B2F_func_type = FUNC_FIM_TYPE;
   else
     B2F_func_type = FUNC_THR_TYPE;


   EDIT_dset_items (new_dset ,
		    ADN_prefix        , B2F_output_prefix ,
		    ADN_directory_name, B2F_session ,
		    ADN_type          , HEAD_FUNC_TYPE,
		    ADN_func_type     , B2F_func_type,
		    ADN_ntt           , 0 ,
		    ADN_nvals         , new_nvals ,
                    ADN_none ) ;


   if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ){
     fprintf(stderr,"*** Fatal error: file %s already exists!\n",
	     DSET_HEADNAME(new_dset) ) ;
     exit(1) ;
   }

   THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ;

   /*** loop over input datasets ***/

   if( ninp > 1 ) myXtFree( new_dset->keywords ) ;

   ivout = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ){
      dset = DSUB(ids) ;
      nv   = NSUBV(ids) ;

      DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;


      /** loop over sub-bricks to output **/

      for( iv=0 ; iv < nv ; iv++ ){
         jv = SUBV(ids,iv) ;                /* which sub-brick to use */

	 EDIT_substitute_brick( new_dset , ivout ,
				DSET_BRICK_TYPE(dset,jv) , DSET_ARRAY(dset,jv) ) ;
	
	 /*----- If this sub-brick is from a bucket dataset,
	   preserve the label for this sub-brick -----*/
	 if (dset->func_type == FUNC_BUCK_TYPE)
	   sprintf (buf, "%s", DSET_BRICK_LABEL(dset,jv));
	 else
	   sprintf(buf,"%.12s[%d]",DSET_PREFIX(dset),jv) ;
	 EDIT_dset_items( new_dset , ADN_brick_label_one+ivout, buf , ADN_none ) ;

#if 0	
	 sprintf(buf,"%s[%d]",DSET_FILECODE(dset),jv) ;
	 EDIT_dset_items(
			 new_dset, ADN_brick_keywords_replace_one+ivout, buf, ADN_none ) ;
#endif
	
	 EDIT_dset_items(
			 new_dset ,
			 ADN_brick_fac_one            +ivout, DSET_BRICK_FACTOR(dset,jv),
#if 0
			 ADN_brick_keywords_append_one+ivout, DSET_BRICK_KEYWORDS(dset,jv) ,
#endif
			 ADN_none ) ;
	
	 /** possibly write statistical parameters for this sub-brick **/
	
	 kv = DSET_BRICK_STATCODE(dset,jv) ;
	
	 if( FUNC_IS_STAT(kv) ){ /* input sub-brick has stat params */
	
	   int npar = MAX_STAT_AUX , lv ;
	   float * par = (float *) malloc( sizeof(float) * (npar) ) ;
	   float * sax = DSET_BRICK_STATAUX(dset,jv) ;
	   for( lv=0 ; lv < npar ; lv++ )
	     par[lv] = (sax != NULL && lv < FUNC_need_stat_aux[kv]) ? sax[lv] : 0.0;
	
	   if (ivout == 1)
	     {
	       EDIT_dset_items(new_dset ,
			       ADN_func_type     , kv,		
			       ADN_stat_aux, par ,
			       ADN_none ) ;
	     }
	
	   free(par) ;
	
	     /* 2: if the input dataset has statistical parameters */

	 } else if( ISFUNC(dset)                        &&   /* dset has stat */
		    FUNC_IS_STAT(dset->func_type)       &&   /* params        */
		    jv == FUNC_ival_thr[dset->func_type]  ){ /* thr sub-brick */
	
	   int npar , lv ;
	   float * par , * sax ;
	   kv  = dset->func_type ;
	   npar = MAX_STAT_AUX ;
	   par  = (float *) malloc( sizeof(float) * (npar+2) ) ;
	   sax  = dset->stat_aux ;
	   for( lv=0 ; lv < npar ; lv++ )
	     par[lv] = (sax != NULL) ? sax[lv] : 0.0 ;
	

	   if (ivout == 1)
	     {
	       for( lv=0 ; lv < npar+2 ; lv++ )
		 printf ("par[%d] = %f \n", lv, par[lv]);
	       EDIT_dset_items(new_dset ,
			       ADN_func_type     , kv,		
			       ADN_stat_aux, par ,
			       ADN_none ) ;
	     }
	
	   free(par) ;
	 }
	
	 /** print a message? **/
	
	 if( B2F_verb ) printf("-verb: copied %s[%d] into %s[%d]\n" ,
			       DSET_FILECODE(dset) , jv ,
			       DSET_FILECODE(new_dset) , ivout ) ;
	 ivout++ ;
      }

      /** loop over all bricks in input dataset and
	unload them if they aren't going into the output
	(not required, but is done to economize on memory) **/

      if( nv < DSET_NVALS(dset) ){
	
	for( kv=0 ; kv < DSET_NVALS(dset) ; kv++ ){  /* all input sub-bricks */
	  for( iv=0 ; iv < nv ; iv++ ){             /* all output sub-bricks */
	    jv = SUBV(ids,iv) ;
	    if( jv == kv ) break ;                 /* input matches output */
	  }
	  if( iv == nv ){
	    mri_free( DSET_BRICK(dset,kv) ) ;
#if 0
	    if( B2F_verb ) printf("-verb: unloaded unused %s[%d]\n" ,
				  DSET_FILECODE(dset) , kv ) ;
#endif
	  }
	}
      }

   } /* end of loop over input datasets */


   if( B2F_verb ) fprintf(stderr,"-verb: loading statistics\n") ;
   THD_load_statistics( new_dset ) ;
   THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
   if( B2F_verb ) fprintf(stderr,"-verb: wrote output: %s\n",DSET_BRIKNAME(new_dset)) ;


   exit(0) ;
}