Beispiel #1
0
Graph *load_graph(Database *db){
    if(db == NULL){
        puts("Error: load graph failed. Db is null.");
        exit(1);
    }
    Graph *graph = _new_graph();
    graph->db = db;
    graph->nodes = NULL;

    int i;
    uint64_t count = 0;
    uint64_t total = 0;
    NodeData *node_data;
    ArcData *arc_data;
    Node *node;
    Arc *arc;
    ArcNode *arcnode;

    puts("Loading graph into memory...");
    fseek(db->fp, 0L, SEEK_SET);
    while(!feof(db->fp)){
        node_data = malloc(sizeof(NodeData));
        count = read_database(node_data, sizeof(NodeData), db);
        total += count;
        if(count == 0){
            continue;
        }
        HASH_FIND_INT(graph->nodes, &(node_data->id), node);
        if(node != NULL){
            printf("Error: node %i already in tree.\n", node_data->id);
            exit(1);
        }
        node = _new_node(node_data, graph);
        HASH_ADD_INT(graph->nodes, data->id, node);
        if(node_data->num_arcnodes > 0){
            for(i=0; i<node_data->num_arcnodes; i++){
                arc_data = malloc(sizeof(ArcData));
                total += read_database((void *)arc_data, sizeof(ArcData), db);
                arc = _new_arc(arc_data);
                arcnode = _new_arcnode(arc);
                node->arcnodes[i] = arcnode;
            }
        }
    }
    printf("Loaded %i nodes.\n", (int)HASH_COUNT(graph->nodes));
    printf("Read %llu bytes from database.\n", (long long unsigned int)total);
    return graph;
}
Beispiel #2
0
int psr_number_from_name(char *psrname)
/* Returns the pulsar number of psrname from the database */
/* This number can be from zero to the total number       */
/* of pulsars minus 1.  This way you can use this number  */
/* as an index from the result of collect_psrparams().    */
/* Return -1 if no pulsar is found.                       */
{
   int ii, psrnumber = -1;
   char *matchname, jname[13], bname[9];

   matchname = strlower(psrname);
   if (matchname[0] == 'j' || matchname[0] == 'b')
      matchname++;

   /* Read the database if needed */
   if (!have_database)
      np = read_database();

   /* Search for the J-name, the B-name, or the alias */
   for (ii = 0; ii < np; ii++) {
      strncpy(jname, pulsardata[ii].jname, 13);
      strncpy(bname, pulsardata[ii].bname, 9);
      if (!strcmp(strlower(jname), matchname) ||
          !strcmp(strlower(bname), matchname) ||
          !strcmp(pulsardata[ii].alias, matchname)) {
         psrnumber = ii;
         break;
      }
   }

   /* Return the pulsar number */

   return psrnumber;
}
Beispiel #3
0
/* GENERATE_CLSF

   15nov94 wmt: pass n_data = 0, rather than 300 to read_database;
        use apply_search_start_fn
   25apr95 wmt: add binary data file capability
   20may95 wmt: added G_prediction_p

   Generates and returns a classification from data-base and model(s).
   Checks for data-base and model(s) already available in *db-list* and
   *model-list* and if found uses them, otherwise it generates data-base
   and model(s) by combining information from data-file, header-file, and
   model-file.  Optionally initializes the classification using the start-fn.
   N-CLASSES is the initial value for the initialized classification.
   DATA-FILE is fully qualified pathname (file type forced to *data-file-type*).
   HEADER-FILE can be omitted (gets the same file name as data-file), be a file
   name (gets the same root as data-file), or be a fully qualified pathname.
   In all cases, the file type is forced to *header-file-type*.  MODEL-FILE has
   same behavior as header-file. The file type is forced to *model-file-type*.
   LOG-FILE-P can be nil (no log file produced). If t the file type is forced
   to be *log-file-type*.  OUTPUT-FILES-DEFAULT (names the log file) can be
   omitted (gets the same root as data-file and file-name of <data-file file
   name>&<header-file file name>& <model-file file name>, be a file name
   (gets the same root as data-file), or be a fully qualified pathname.
   (REREAD_P T) forces a re-read of data-file, and (REGENERATE_P T) forces a
   re-generation of the model(s) even if they are found in *db-list* and
   *model-list*.  CLSF-INIT-FUN specifies the classification initialization
   function.  (DISPLAY-WTS T) will display class weights produced by the
   initialization.  *package* is bound for interns by read.
   */
clsf_DS generate_clsf( int n_classes, FILE *header_file_fp, FILE *model_file_fp,
        FILE *log_file_fp, FILE *stream, int reread_p, int regenerate_p,
        char *data_file_ptr, char *header_file_ptr, char *model_file_ptr,
        char *log_file_ptr, int restart_p, char *start_fn_type,
        unsigned int initial_cycles_p, int max_data,
                       int start_j_list_from_s_params)
{
  int total_error_cnt, total_warning_cnt, num_models = 0;
  clsf_DS clsf;
  database_DS db;
  model_DS *models;
  int expand_p = FALSE;

  /* read_database & read_model_file are done here because jtp designed
     it this way, moving them to process_data_header_model_files breaks
     the program  - wmt */

  log_header(log_file_fp, stream, data_file_ptr, header_file_ptr, model_file_ptr,
             log_file_ptr);

  db = read_database( header_file_fp, log_file_fp, data_file_ptr, header_file_ptr,
                     max_data, reread_p, stream);

  models = read_model_file(model_file_fp, log_file_fp, db, regenerate_p, expand_p,
                           stream, &num_models, model_file_ptr); 

  process_data_header_model_files( log_file_fp, regenerate_p, stream, db, models,
                                  num_models, &total_error_cnt, &total_warning_cnt);

  if ((G_prediction_p == FALSE) && (start_j_list_from_s_params == FALSE) &&
      (restart_p == FALSE) && (db->n_data > 1000)) {
    to_screen_and_log_file("\nWARNING: the default start_j_list may not find the correct\n"
                           "         number of classes in your data set!\n",
                           log_file_fp, stream, TRUE);
    total_warning_cnt++;
  }
 
  check_stop_processing( total_error_cnt, total_warning_cnt, log_file_fp, stderr);

  if ((G_prediction_p == TRUE) && (G_training_clsf != NULL))
    models = G_training_clsf->models;

  clsf = set_up_clsf( n_classes, db, models, num_models);

  if ((restart_p == FALSE) && (G_prediction_p == FALSE))
    apply_search_start_fn (clsf, start_fn_type, initial_cycles_p, n_classes,
                           log_file_fp, stream);
  return(clsf);
} 
Beispiel #4
0
static void
init(void) 
{
  char *dname;
  FILE *in;

  if (!inited) {
    inited = 1;
    dname = getenv("JBOFIHE_DICTIONARY");
    if (!dname) {
      dname = DEFAULT_DICTIONARY;
    }
    in = fopen(dname, "rb");
    if (!in) {
      inited = -1;
    } else {
      read_database(in);
      fclose(in);
    }
  }
}
Beispiel #5
0
void get_psrparams(psrparams * psr, char *psrname)
/* Read a full pulsar database entry for pulsar psrname. */
/* Return the data in a psrparams structure.             */
{
   int pnum = 0;

   /* Read the database if needed */
   if (!have_database)
      np = read_database();

   /* Find the pulsar of interest */
   pnum = psr_number_from_name(psrname);

   /* Fill the structure with data */
   if (pnum >= 0)
      get_psr(pnum, psr);
   else {
      printf("Could not find the PSR in the database in get_psrparams().\n");
      exit(2);
   }
}
Beispiel #6
0
/* heavily outdated */
int main(int argc, char **argv)
{
	wchar_t *database = mbstowcs_alloc("test_file");

/*	if (database == NULL)
		memerrmsg("main in dbio.c");
*/
	/* REMEMBER: set the INDEXDIR environment variable. */
	setProgramName(*argv);
	findUtf8OrDie();
	set_dbase_dir();
	/* Testing with book.idx and db, renamed, then edited sending output to
	   stdout, so I can compare! */
	fprintf(stderr, "Reading indexfile\n");
	read_idxfile(database);
	fprintf(stderr, "Reading databasefile\n");
	read_database(database);
	print_db(database, NULL);
	dbmodified = 1;
	save_db();
	release_idx();
	release_db();
	return 0;
}
Beispiel #7
0
void nfosc_start() {
    if (running) return;
    
    max_symbol_id = 0;
    session_id = -1;
    buffer_size = 0;
    
    // try to open the NFC device
    printf("nfOSC v0.5 using libnfc v%s\n", nfc_version());
    printf("looking for NFC devices ...\n");
    fflush(stdout);
    
    nfc_init(&context);
    if (context == NULL) {
        fprintf(stderr, "unable to init libnfc (malloc)\n");
        exit(1);
    }
    
    nfc_connstring connstrings[MAX_DEVICE_COUNT];
    size_t szFound = nfc_list_devices (context, connstrings, MAX_DEVICE_COUNT);
    
    no_devices = (int)szFound;
    for (int dev=0;dev<no_devices;dev++) {
        pnd[device_count] = nfc_open(context, connstrings[dev]);
        if (pnd[device_count] == NULL) continue;
        nfc_initiator_init(pnd[device_count]);
        
        // drop the field for a while
        nfc_device_set_property_bool(pnd[device_count],NP_ACTIVATE_FIELD,false);
        
        // let the reader only try once to find a tag
        nfc_device_set_property_bool(pnd[device_count],NP_INFINITE_SELECT,false);
        
        // configure the CRC and Parity settings
        nfc_device_set_property_bool(pnd[device_count],NP_HANDLE_CRC,true);
        nfc_device_set_property_bool(pnd[device_count],NP_HANDLE_PARITY,true);
        
        // enable field so more power consuming cards can power themselves up
        nfc_device_set_property_bool(pnd[device_count],NP_ACTIVATE_FIELD,true);
        
        printf("connected to NFC reader #%d: %s\n",device_count,nfc_device_get_name(pnd[device_count]));
        device_count++;
    }
    
    no_devices = device_count;
    
    
    if (device_count==0) {
        printf("no device found!\n");
        return;
    } else if (device_count==1) {
        printf("1 device found\n");
        sprintf(source_string, "NFOSC");
    } else printf("%d devices found\n", device_count);
    
    read_database();
    
    printf("sending OSC packets to %s %s\n",host,port);
    target = lo_address_new(host, port);
    
    running = true;
    
    pthread_create(&main_thread , NULL, (void *)&main_loop, NULL);
    
}
Beispiel #8
0
int comp_rawbin_to_cand(rawbincand * cand, infodata * idata, char *output, int full)
/* Compares a binary PSR candidate defined by its props found in    */
/*   *cand, and *idata with all of the pulsars in the pulsar        */
/*   database.  It returns a string (verbose if full==1) describing */
/*   the results of the search in *output.                          */
{
   int ii, jj, kk;
   static int np;
   double theop, ra, dec, beam2, difft = 0.0, epoch;
   double bmod, pmod, orbperr, psrperr;
   char tmp1[80], tmp2[80], tmp3[80];

   /* Read the database if needed */

   if (!have_database)
      np = read_database();

   /* Convert the beam width to radians */

   beam2 = 2.0 * ARCSEC2RAD * idata->fov;

   /* Convert RA and DEC to radians  (Use J2000) */

   ra = hms2rad(idata->ra_h, idata->ra_m, idata->ra_s);
   dec = dms2rad(idata->dec_d, idata->dec_m, idata->dec_s);

   /* Calculate the time related variables  */

   epoch = (double) idata->mjd_i + idata->mjd_f;

   /* Calculate the approximate error in our value of orbital period */

   orbperr = 0.5 * cand->full_T / cand->mini_N;

   /* Calculate the approximate error in our value of spin period */

   if (cand->full_lo_r == 0.0)
      psrperr = cand->psr_p;
   else
      psrperr = fabs(cand->full_T /
                     (cand->full_lo_r + 0.5 * cand->mini_N) -
                     cand->full_T / cand->full_lo_r);

   /* Run through RAs in database looking for things close  */
   /* If find one, check the DEC as well (the angle between */
   /* the sources < 2*beam diam).  If find one, check its   */
   /* period.  If this matches within 2*perr, return the    */
   /* number of the pulsar.  If no matches, return 0.       */

   for (ii = 0; ii < np; ii++) {

      /* See if we're close in RA */

      if (fabs(pulsardata[ii].ra2000 - ra) < 5.0 * beam2) {

         /* See if we're close in RA and DEC */

         if (sphere_ang_diff(pulsardata[ii].ra2000, pulsardata[ii].dec2000,
                             ra, dec) < 5.0 * beam2) {

            /* Check that the psr in the database is in a binary   */

            if (pulsardata[ii].orb.p != 0.0) {

               /* Predict the period of the pulsar at the observation MJD */

               difft = SECPERDAY * (epoch - pulsardata[ii].timepoch);
               theop = pulsardata[ii].p + pulsardata[ii].pd * difft;

               /* Check the predicted period and its harmonics against the */
               /* measured period.  Use both pulsar and binary periods.    */

               for (jj = 1; jj < 41; jj++) {
                  pmod = 1.0 / (double) jj;
                  if (fabs(theop * pmod - cand->psr_p) < psrperr) {
                     for (kk = 1; kk < 10; kk++) {
                        bmod = (double) kk;
                        if (fabs
                            (pulsardata[ii].orb.p * bmod - cand->orb_p / SECPERDAY) <
                            orbperr) {
                           if (strlen(pulsardata[ii].bname) == 0) {
                              if (jj > 1) {
                                 if (full) {
                                    sprintf(tmp1,
                                            "Possibly the %s phasemod harmonic ",
                                            num[kk]);
                                    sprintf(tmp2, "of the %s harmonic of PSR ",
                                            num[jj]);
                                    sprintf(tmp3,
                                            "J%s (p = %11.7f s, pbin = %9.4f d).\n",
                                            pulsardata[ii].jname, theop,
                                            pulsardata[ii].orb.p);
                                    sprintf(output, "%s%s%s", tmp1, tmp2, tmp3);
                                 } else {
                                    sprintf(output, "%s H J%.12s", num[kk],
                                            pulsardata[ii].jname);
                                 }
                              } else {
                                 if (full) {
                                    sprintf(tmp1,
                                            "Possibly the %s phasemod harmonic ",
                                            num[kk]);
                                    sprintf(tmp2,
                                            "of PSR J%s (p = %11.7f s, pbin = %9.4f d).\n",
                                            pulsardata[ii].jname, theop,
                                            pulsardata[ii].orb.p);
                                    sprintf(output, "%s%s", tmp1, tmp2);
                                 } else {
                                    sprintf(output, "PSR J%.12s",
                                            pulsardata[ii].jname);
                                 }
                              }
                           } else {
                              if (jj > 1) {
                                 if (full) {
                                    sprintf(tmp1,
                                            "Possibly the %s modulation harmonic ",
                                            num[kk]);
                                    sprintf(tmp2, "of the %s harmonic of PSR ",
                                            num[jj]);
                                    sprintf(tmp3,
                                            "B%s (p = %11.7f s, pbin = %9.4f d).\n",
                                            pulsardata[ii].bname, theop,
                                            pulsardata[ii].orb.p);
                                    sprintf(output, "%s%s%s", tmp1, tmp2, tmp3);
                                 } else {
                                    sprintf(output, "%s H B%s", num[kk],
                                            pulsardata[ii].bname);
                                 }
                              } else {
                                 if (full) {
                                    sprintf(tmp1,
                                            "Possibly the %s phasemod harmonic ",
                                            num[kk]);
                                    sprintf(tmp2,
                                            "of PSR B%s (p = %11.7f s, pbin = %9.4f d).\n",
                                            pulsardata[ii].bname, theop,
                                            pulsardata[ii].orb.p);
                                    sprintf(output, "%s%s", tmp1, tmp2);
                                 } else {
                                    sprintf(output, "PSR B%s", pulsardata[ii].bname);
                                 }
                              }
                           }
                        }
                        return ii + 1;
                     }
                  }
               }
            }
         }
      }
   }

   /* Didn't find a match */

   if (full) {
      sprintf(output, "I don't recognize this candidate in the pulsar database.\n");
   } else {
      sprintf(output, "                  ");
   }
   return 0;
}
Beispiel #9
0
int comp_psr_to_cand(fourierprops * cand, infodata * idata, char *output, int full)
/* Compares a pulsar candidate defined by its properties found in   */
/*   *cand, and *idata with all of the pulsars in the pulsar        */
/*   database.  It returns a string (verbose if full==1) describing */
/*   the results of the search in *output.                          */
{
   int ii, jj;
   static infodata *old_idata;
   double theor, theoz, sidedr = 20.0;
   double r_criteria, z_criteria, rdiff, zdiff, difft = 0;
   static double T, beam2, ra, dec, epoch;
   char tmp1[80], tmp2[80], tmp3[80], shortout[30], psrname[20];
   rzwerrs rzws;

   /* Read the database if needed */

   if (!have_database)
      np = read_database();

   /* If calling for the first time for a certain data set, */
   /* initialize some values.                               */

   if (idata != old_idata) {
      /* Convert the beam width to radians */

      beam2 = 2.0 * ARCSEC2RAD * idata->fov;

      /* Convert RA and DEC to radians  (Use J2000) */

      ra = hms2rad(idata->ra_h, idata->ra_m, idata->ra_s);
      dec = dms2rad(idata->dec_d, idata->dec_m, idata->dec_s);
      T = idata->N * idata->dt;
      epoch = (double) idata->mjd_i + idata->mjd_f + T / (2.0 * SECPERDAY);

      /* Set up old_idata for next time */

      old_idata = idata;
   }
   /* Calculate the measured r, z, w's and their derivatives */

   calc_rzwerrs(cand, T, &rzws);

   /* Run through RAs in database looking for things close  */
   /* If find one, check the DEC as well (the angle between */
   /* the sources < 2*beam diam).  If find one, check its   */
   /* period.  If this matches within 2*perr, return the    */
   /* number of the pulsar.  If no matches, return 0.       */

   for (ii = 0; ii < np; ii++) {

      /* See if we're close in RA */

      if (fabs(pulsardata[ii].ra2000 - ra) < 5 * beam2) {

         /* See if we're close in RA and DEC */

         if (sphere_ang_diff(pulsardata[ii].ra2000, pulsardata[ii].dec2000,
                             ra, dec) < 5 * beam2) {

            /* Predict the period of the pulsar at the observation MJD */

            difft = SECPERDAY * (epoch - pulsardata[ii].timepoch);
            theor = T / (pulsardata[ii].p + pulsardata[ii].pd * difft);
            theoz = -pulsardata[ii].pd * theor * theor;

            /* Check the predicted period and its harmonics against the */
            /* measured period.                                         */

            for (jj = 1; jj < 41; jj++) {

               /* If the psr from the database is in a             */
               /* binary orbit, loosen the match criteria.         */
               /* This accounts for Doppler variations in period.  */

               if (pulsardata[ii].orb.p != 0.0) {
                  r_criteria = 0.001 * theor * jj;      /* 0.1% fractional error   */
                  z_criteria = 9999999999.0;    /* Always match for binary */
                  strcpy(tmp1, "?");
                  if (full) {
                     strcpy(tmp3, "Possibly (large error) ");
                  }
               } else {
                  r_criteria = 5.0;     /* 5 bin error matching... */
                  z_criteria = 9999999999.0;    /* Always match for binary */
                  /* z_criteria = 2.5 * cand->zerr; */
                  strcpy(tmp1, "");
                  if (full) {
                     strcpy(tmp3, "Looks like ");
                  }
               }

               if (theor * jj > 1.5 * cand->r)
                  break;

               rdiff = fabs(theor * jj - cand->r);
               zdiff = fabs(theoz * jj - cand->z);

               if (rdiff < r_criteria && zdiff < z_criteria) {
                  if (strlen(pulsardata[ii].bname) == 0)
                     sprintf(psrname, "J%s", pulsardata[ii].jname);
                  else
                     sprintf(psrname, "B%s", pulsardata[ii].bname);
                  if (jj == 1) {
                     if (full) {
                        sprintf(tmp1, "the fundamental of ");
                        sprintf(tmp2, "PSR %s. (predicted p = %11.7f s).\n",
                                psrname, T / theor);
                        sprintf(output, "%s%s\n     %s", tmp3, tmp1, tmp2);
                     } else {
                        sprintf(shortout, "PSR %s%s", psrname, tmp1);
                        strncpy(output, shortout, 20);
                     }
                  } else {
                     if (full) {
                        sprintf(tmp1, "the %s harmonic of ", num[jj]);
                        sprintf(tmp2, "PSR %s. (predicted p = %11.7f s).\n",
                                psrname, T / theor);
                        sprintf(output, "%s%s\n     %s", tmp3, tmp1, tmp2);
                     } else {
                        sprintf(shortout, "%s H %s%s", num[jj], psrname, tmp1);
                        strncpy(output, shortout, 20);
                     }
                  }
                  return ii + 1;
               } else if (rdiff < sidedr) {
                  if (strlen(pulsardata[ii].bname) == 0)
                     sprintf(psrname, "J%s", pulsardata[ii].jname);
                  else
                     sprintf(psrname, "B%s", pulsardata[ii].bname);
                  if (full) {
                     sprintf(tmp1, "a sidelobe of the %s harmonic of ", num[jj]);
                     sprintf(tmp2, "PSR %s. (predicted p = %11.7f s).\n",
                             psrname, T / theor);
                     sprintf(output, "%s%s\n     %s", tmp3, tmp1, tmp2);
                  } else {
                     sprintf(shortout, "SL H%d %s", jj, psrname);
                     strncpy(output, shortout, 20);
                  }
                  return ii + 1;
               }
            }
         }
      }
   }

   /* Didn't find a match */

   if (full) {
      sprintf(output, "I don't recognize this candidate in the pulsar database.\n");
   } else {
      strncpy(output, "                       ", 20);
   }
   return 0;
}
Beispiel #10
0
int
main (int argc, char *argv[])
{
  WispObject *database;
  int do_long_listing = 0;
  int matches_found = 0;
  int arguments_found = 0;
  char *database_filename = (char *)NULL;

  if (strcmp (argv[0], "rolodex") == 0)
    {
      database_filename = getenv ("ROLODEX");
      if (database_filename == (char *)NULL)
	database_filename = rolodex_file;
    }
  else
    {
      struct passwd *entry;

      entry = getpwuid (getuid ());
      if (entry)
	{
	  database_filename = (char *) xmalloc
	    (strlen (user_file_template) + strlen (entry->pw_dir) + 4);

	  sprintf (database_filename, user_file_template, entry->pw_dir);
	}
    }

  if (!database_filename)
    {
      fprintf (stderr, "Who are you?\n");
      return (-1);
    }

  database = read_database (database_filename);

  while (--argc)
    {
      char *arg = *++argv;

      if (strcmp (arg, "-l") == 0)
	{
	  do_long_listing = 1;
	}
      else
	{
	  WispObject *matches;

	  arguments_found++;
	  matches = find_matches (database, "name:", arg);
	  if (matches != NIL)
	    {
	      matches_found += list_length (matches);
	      print_entries (stdout, matches, do_long_listing);
	    }

	  matches = find_matches (database, "email:", arg);
	  if (matches != NIL)
	    {
	      matches_found += list_length (matches);
	      print_entries (stdout, matches, do_long_listing);
	    }

	  matches = find_matches (database, "e-mail:", arg);
	  if (matches != NIL)
	    {
	      matches_found += list_length (matches);
	      print_entries (stdout, matches, do_long_listing);
	    }
	}
    }

  if (!arguments_found)
    {
      /* Just find birthdays for today's date. */
      WispObject *matches;
      char todays_date[20], yesterdays_date[20], tomorrows_date[20];
      time_t ticks;
      struct tm *now;

      ticks = (time_t)time ((time_t *)NULL);
      now = localtime (&ticks);

      sprintf (todays_date, "%02d/%02d", 1 + now->tm_mon, now->tm_mday);

      ticks -= 60 * 60 * 24;
      now = localtime (&ticks);
      sprintf (yesterdays_date, "%02d/%02d", 1 + now->tm_mon, now->tm_mday);

      ticks += 2 * (60 * 60 * 24);
      now = localtime (&ticks);
      sprintf (tomorrows_date, "%02d/%02d", 1 + now->tm_mon, now->tm_mday);

      matches = find_date_matches (database, "birthday:", todays_date);
      if (matches != NIL)
	{
	  matches_found += list_length (matches);
	  print_entries (stdout, matches, do_long_listing);
	}

      matches = find_date_matches (database, "birthday:", yesterdays_date);
      if (matches != NIL)
	{
	  matches_found += list_length (matches);
	  print_entries (stdout, matches, do_long_listing);
	}

     matches = find_date_matches (database, "birthday:", tomorrows_date);
     if (matches != NIL)
       {
	 matches_found += list_length (matches);
	 print_entries (stdout, matches, do_long_listing);
       }
    }

  return (matches_found != 0);
}
Beispiel #11
0
int main(int argc, char **argv) {
    char *model_list = NULL; // "all_models.list";
    char *database_file = NULL; // "train.db";
    // char *database_file = "train_10.db";
    // char *database_file = "train_1.db";
    HMM **hmm_set = NULL;
    int max_iter = 20;
    float tolerance = 0.00001;
    char *result_dir = NULL; // "train_result";
    char filename_buf[512];
    int feat_dim = 13;
    int i = 1;
    int init_feat_capacity = 64;

    while (i < argc) {
        if (!strcmp(argv[i], "--model-list")) {
            if (i + 1 >= argc) {
                print_usage("Missing argument.");
                return 2;
            }
            model_list = argv[i + 1];
            i += 2;
        } else if (!strcmp(argv[i], "--db")) {
            if (i + 1 >= argc) {
                print_usage("Missing argument.");
                return 2;
            }
            database_file = argv[i + 1];
            i += 2;
        } else if (!strcmp(argv[i], "--result-dir")) {
            if (i + 1 >= argc) {
                print_usage("Missing argument.");
                return 2;
            }
            result_dir = argv[i + 1];
            i += 2;
        } else if (!strcmp(argv[i], "--max-iter")) {
            if (i + 1 >= argc) {
                print_usage("Missing argument.");
                return 2;
            }
            max_iter = atoi(argv[i + 1]);
            i += 2;
        } else if (!strcmp(argv[i], "--feat-dim")) {
            if (i + 1 >= argc) {
                print_usage("Missing argument.");
                return 2;
            }
            feat_dim = atoi(argv[i + 1]);
            i += 2;
        } else if (!strcmp(argv[i], "--init-capacity")) {
            if (i + 1 >= argc) {
                print_usage("Missing argument.");
                return 2;
            }
            init_feat_capacity = atoi(argv[i + 1]);
            i += 2;
        } else {
            fprintf(stderr, "Invalid argument: %s\n", argv[i]);
            print_usage(NULL);
            return 3;
        }
    }

    if (database_file == NULL || max_iter < 1 || result_dir == NULL || feat_dim < 1 || model_list == NULL) {
        print_usage("Missing argument.");
        return 4;
    }

    FILE *fmodel_list = fopen(model_list, "r");
    int hmm_size = read_models(fmodel_list, &hmm_set);
    fclose(fmodel_list);

    Database *train_db = read_database(database_file);

    // void hmm_train_continuous(HMM **hmm_set, int hmm_size, Database *db, int feat_dim, int max_iter, float tolerance)

    hmm_train_continuous(hmm_set, hmm_size, train_db, feat_dim, max_iter, tolerance, init_feat_capacity);

    for (int h = 0; h < hmm_size; h++) {
        sprintf(filename_buf, "%s/%s.hmm", result_dir, hmm_set[h]->lex);
        fprintf(stderr, "Writing model for %s\n", filename_buf);
        hmm_write(hmm_set[h], filename_buf);
    }

    return 0;
}