Exemplo n.º 1
0
int main(int argc, char *argv[])
{
   /* Any variable that begins with 't' means topocentric */
   /* Any variable that begins with 'b' means barycentric */
   FILE **outfiles = NULL;
   float **outdata;
   double dtmp, *dms, avgdm = 0.0, dsdt = 0, maxdm;
   double *dispdt, tlotoa = 0.0, blotoa = 0.0, BW_ddelay = 0.0;
   double max = -9.9E30, min = 9.9E30, var = 0.0, avg = 0.0;
   double *btoa = NULL, *ttoa = NULL, avgvoverc = 0.0;
   char obs[3], ephem[10], rastring[50], decstring[50];
   long totnumtowrite, totwrote = 0, padwrote = 0, datawrote = 0;
   int *idispdt, **offsets;
   int ii, jj, numadded = 0, numremoved = 0, padding = 0, good_inputs = 1;
   int numbarypts = 0, numread = 0, numtowrite = 0;
   int padtowrite = 0, statnum = 0;
   int numdiffbins = 0, *diffbins = NULL, *diffbinptr = NULL, good_padvals = 0;
   double local_lodm;
   char *datafilenm, *outpath, *outfilenm, *hostname;
   struct spectra_info s;
   infodata idata;
   mask obsmask;

   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
   MPI_Comm_rank(MPI_COMM_WORLD, &myid);
#ifdef _OPENMP
   omp_set_num_threads(1); // Explicitly turn off OpenMP
#endif
   set_using_MPI();
   {
      FILE *hostfile;
      char tmpname[100];
      int retval;

      hostfile = chkfopen("/etc/hostname", "r");
      retval = fscanf(hostfile, "%s\n", tmpname);
      if (retval==0) {
          printf("Warning:  error reading /etc/hostname on proc %d\n", myid);
      }
      hostname = (char *) calloc(strlen(tmpname) + 1, 1);
      memcpy(hostname, tmpname, strlen(tmpname));
      fclose(hostfile);
   }

   /* Call usage() if we have no command line arguments */

   if (argc == 1) {
      if (myid == 0) {
         Program = argv[0];
         usage();
      }
      MPI_Finalize();
      exit(1);
   }

   make_maskbase_struct();
   make_spectra_info_struct();

   /* Parse the command line using the excellent program Clig */

   cmd = parseCmdline(argc, argv);
   spectra_info_set_defaults(&s);
   // If we are zeroDMing, make sure that clipping is off.
   if (cmd->zerodmP) cmd->noclipP = 1;
   s.clip_sigma = cmd->clip;
   if (cmd->noclipP) {
       cmd->clip = 0.0;
       s.clip_sigma = 0.0;
   }
   if (cmd->ifsP) {
       // 0 = default or summed, 1-4 are possible also
       s.use_poln = cmd->ifs + 1;
   }
   if (!cmd->numoutP)
      cmd->numout = LONG_MAX;

#ifdef DEBUG
   showOptionValues();
#endif

   if (myid == 0) {             /* Master node only */
      printf("\n\n");
      printf("      Parallel Pulsar Subband De-dispersion Routine\n");
      printf("                 by Scott M. Ransom\n\n");

      s.filenames = cmd->argv;
      s.num_files = cmd->argc;
      s.clip_sigma = cmd->clip;
      // -1 causes the data to determine if we use weights, scales, & 
      // offsets for PSRFITS or flip the band for any data type where
      // we can figure that out with the data
      s.apply_flipband = (cmd->invertP) ? 1 : -1;
      s.apply_weight = (cmd->noweightsP) ? 0 : -1;
      s.apply_scale  = (cmd->noscalesP) ? 0 : -1;
      s.apply_offset = (cmd->nooffsetsP) ? 0 : -1;
      s.remove_zerodm = (cmd->zerodmP) ? 1 : 0;

      if (RAWDATA) {
          if (cmd->filterbankP) s.datatype = SIGPROCFB;
          else if (cmd->psrfitsP) s.datatype = PSRFITS;
          else if (cmd->pkmbP) s.datatype = SCAMP;
          else if (cmd->bcpmP) s.datatype = BPP;
          else if (cmd->wappP) s.datatype = WAPP;
          else if (cmd->spigotP) s.datatype = SPIGOT;
      } else {  // Attempt to auto-identify the data
          identify_psrdatatype(&s, 1);
          if (s.datatype==SIGPROCFB) cmd->filterbankP = 1;
          else if (s.datatype==PSRFITS) cmd->psrfitsP = 1;
          else if (s.datatype==SCAMP) cmd->pkmbP = 1;
          else if (s.datatype==BPP) cmd->bcpmP = 1;
          else if (s.datatype==WAPP) cmd->wappP = 1;
          else if (s.datatype==SPIGOT) cmd->spigotP = 1;
          else if (s.datatype==SUBBAND) insubs = 1;
          else {
              printf("\nError:  Unable to identify input data files.  Please specify type.\n\n");
              good_inputs = 0;
          }
      }
      // So far we can only handle PSRFITS, filterbank, and subbands
      if (s.datatype!=PSRFITS && 
          s.datatype!=SIGPROCFB && 
          s.datatype!=SUBBAND) good_inputs = 0;

      // For subbanded data
      if (!RAWDATA) s.files = (FILE **)malloc(sizeof(FILE *) * s.num_files);

      if (good_inputs && (RAWDATA || insubs)) {
          char description[40];
          psrdatatype_description(description, s.datatype);
          if (s.num_files > 1)
              printf("Reading %s data from %d files:\n", description, s.num_files);
          else
              printf("Reading %s data from 1 file:\n", description);
          for (ii = 0; ii < s.num_files; ii++) {
              printf("  '%s'\n", cmd->argv[ii]);
              if (insubs) s.files[ii] = chkfopen(s.filenames[ii], "rb");
          }
          printf("\n");
          if (RAWDATA) {
              read_rawdata_files(&s);
              print_spectra_info_summary(&s);
              spectra_info_to_inf(&s, &idata);
          } else { // insubs
              char *root, *suffix;
              cmd->nsub = s.num_files;
              s.N = chkfilelen(s.files[0], sizeof(short));
              s.start_subint = gen_ivect(1);
              s.num_subint = gen_ivect(1);
              s.start_MJD = (long double *)malloc(sizeof(long double));
              s.start_spec = (long long *)malloc(sizeof(long long));
              s.num_spec = (long long *)malloc(sizeof(long long));
              s.num_pad = (long long *)malloc(sizeof(long long));
              s.start_spec[0] = 0L;
              s.start_subint[0] = 0;
              s.num_spec[0] = s.N;
              s.num_subint[0] = s.N / SUBSBLOCKLEN;
              s.num_pad[0] = 0L;
              s.padvals = gen_fvect(s.num_files);
              for (ii = 0 ; ii < ii ; ii++)
                  s.padvals[ii] = 0.0;
              if (split_root_suffix(s.filenames[0], &root, &suffix) == 0) {
                  printf("\nError:  The input filename (%s) must have a suffix!\n\n", s.filenames[0]);
                  exit(1);
              }
              if (strncmp(suffix, "sub", 3) == 0) {
                  char *tmpname;
                  tmpname = calloc(strlen(root) + 10, 1);
                  sprintf(tmpname, "%s.sub", root);
                  readinf(&idata, tmpname);
                  free(tmpname);
                  strncpy(s.telescope, idata.telescope, 40);
                  strncpy(s.backend, idata.instrument, 40);
                  strncpy(s.observer, idata.observer, 40);
                  strncpy(s.source, idata.object, 40);
                  s.ra2000 = hms2rad(idata.ra_h, idata.ra_m,
                                     idata.ra_s) * RADTODEG;
                  s.dec2000 = dms2rad(idata.dec_d, idata.dec_m,
                                      idata.dec_s) * RADTODEG;
                  ra_dec_to_string(s.ra_str,
                                   idata.ra_h, idata.ra_m, idata.ra_s);
                  ra_dec_to_string(s.dec_str,
                                   idata.dec_d, idata.dec_m, idata.dec_s);
                  s.num_channels = idata.num_chan;
                  s.start_MJD[0] = idata.mjd_i + idata.mjd_f;
                  s.dt = idata.dt;
                  s.T = s.N * s.dt;
                  s.lo_freq = idata.freq;
                  s.df = idata.chan_wid;
                  s.hi_freq = s.lo_freq + (s.num_channels - 1.0) * s.df;
                  s.BW = s.num_channels * s.df;
                  s.fctr = s.lo_freq - 0.5 * s.df + 0.5 * s.BW;
                  s.beam_FWHM = idata.fov / 3600.0;
                  s.spectra_per_subint = SUBSBLOCKLEN;
                  print_spectra_info_summary(&s);
              } else {
                  printf("\nThe input files (%s) must be subbands!  (i.e. *.sub##)\n\n",
                         cmd->argv[0]);
                  MPI_Finalize();
                  exit(1);
              }
              free(root);
              free(suffix);
          }
      }
   }

   //  If we don't have good input data, exit
   MPI_Bcast(&good_inputs, 1, MPI_INT, 0, MPI_COMM_WORLD);
   if (!good_inputs) {
       MPI_Finalize();
       exit(1);
   }
   
   MPI_Bcast(&insubs, 1, MPI_INT, 0, MPI_COMM_WORLD);
   if (insubs)
       cmd->nsub = cmd->argc;

   /* Determine the output file names and open them */

   local_numdms = cmd->numdms / (numprocs - 1);
   dms = gen_dvect(local_numdms);
   if (cmd->numdms % (numprocs - 1)) {
       if (myid == 0)
           printf
               ("\nThe number of DMs must be divisible by (the number of processors - 1).\n\n");
       MPI_Finalize();
       exit(1);
   }
   local_lodm = cmd->lodm + (myid - 1) * local_numdms * cmd->dmstep;
   
   split_path_file(cmd->outfile, &outpath, &outfilenm);
   datafilenm = (char *) calloc(strlen(outfilenm) + 20, 1);
   if (myid > 0) {
       if (chdir(outpath) == -1) {
           printf("\nProcess %d on %s cannot chdir() to '%s'.  Exiting.\n\n", 
                  myid, hostname, outpath);
           MPI_Finalize();
           exit(1);
       }
       outfiles = (FILE **) malloc(local_numdms * sizeof(FILE *));
       for (ii = 0; ii < local_numdms; ii++) {
           dms[ii] = local_lodm + ii * cmd->dmstep;
           avgdm += dms[ii];
           sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]);
           outfiles[ii] = chkfopen(datafilenm, "wb");
       }
       avgdm /= local_numdms;
   }
   
   // Broadcast the raw data information

   broadcast_spectra_info(&s, myid);
   if (myid > 0) {
       spectra_info_to_inf(&s, &idata);
       if (s.datatype==SIGPROCFB) cmd->filterbankP = 1;
       else if (s.datatype==PSRFITS) cmd->psrfitsP = 1;
       else if (s.datatype==SCAMP) cmd->pkmbP = 1;
       else if (s.datatype==BPP) cmd->bcpmP = 1;
       else if (s.datatype==WAPP) cmd->wappP = 1;
       else if (s.datatype==SPIGOT) cmd->spigotP = 1;
       else if (s.datatype==SUBBAND) insubs = 1;
   }
   s.filenames = cmd->argv;

   /* Read an input mask if wanted */
   
   if (myid > 0) {
       int numpad = s.num_channels;
       if (insubs)
           numpad = s.num_files;
       s.padvals = gen_fvect(numpad);
       for (ii = 0 ; ii < numpad ; ii++)
           s.padvals[ii] = 0.0;
   }
   if (cmd->maskfileP) {
       if (myid == 0) {
           read_mask(cmd->maskfile, &obsmask);
           printf("Read mask information from '%s'\n\n", cmd->maskfile);
           good_padvals = determine_padvals(cmd->maskfile, &obsmask, s.padvals);
       }
       broadcast_mask(&obsmask, myid);
       MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD);
       MPI_Bcast(s.padvals, obsmask.numchan, MPI_FLOAT, 0, MPI_COMM_WORLD);
   } else {
       obsmask.numchan = obsmask.numint = 0;
       MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD);
   }

   // The number of topo to bary time points to generate with TEMPO
   numbarypts = (int) (s.T * 1.1 / TDT + 5.5) + 1;

   // Identify the TEMPO observatory code
   {
       char *outscope = (char *) calloc(40, sizeof(char));
       telescope_to_tempocode(idata.telescope, outscope, obs);
       free(outscope);
   }

   // Broadcast or calculate a few extra important values
   if (insubs) avgdm = idata.dm;
   idata.dm = avgdm;
   dsdt = cmd->downsamp * idata.dt;
   maxdm = cmd->lodm + cmd->numdms * cmd->dmstep;
   BW_ddelay = delay_from_dm(maxdm, idata.freq) - 
       delay_from_dm(maxdm, idata.freq + (idata.num_chan-1) * idata.chan_wid);
   blocksperread = ((int) (BW_ddelay / idata.dt) / s.spectra_per_subint + 1);
   worklen = s.spectra_per_subint * blocksperread;
   
   if (cmd->nsub > s.num_channels) {
      printf
          ("Warning:  The number of requested subbands (%d) is larger than the number of channels (%d).\n",
           cmd->nsub, s.num_channels);
      printf("          Re-setting the number of subbands to %d.\n\n", s.num_channels);
      cmd->nsub = s.num_channels;
   }

   if (s.spectra_per_subint % cmd->downsamp) {
       if (myid == 0) {
           printf
               ("\nError:  The downsample factor (%d) must be a factor of the\n",
                cmd->downsamp);
           printf("        blocklength (%d).  Exiting.\n\n", s.spectra_per_subint);
       }
       MPI_Finalize();
       exit(1);
   }

   tlotoa = idata.mjd_i + idata.mjd_f;  /* Topocentric epoch */

   if (cmd->numoutP)
      totnumtowrite = cmd->numout;
   else
      totnumtowrite = (long) idata.N / cmd->downsamp;

   if (cmd->nobaryP) {          /* Main loop if we are not barycentering... */

      /* Dispersion delays (in bins).  The high freq gets no delay   */
      /* All other delays are positive fractions of bin length (dt)  */

      dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm,
                                     idata.freq, idata.chan_wid, 0.0);
      idispdt = gen_ivect(s.num_channels);
      for (ii = 0; ii < s.num_channels; ii++)
          idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt);
      vect_free(dispdt);

      /* The subband dispersion delays (see note above) */

      offsets = gen_imatrix(local_numdms, cmd->nsub);
      for (ii = 0; ii < local_numdms; ii++) {
         double *subdispdt;

         subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii],
                                    idata.freq, idata.chan_wid, 0.0);
         dtmp = subdispdt[cmd->nsub - 1];
         for (jj = 0; jj < cmd->nsub; jj++)
            offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt);
         vect_free(subdispdt);
      }

      /* Allocate our data array and start getting data */

      if (myid == 0) {
         printf("De-dispersing using %d subbands.\n", cmd->nsub);
         if (cmd->downsamp > 1)
            printf("Downsampling by a factor of %d (new dt = %.10g)\n",
                   cmd->downsamp, dsdt);
         printf("\n");
      }
      
      /* Print the nodes and the DMs they are handling */
      print_dms(hostname, myid, numprocs, local_numdms, dms);

      outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp);
      numread = get_data(outdata, blocksperread, &s,
                         &obsmask, idispdt, offsets, &padding);

      while (numread == worklen) {

         numread /= cmd->downsamp;
         if (myid == 0)
            print_percent_complete(totwrote, totnumtowrite);

         /* Write the latest chunk of data, but don't   */
         /* write more than cmd->numout points.         */

         numtowrite = numread;
         if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout)
            numtowrite = cmd->numout - totwrote;
         if (myid > 0) {
            write_data(outfiles, local_numdms, outdata, 0, numtowrite);
            /* Update the statistics */
            if (!padding) {
               for (ii = 0; ii < numtowrite; ii++)
                  update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var);
               statnum += numtowrite;
            }
         }
         totwrote += numtowrite;

         /* Stop if we have written out all the data we need to */

         if (cmd->numoutP && (totwrote == cmd->numout))
            break;

         numread = get_data(outdata, blocksperread, &s,
                            &obsmask, idispdt, offsets, &padding);
      }
      datawrote = totwrote;

   } else {                     /* Main loop if we are barycentering... */

      /* What ephemeris will we use?  (Default is DE405) */
      strcpy(ephem, "DE405");

      /* Define the RA and DEC of the observation */

      ra_dec_to_string(rastring, idata.ra_h, idata.ra_m, idata.ra_s);
      ra_dec_to_string(decstring, idata.dec_d, idata.dec_m, idata.dec_s);

      /* Allocate some arrays */

      btoa = gen_dvect(numbarypts);
      ttoa = gen_dvect(numbarypts);
      for (ii = 0; ii < numbarypts; ii++)
         ttoa[ii] = tlotoa + TDT * ii / SECPERDAY;

      /* Call TEMPO for the barycentering */

      if (myid == 0) {
         double maxvoverc = -1.0, minvoverc = 1.0, *voverc = NULL;

         printf("\nGenerating barycentric corrections...\n");
         voverc = gen_dvect(numbarypts);
         barycenter(ttoa, btoa, voverc, numbarypts, rastring, decstring, obs, ephem);
         for (ii = 0; ii < numbarypts; ii++) {
            if (voverc[ii] > maxvoverc)
               maxvoverc = voverc[ii];
            if (voverc[ii] < minvoverc)
               minvoverc = voverc[ii];
            avgvoverc += voverc[ii];
         }
         avgvoverc /= numbarypts;
         vect_free(voverc);

         printf("   Average topocentric velocity (c) = %.7g\n", avgvoverc);
         printf("   Maximum topocentric velocity (c) = %.7g\n", maxvoverc);
         printf("   Minimum topocentric velocity (c) = %.7g\n\n", minvoverc);
         printf("De-dispersing using %d subbands.\n", cmd->nsub);
         if (cmd->downsamp > 1) {
             printf("     Downsample = %d\n", cmd->downsamp);
             printf("  New sample dt = %.10g\n", dsdt);
         }
         printf("\n");
      }

      /* Print the nodes and the DMs they are handling */
      print_dms(hostname, myid, numprocs, local_numdms, dms);

      MPI_Bcast(btoa, numbarypts, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      MPI_Bcast(&avgvoverc, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      blotoa = btoa[0];

      /* Dispersion delays (in bins).  The high freq gets no delay   */
      /* All other delays are positive fractions of bin length (dt)  */

      dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm,
                                     idata.freq, idata.chan_wid, avgvoverc);
      idispdt = gen_ivect(s.num_channels);
      for (ii = 0; ii < s.num_channels; ii++)
          idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt);
      vect_free(dispdt);

      /* The subband dispersion delays (see note above) */

      offsets = gen_imatrix(local_numdms, cmd->nsub);
      for (ii = 0; ii < local_numdms; ii++) {
         double *subdispdt;

         subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii],
                                    idata.freq, idata.chan_wid, avgvoverc);
         dtmp = subdispdt[cmd->nsub - 1];
         for (jj = 0; jj < cmd->nsub; jj++)
            offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt);
         vect_free(subdispdt);
      }

      /* Convert the bary TOAs to differences from the topo TOAs in */
      /* units of bin length (dt) rounded to the nearest integer.   */

      dtmp = (btoa[0] - ttoa[0]);
      for (ii = 0; ii < numbarypts; ii++)
         btoa[ii] = ((btoa[ii] - ttoa[ii]) - dtmp) * SECPERDAY / dsdt;

      /* Find the points where we need to add or remove bins */
      {
         int oldbin = 0, currentbin;
         double lobin, hibin, calcpt;

         numdiffbins = abs(NEAREST_LONG(btoa[numbarypts - 1])) + 1;
         diffbins = gen_ivect(numdiffbins);
         diffbinptr = diffbins;
         for (ii = 1; ii < numbarypts; ii++) {
            currentbin = NEAREST_LONG(btoa[ii]);
            if (currentbin != oldbin) {
               if (currentbin > 0) {
                  calcpt = oldbin + 0.5;
                  lobin = (ii - 1) * TDT / dsdt;
                  hibin = ii * TDT / dsdt;
               } else {
                  calcpt = oldbin - 0.5;
                  lobin = -((ii - 1) * TDT / dsdt);
                  hibin = -(ii * TDT / dsdt);
               }
               while (fabs(calcpt) < fabs(btoa[ii])) {
                  /* Negative bin number means remove that bin */
                  /* Positive bin number means add a bin there */
                  *diffbinptr =
                      NEAREST_LONG(LININTERP
                                  (calcpt, btoa[ii - 1], btoa[ii], lobin, hibin));
                  diffbinptr++;
                  calcpt = (currentbin > 0) ? calcpt + 1.0 : calcpt - 1.0;
               }
               oldbin = currentbin;
            }
         }
         *diffbinptr = cmd->numout; /* Used as a marker */
      }
      diffbinptr = diffbins;

      /* Now perform the barycentering */

      outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp);
      numread = get_data(outdata, blocksperread, &s, 
                         &obsmask, idispdt, offsets, &padding);

      while (numread == worklen) {      /* Loop to read and write the data */
         int numwritten = 0;
         double block_avg, block_var;

         numread /= cmd->downsamp;
         /* Determine the approximate local average */
         avg_var(outdata[0], numread, &block_avg, &block_var);
         if (myid == 0)
            print_percent_complete(totwrote, totnumtowrite);

         /* Simply write the data if we don't have to add or */
         /* remove any bins from this batch.                 */
         /* OR write the amount of data up to cmd->numout or */
         /* the next bin that will be added or removed.      */

         numtowrite = abs(*diffbinptr) - datawrote;
         if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout)
            numtowrite = cmd->numout - totwrote;
         if (numtowrite > numread)
            numtowrite = numread;
         if (myid > 0) {
            write_data(outfiles, local_numdms, outdata, 0, numtowrite);
            /* Update the statistics */
            if (!padding) {
               for (ii = 0; ii < numtowrite; ii++)
                  update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var);
               statnum += numtowrite;
            }
         }
         datawrote += numtowrite;
         totwrote += numtowrite;
         numwritten += numtowrite;

         if ((datawrote == abs(*diffbinptr)) && 
             (numwritten != numread) && 
             (totwrote < cmd->numout)) {  /* Add/remove a bin */
            int skip, nextdiffbin;

            skip = numtowrite;

            /* Write the rest of the data after adding/removing a bin  */
            do {

               if (*diffbinptr > 0) {
                  /* Add a bin */
                  if (myid > 0)
                     write_padding(outfiles, local_numdms, block_avg, 1);
                  numadded++;
                  totwrote++;
               } else {
                  /* Remove a bin */
                  numremoved++;
                  datawrote++;
                  numwritten++;
                  skip++;
               }
               diffbinptr++;

               /* Write the part after the diffbin */

               numtowrite = numread - numwritten;
               if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout)
                  numtowrite = cmd->numout - totwrote;
               nextdiffbin = abs(*diffbinptr) - datawrote;
               if (numtowrite > nextdiffbin)
                  numtowrite = nextdiffbin;
               if (myid > 0) {
                  write_data(outfiles, local_numdms, outdata, skip, numtowrite);
                  /* Update the statistics and counters */
                  if (!padding) {
                     for (ii = 0; ii < numtowrite; ii++)
                        update_stats(statnum + ii,
                                     outdata[0][skip + ii], &min, &max, &avg, &var);
                     statnum += numtowrite;
                  }
               }
               numwritten += numtowrite;
               datawrote += numtowrite;
               totwrote += numtowrite;
               skip += numtowrite;

               /* Stop if we have written out all the data we need to */

               if (cmd->numoutP && (totwrote == cmd->numout))
                  break;
            } while (numwritten < numread);
         }
         /* Stop if we have written out all the data we need to */

         if (cmd->numoutP && (totwrote == cmd->numout))
            break;

         numread = get_data(outdata, blocksperread, &s,
                            &obsmask, idispdt, offsets, &padding);
      }
   }

   if (myid > 0) {

      /* Calculate the amount of padding we need  */

      if (cmd->numoutP && (cmd->numout > totwrote))
         padwrote = padtowrite = cmd->numout - totwrote;

      /* Write the new info file for the output data */

      idata.dt = dsdt;
      update_infodata(&idata, totwrote, padtowrite, diffbins,
                      numdiffbins, cmd->downsamp);
      for (ii = 0; ii < local_numdms; ii++) {
         idata.dm = dms[ii];
         if (!cmd->nobaryP) {
            double baryepoch, barydispdt, baryhifreq;

            baryhifreq = idata.freq + (s.num_channels - 1) * idata.chan_wid;
            barydispdt = delay_from_dm(dms[ii], doppler(baryhifreq, avgvoverc));
            baryepoch = blotoa - (barydispdt / SECPERDAY);
            idata.bary = 1;
            idata.mjd_i = (int) floor(baryepoch);
            idata.mjd_f = baryepoch - idata.mjd_i;
         }
         sprintf(idata.name, "%s_DM%.2f", outfilenm, dms[ii]);
         writeinf(&idata);
      }

      /* Set the padded points equal to the average data point */

      if (idata.numonoff >= 1) {
         int index, startpad, endpad;

         for (ii = 0; ii < local_numdms; ii++) {
            fclose(outfiles[ii]);
            sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]);
            outfiles[ii] = chkfopen(datafilenm, "rb+");
         }
         for (ii = 0; ii < idata.numonoff; ii++) {
            index = 2 * ii;
            startpad = idata.onoff[index + 1];
            if (ii == idata.numonoff - 1)
               endpad = idata.N - 1;
            else
               endpad = idata.onoff[index + 2];
            for (jj = 0; jj < local_numdms; jj++)
               chkfseek(outfiles[jj], (startpad + 1) * sizeof(float), SEEK_SET);
            padtowrite = endpad - startpad;
            write_padding(outfiles, local_numdms, avg, padtowrite);
         }
      }
   }

   /* Print simple stats and results */

   var /= (datawrote - 1);
   if (myid == 0)
      print_percent_complete(1, 1);
   if (myid == 1) {
      printf("\n\nDone.\n\nSimple statistics of the output data:\n");
      printf("             Data points written:  %ld\n", totwrote);
      if (padwrote)
         printf("          Padding points written:  %ld\n", padwrote);
      if (!cmd->nobaryP) {
         if (numadded)
            printf("    Bins added for barycentering:  %d\n", numadded);
         if (numremoved)
            printf("  Bins removed for barycentering:  %d\n", numremoved);
      }
      printf("           Maximum value of data:  %.2f\n", max);
      printf("           Minimum value of data:  %.2f\n", min);
      printf("              Data average value:  %.2f\n", avg);
      printf("         Data standard deviation:  %.2f\n", sqrt(var));
      printf("\n");
   }

   /* Close the files and cleanup */

   if (cmd->maskfileP)
      free_mask(obsmask);
   if (myid > 0) {
      for (ii = 0; ii < local_numdms; ii++)
         fclose(outfiles[ii]);
      free(outfiles);
   }
   vect_free(outdata[0]);
   vect_free(outdata);
   vect_free(dms);
   free(hostname);
   vect_free(idispdt);
   vect_free(offsets[0]);
   vect_free(offsets);
   free(datafilenm);
   free(outfilenm);
   free(outpath);
   if (!cmd->nobaryP) {
      vect_free(btoa);
      vect_free(ttoa);
      vect_free(diffbins);
   }
   MPI_Finalize();
   return (0);
}
Exemplo n.º 2
0
char *make_polycos(char *parfilenm, infodata * idata, char *polycofilenm)
{
    FILE *tmpfile;
    int tracklen;
    double T, fmid = 0.0, epoch;
    char *command, *psrname, scopechar;
    char *pcpathnm, *pcfilenm;
    psrparams psr;

    /* Get the path and name of the output polycofilenm */
    split_path_file(polycofilenm, &pcpathnm, &pcfilenm);

    /* Read the parfile */
    epoch = idata->mjd_i + idata->mjd_f;
    T = (idata->dt * idata->N) / SECPERDAY;
    if (!get_psr_from_parfile(parfilenm, epoch, &psr)) {
        fprintf(stderr,
                "\nError:  Cannot read parfile '%s' in make_polycos()\n\n",
                parfilenm);
        exit(-1);
    }

    /* Generate temp directory */
    char tmpdir[] = "/tmp/polycoXXXXXX";
    if (mkdtemp(tmpdir) == NULL) {
        fprintf(stderr,
                "\nError:  Cannot generate temp dir '%s' in make_polycos()\n\n",
                tmpdir);
        exit(-1);
    }

    /* Copy the parfile to the temp directory */
    command = (char *) calloc(strlen(parfilenm) + strlen(tmpdir) +
                              strlen(pcfilenm) + strlen(pcpathnm) + 200, 1);
    sprintf(command, "cp %s %s/pulsar.par", parfilenm, tmpdir);
    if (system(command) != 0) {
        fprintf(stderr,
                "\nError:  Cannot copy parfile '%s' to tmpdir '%s' in make_polycos()\n\n",
                parfilenm, tmpdir);
        exit(-1);
    }

    /* change to temp dir */
    char *origdir = getcwd(NULL, 0);
    chdir(tmpdir);

    /* Write tz.in */
    if (strcmp(idata->telescope, "GBT") == 0) {
        scopechar = '1';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "Arecibo") == 0) {
        scopechar = '3';
        tracklen = 3;
    } else if (strcmp(idata->telescope, "VLA") == 0) {
        scopechar = '6';
        tracklen = 6;
    } else if (strcmp(idata->telescope, "Parkes") == 0) {
        scopechar = '7';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "Jodrell") == 0) {
        scopechar = '8';
        tracklen = 12;
    } else if ((strcmp(idata->telescope, "GB43m") == 0) ||
               (strcmp(idata->telescope, "GB 140FT") == 0) ||
               (strcmp(idata->telescope, "NRAO20") == 0)) {
        scopechar = 'a';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "Nancay") == 0) {
        scopechar = 'f';
        tracklen = 4;
    } else if (strcmp(idata->telescope, "Effelsberg") == 0) {
        scopechar = 'g';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "LOFAR") == 0) {
        scopechar = 't';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "WSRT") == 0) {
        scopechar = 'i';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "GMRT") == 0) {
        scopechar = 'r';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "LWA") == 0) {
        scopechar = 'x';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "SRT") == 0) {
        scopechar = 'z';
        tracklen = 12;
    } else if (strcmp(idata->telescope, "Geocenter") == 0) {
        scopechar = 'o';
        tracklen = 12;
    } else {                    /*  Barycenter */
        printf("Defaulting to barycenter for polyco generation...\n");
        scopechar = '@';
        tracklen = 12;
    }
    /* For optical, X-ray, or gamma-ray data */
    if (scopechar != '@' && scopechar != 'o') {
        fmid = idata->freq + (idata->num_chan / 2 - 0.5) * idata->chan_wid;
    } else {
        fmid = 0.0;
    }
    printf("Generating polycos for PSR %s.\n", psr.jname);
    tmpfile = chkfopen("tz.in", "w");
    fprintf(tmpfile, "%c %d 60 12 430\n\n\n%s 60 12 %d %.5f\n",
            scopechar, tracklen, psr.jname, tracklen, fmid);
    fclose(tmpfile);
    //sprintf(command, "echo %d %d | tempo -z -f %s > /dev/null",
    sprintf(command, "echo %d %d | tempo -z -f pulsar.par > /dev/null",
            idata->mjd_i - 1, (int) ceil(epoch + T));
    if (system(command) != 0) {
        fprintf(stderr,
                "\nError:  Problem running TEMPO in '%s' for make_polycos()\n\n",
                tmpdir);
        exit(-1);
    } else {
        sprintf(command, "cp polyco.dat %s/%s", pcpathnm, pcfilenm);
        if (system(command) != 0) {
            fprintf(stderr,
                    "\nError:  Cannot copy polyco.dat in '%s' to '%s' make_polycos()\n\n",
                    tmpdir, polycofilenm);
            exit(-1);
        }
        remove("polyco.dat");
        remove("pulsar.par");
        remove("tempo.lis");
        remove("tz.in");
        remove("tz.tmp");
    }
    chdir(origdir);
    free(origdir);
    free(pcpathnm);
    free(pcfilenm);
    free(command);
    remove(tmpdir);
    psrname = (char *) calloc(strlen(psr.jname) + 1, sizeof(char));
    strcpy(psrname, psr.jname);
    return psrname;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
   FILE **infiles, *outfile = NULL, *scalingfile;
   int filenum, argnum = 1, ii = 0, ptsperblock, numlags, numfiles;
   int bytes_per_read, scaling = 0, numscalings, output = 1;
   long long N;
   char *path, *filenm;
   char outfilenm[200], filenmbase[200], scalingnm[200], rawlags[4096];
   unsigned char output_samples[2048];
   float *scalings = NULL;
   double dt, T;
   SPIGOT_INFO *spigots;
   sigprocfb fb;
   infodata idata;

   if (argc == 1) {
      fprintf(stderr, "Usage: spigotSband2filterbank [-stdout] SPIGOT_files\n");
      exit(0);
   }

   if (!strcmp(argv[argnum], "-stdout")) {      /* Use STDOUT */
      argnum++;
      output = 0;
      outfile = stdout;
   } else {
      printf
          ("\nConverting raw SPIGOT S-band FITs data into SIGPROC\n"
           "filterbank format and throwing out the bottom 200MHz...\n\n");
   }

   /* Attempt to read a file with lag scalings in it */
   sprintf(scalingnm, "%s.scaling", filenmbase);
   if ((scalingfile = fopen(scalingnm, "rb"))) {
      /* Determine the length of the file */
      numscalings = (int) chkfilelen(scalingfile, sizeof(float));
      /* Create the array and read 'em */
      scalings = gen_fvect(numscalings);
      chkfread(scalings, sizeof(float), numscalings, scalingfile);
      scaling = 1;
      /* close the scaling file */
      fclose(scalingfile);
      if (outfile != stdout)
         printf("Scaling the lags with the %d values found in '%s'\n\n",
                numscalings, scalingnm);
   }

   /* Read and convert the basic SPIGOT file information */

   numfiles = argc - 1;
   if (outfile == stdout)
      numfiles--;
   else
      printf("Spigot card input file information:\n");
   spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles);
   infiles = (FILE **) malloc(sizeof(FILE *) * numfiles);
   for (filenum = 0; filenum < numfiles; filenum++, argnum++) {
      if (outfile != stdout)
         printf("  '%s'\n", argv[argnum]);
      infiles[filenum] = chkfopen(argv[argnum], "rb");
      read_SPIGOT_header(argv[argnum], spigots + filenum);
      rewind(infiles[filenum]);
   }
   if (outfile != stdout)
      printf("\n");

   /* The following is necessary in order to initialize all the */
   /* static variables in spigot.c                              */
   get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N,
                        &ptsperblock, &numlags, &dt, &T, &idata, output);

   /* Step through the SPIGOT files */
   ii = 0;
   if (outfile == stdout)
      argnum = 2;
   else
      argnum = 1;
   for (filenum = 0; filenum < numfiles; filenum++, argnum++) {
      split_path_file(argv[argnum], &path, &filenm);
      strncpy(filenmbase, filenm, strlen(filenm) - 5);
      filenmbase[strlen(filenm) - 5] = '\0';
      sprintf(outfilenm, "%s.fil", filenmbase);
      if (outfile != stdout){
         printf("Reading S-band Spigot lags from '%s'\n", argv[argnum]);
         printf("Writing filterbank spectra to   '%s'\n\n", outfilenm);
         outfile = chkfopen(outfilenm, "wb");
      }
      // Update the filterbank header information for each file
      spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase);
      write_filterbank_header(&fb, outfile);
      chkfseek(infiles[filenum], spigots[filenum].header_len, SEEK_SET);
      bytes_per_read = numlags * spigots[filenum].bits_per_lag / 8;

      /* Loop over the samples in the file */
      while (chkfread(rawlags, bytes_per_read, 1, infiles[filenum])) {
         if (scaling)
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, scalings[ii]);
         else
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0);
         ii++;
         /* Invert the band so that the high freqs are first */
         /* This is how SIGPROC stores its data.             */
         {
            int jj;
            unsigned char tempzz = 0.0, *loptr, *hiptr;
            loptr = output_samples + 0;
            hiptr = output_samples + numlags - 1;
            for (jj = 0; jj < numlags / 2; jj++, loptr++, hiptr--) {
               SWAP(*loptr, *hiptr);
            }
         }
         chkfwrite(output_samples, sizeof(unsigned char), fb.nchans, outfile);
      }
      fclose(infiles[filenum]);
      if (outfile != stdout)
         fclose(outfile);
   }
   if (outfile != stdout)
      fprintf(stderr, "Converted and wrote %d samples.\n\n", ii);
   if (scaling)
      vect_free(scalings);
   free(spigots);
   free(path);
   free(filenm);
   free(infiles);
   return 0;
}
Exemplo n.º 4
0
void init_subbanding(struct psrfits *pfi, struct psrfits *pfo,
                     struct subband_info *si, Cmdline *cmd)
{
    int ii, jj, kk, cindex;
    double lofreq, dtmp;

    // If -nsub is not set, do no subbanding
    if (!cmd->nsubP) cmd->nsub = pfi->hdr.nchan;
    // Don't change the number of output bits unless we explicitly ask to
    if (!cmd->outbitsP) cmd->outbits = pfi->hdr.nbits;

    si->nsub = cmd->nsub;
    si->nchan = pfi->hdr.nchan;
    si->npol = pfi->hdr.npol;
    si->numunsigned = si->npol;
    if (si->npol==4) {
        if (strncmp(pfi->hdr.poln_order, "AABBCRCI", 8)==0)
            si->numunsigned = 2;
        if (strncmp(pfi->hdr.poln_order, "IQUV", 4)==0)
            si->numunsigned = 1;
    }
    si->chan_per_sub = si->nchan / si->nsub;
    si->bufwid = si->nchan * si->npol; // Freq * polns
    si->buflen = pfi->hdr.nsblk;  // Number of spectra in each row
    // Check the downsampling factor in time
    if (si->buflen % cmd->dstime) {
        fprintf(stderr,
                "Error!:  %d spectra per row is not evenly divisible by -dstime of %d!\n",
                si->buflen, cmd->dstime);
        exit(1);
    }
    // Check the downsampling factor in frequency
    if (si->nchan % si->nsub) {
        fprintf(stderr,
                "Error!  %d channels is not evenly divisible by %d subbands!\n",
                si->nchan, si->nsub);
        exit(1);
    }
    si->dm = cmd->dm;
    si->sub_df = pfi->hdr.df * si->chan_per_sub;
    si->sub_freqs = (float *)malloc(sizeof(float) * si->nsub);
    si->chan_delays = (double *)malloc(sizeof(double) * si->nchan);
    si->sub_delays = (double *)malloc(sizeof(double) * si->nsub);
    si->idelays = (int *)malloc(sizeof(int) * si->nchan);
    si->weights = (float *)malloc(sizeof(float) * si->nsub);
    si->offsets = (float *)malloc(sizeof(float) * si->nsub * si->npol);
    si->scales = (float *)malloc(sizeof(float) * si->nsub * si->npol);
    si->chan_avgs = (float *)malloc(sizeof(float) * si->bufwid);
    si->chan_stds = (float *)malloc(sizeof(float) * si->bufwid);

    /* Alloc data buffers for the input PSRFITS file */
    pfi->sub.dat_freqs = (float *)malloc(sizeof(float) * pfi->hdr.nchan);
    pfi->sub.dat_weights = (float *)malloc(sizeof(float) * pfi->hdr.nchan);
    pfi->sub.dat_offsets = (float *)malloc(sizeof(float)
                                           * pfi->hdr.nchan * pfi->hdr.npol);
    pfi->sub.dat_scales  = (float *)malloc(sizeof(float)
                                           * pfi->hdr.nchan * pfi->hdr.npol);
    pfi->sub.rawdata = (unsigned char *)malloc(pfi->sub.bytes_per_subint);
    if (pfi->hdr.nbits!=8) {
        pfi->sub.data = (unsigned char *)malloc(pfi->sub.bytes_per_subint *
                                                (8 / pfi->hdr.nbits));
    } else {
        pfi->sub.data = pfi->sub.rawdata;
    }

    // Read the first row of data
    psrfits_read_subint(pfi);
    if (si->userwgts) // Always overwrite if using user weights
        memcpy(pfi->sub.dat_weights, si->userwgts, pfi->hdr.nchan * sizeof(float));

    // Reset the read counters since we'll re-read
    pfi->rownum--;
    pfi->tot_rows--;
    pfi->N -= pfi->hdr.nsblk;

    // Compute the subband properties, DM delays and offsets
    lofreq = pfi->sub.dat_freqs[0] - pfi->hdr.df * 0.5;
    for (ii = 0, cindex = 0 ; ii < si->nsub ; ii++) {
        dtmp = lofreq + ((double)ii + 0.5) * si->sub_df;
        si->sub_freqs[ii] = dtmp;
        si->sub_delays[ii] = delay_from_dm(si->dm, dtmp);
        // Determine the dispersion delays and convert them
        // to offsets in units of sample times
        for (jj = 0 ; jj < si->chan_per_sub ; jj++, cindex++) {
            si->chan_delays[cindex] = delay_from_dm(si->dm,
                                                    pfi->sub.dat_freqs[cindex]);
            si->chan_delays[cindex] -= si->sub_delays[ii];
            si->idelays[cindex] = (int)rint(si->chan_delays[cindex] / pfi->hdr.dt);
        }
    }

    // Now determine the earliest and latest delays
    si->max_early = si->max_late = 0;
    for (ii = 0 ; ii < si->nchan ; ii++) {
        if (si->idelays[ii] < si->max_early)
            si->max_early = si->idelays[ii];
        if (si->idelays[ii] > si->max_late)
            si->max_late = si->idelays[ii];
    }
    si->max_overlap = abs(si->max_early) + si->max_late;

    // This buffer will hold the float-converted input data, plus the bits
    // of data from the previous and next blocks
    si->fbuffer = (float *)calloc((si->buflen + 2 * si->max_overlap) *
                                  si->bufwid, sizeof(float));
    // The input data will be stored directly in the buffer space
    // So the following is really just an offset into the bigger buffer
    pfi->sub.fdata = si->fbuffer + si->max_overlap * si->bufwid;

    // Now start setting values for the output arrays
    *pfo = *pfi;

    // We are changing the number of bits in the data
    if (pfi->hdr.nbits != cmd->outbits)
        pfo->hdr.nbits = cmd->outbits;

    // Determine the length of the outputfiles to use
    if (cmd->filetimeP) {
        pfo->rows_per_file = 10 * \
            (int) rint(0.1 * (cmd->filetime / pfi->sub.tsubint));
    } else if (cmd->filelenP) {
        long long filelen;
        int bytes_per_subint;
        filelen = cmd->filelen * (1L<<30);  // In GB
        bytes_per_subint = (pfo->hdr.nbits * pfo->hdr.nchan *
                            pfo->hdr.npol * pfo->hdr.nsblk) / \
            (8 * si->chan_per_sub * cmd->dstime * (cmd->onlyIP ? 4 : 1));
        pfo->rows_per_file = filelen / bytes_per_subint;
        pfo->sub.bytes_per_subint = bytes_per_subint;
    } else {  // By default, keep the filesize roughly constant
        pfo->rows_per_file = pfi->rows_per_file * si->chan_per_sub *
            cmd->dstime * (cmd->onlyIP ? 4 : 1) *
            pfi->hdr.nbits / pfo->hdr.nbits;
    }

    pfo->filenum = 0; // This causes the output files to be created
    pfo->filename[0] = '\0';
    pfo->rownum = 1;
    pfo->tot_rows = 0;
    pfo->N = 0;
    // Set the "orig" values to those of the input file
    pfo->hdr.orig_nchan = pfi->hdr.nchan;
    pfo->hdr.orig_df = pfi->hdr.df;
    {
        char *inpath, *infile;
        split_path_file(pfi->basefilename, &inpath, &infile);
        sprintf(pfo->basefilename, "%s_subs", infile);
        free(inpath);
        free(infile);
    }
    // Reset different params
    pfo->sub.dat_freqs = si->sub_freqs;
    pfo->sub.dat_weights = si->weights;
    pfo->sub.dat_offsets = si->offsets;
    pfo->sub.dat_scales  = si->scales;
    pfo->hdr.ds_freq_fact = si->chan_per_sub;
    pfo->hdr.ds_time_fact = cmd->dstime;
    pfo->hdr.onlyI = cmd->onlyIP;
    pfo->hdr.chan_dm = si->dm;
    pfo->sub.rawdata = (unsigned char *)malloc(si->nsub * si->npol * si->buflen);
    if (pfo->hdr.nbits!=8) {
        pfo->sub.data = (unsigned char *)malloc(si->nsub * si->npol * si->buflen *
                                                (8 / pfo->hdr.nbits));
    } else {
        pfo->sub.data = pfo->sub.rawdata;
    }
    si->outfbuffer = (float *)calloc(si->nsub * si->npol * si->buflen,
                                     sizeof(float));
    pfo->sub.fdata = si->outfbuffer;

    // Now re-read the first row (i.e. for "real" this time)
    get_current_row(pfi, si);

    // Set the new weights properly
    new_weights(pfi, pfo);

    // Now fill the first part of si->fbuffer with the chan_avgs so that
    // it acts like a previously read block (or row)
    fill_chans_with_avgs(si->max_overlap, si->bufwid,
                         si->fbuffer, si->chan_avgs);
}
Exemplo n.º 5
0
int client_mode(char* server, char mode, char* filename) {
    
    DEBUG("除錯模式啟動\n");

    /*  建立客戶端 socket  */

    if ((client_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
        perror("socket() 呼叫失敗");
        exit(EXIT_FAILURE);
    }

    /*  設定客戶端 socket  */

    bzero(&server_address, sizeof (struct sockaddr_in));
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr(server);
    server_address.sin_port = htons(PORT);
    len = sizeof (server_address);

    /* 與伺服器建立連線 */

    if ((result = connect(client_sockfd, (struct sockaddr *) &server_address, len)) < 0) {
        perror("connect() 呼叫失敗"); 
        close(client_sockfd);
        exit(EXIT_FAILURE);

    } else {
        printf("連線中...\n");
    }
    
    FD_ZERO(&readfds);
    FD_SET(client_sockfd, &readfds);
    
    /* 開始傳送接收資料 */
    
    bzero(bytebuf, 1);           
    bzero(buf, BUFF_LEN);
    bzero(tmp, BUFF_LEN);
    
    /* 通知伺服器目前的模式 (Download/Upload) */
    
    if (send(client_sockfd, &mode, sizeof (char), 0)) {
        DEBUG("mode 訊息已送出\n");
    }
    
    if (mode == 'D') {    /* 下載模式 */
    
        /* 要求伺服器提供使用者指定的檔案 */

        /* 傳送檔案名稱給伺服器 */
    
        if (send(client_sockfd, filename, BUFF_LEN, 0)) {
            DEBUG("Filename 訊息已送出\n");
        }
    
        /* 處理檔案路徑 */
        /* malloc two buffs */
        char* _path = malloc(BUFF_LEN);
        char*_fname = malloc(BUFF_LEN);
        
        split_path_file(&_path, &_fname, filename);
        strcpy(filename, _fname);
        chdir("./downloads");
        
        DEBUG("File name: %s\n", filename);

        /* 接收檔案大小 */
        
        if (recv(client_sockfd, &nread, sizeof (int), 0)) {
            DEBUG("Filesize 訊息已接收\n");
            printf("檔案大小為 %d bytes\n", nread);
        }
        
        if (nread <= 0) {
            printf("伺服器上沒有這個檔案喔\n"); 
            close(client_sockfd);
            exit(EXIT_FAILURE);
        }
        
        fp = fopen(filename, "wb, ccs=UTF-8");
        
         /* 顯示進度 */

        for (i = 0, cread = 1, per = 0; i < nread; i = i + 1, cread = cread + 1) { 
            
            bzero(bytebuf, sizeof (wchar_t*));
            
            st = recv(client_sockfd, bytebuf, 1, 0);
            
            per = ((float) cread / (float) nread) * 100;
            j = i % DOT_LEN;
            if (i == nread - 1) {
                j = DOT_LEN - 1;
            }
            
            /* 處理取得的資料 */
            
            fwrite(bytebuf, 1, 1, fp);
            
            cls();
            printf("\r進度:%3d %c %8s 正在下載 \"%s\" %d / %d bytes\n", per, '%', dot[j], filename, cread, nread);
            usleep(250);    /* 避免 CPU 佔用過高與畫面閃爍 */

        }
        
        fclose(fp);
        
        printf("傳輸完成\n");
        
        chdir("..");
    }
    
    if (mode == 'U') {    /* 上傳模式 */
    
        /* 處理檔案路徑 */
        /* malloc two buffs */
        char* _path = malloc(BUFF_LEN);
        char*_fname = malloc(BUFF_LEN);
        
        split_path_file(&_path, &_fname, filename);
        strcpy(filename, _fname);
        chdir(_path);
        
        DEBUG("File name: %s\n", filename);
        
        fp = fopen(filename, "rb, ccs=UTF-8");
        if (!fp) {
            printf("找不到 %s%s\n", _path, filename);
            close(fd);
            close(client_sockfd);
            exit(EXIT_FAILURE);
        }

        /* 開始傳送資料 */

        /* 取得檔案大小 */
        
        fseek(fp, 0L, SEEK_END);
        nread = ftell(fp);
        fseek(fp, 0L, SEEK_SET);
        
        DEBUG("File size: %d\n", nread);
        
        /* 傳送檔案名稱與檔案大小給對方 */
        
        if (send(client_sockfd, filename, BUFF_LEN, 0)) {
            DEBUG("Filename 訊息已送出\n");
        }
        
        if (send(client_sockfd, &nread, sizeof (int), 0)) {
            DEBUG("Filesize 訊息已送出\n");
        }

        for (i = 0, cread = 1, per = 0; i < nread; i = i + 1, cread = cread + 1) { 
            
            bzero(bytebuf, sizeof (wchar_t*));
            
            if (!feof(fp)) {
                st = fread(bytebuf, 1, 1, fp);
            }
                   
            st = send(client_sockfd, bytebuf, 1, 0);
            
            per = ((float) cread / (float) nread) * 100;
            j = i % DOT_LEN;
            if (i == nread - 1) {
                j = DOT_LEN - 1;
            }
            
            cls();
            printf("\r進度:%3d %c %8s 正在上傳 \"%s\" %d / %d bytes\n", per, '%', dot[j], filename, cread, nread);
            usleep(250);    /* 避免 CPU 佔用過高與畫面閃爍 */

        }
        
        fclose(fp);
    
        printf("傳輸完成\n");
    
        chdir("..");
    }
    
    
    /* 關閉 socket */
    
    close(client_sockfd);
    exit(EXIT_SUCCESS);
    
    return EXIT_SUCCESS;
}
Exemplo n.º 6
0
/* Given a GString containing MMD source, and optional base directory,
	substitute transclusion references in the source 

	Pass the path to the current folder if available -- should be a full path. 

	Keep track of what we're parsing to prevent recursion using stack. */
void transclude_source(GString *source, char *basedir, char *stack, int output_format, GString *manifest) {
	char *base = NULL;
	char *path = NULL;
	char *start;
	char *stop;
	char *temp;
	int curchar;
	size_t pos;
	char real[1000];
	FILE *input;
	long offset;

	if (basedir == NULL) {
		base = strdup("");
	} else {
		base = strdup(basedir);
	}

	GString *folder = NULL;
	GString *filename = NULL;
	GString *filebuffer = NULL;
	GString *stackstring = NULL;

	path = strdup(base);

	/* Look for override folder inside document */
	if (has_metadata(source->str, 0x000000)) {
		char *meta = extract_metadata_value(source->str, 0x000000, "transcludebase");
		if (meta != NULL)
			path = path_from_dir_base(base, meta);
	}

	if (path == NULL) {
		/* We have nowhere to look, so nothing to do */
		free(path);
		free(base);
		return;
	}

	folder = g_string_new(path);

	/* Ensure that folder ends in "/" */
	/* TODO: adjust for windows */
	if (!(folder->str[strlen(folder->str)-1] == '/') ) {
		g_string_append_c(folder, '/');
	}

	/* fprintf(stderr, "Transclude using '%s'\n", folder->str); */

	/* Iterate through {{foo.txt}} and substitute contents of file without metadata */

	start = strstr(source->str,"{{");

	while (start != NULL) {
		stop = strstr(start,"}}");
		if (stop == NULL)
			break;

		/* Check that we found something reasonable -- we cap at 1000 characters */
        if (stop - start < 1000) {
			strncpy(real,start+2,stop-start-2);
			real[stop-start-2] = '\0';

			if (is_separator(real[0])) {
				filename = g_string_new(real);
			} else {
				filename = g_string_new(folder->str);
				g_string_append_printf(filename, "%s",real);
			}

			if (strcmp(filename->str,"./TOC") == 0) {
				pos = stop - source->str;
				start = strstr(source->str + pos,"{{");
				g_string_free(filename, true);
				continue;
			}

			/* Adjust for wildcard extensions */
			/* But not if output_format == 0 */
			if (output_format && strncmp(&filename->str[strlen(filename->str) - 2],".*",2) == 0) {
				g_string_erase(filename, strlen(filename->str) - 2, 2);
				if (output_format == TEXT_FORMAT) {
					g_string_append(filename,".txt");
				} else if (output_format == HTML_FORMAT) {
					g_string_append(filename,".html");
				} else if (output_format == LATEX_FORMAT) {
					g_string_append(filename,".tex");
				} else if (output_format == BEAMER_FORMAT) {
					g_string_append(filename,".tex");
				} else if (output_format == MEMOIR_FORMAT) {
					g_string_append(filename,".tex");
				} else if (output_format == ODF_FORMAT) {
					g_string_append(filename,".fodt");
				} else if (output_format == OPML_FORMAT) {
					g_string_append(filename,".opml");
				} else if (output_format == LYX_FORMAT) {
					g_string_append(filename,".lyx");
				} else if (output_format == RTF_FORMAT) {
					g_string_append(filename,".rtf");
				} else {
					/* default extension -- in this case we only have 1 */
					g_string_append(filename,".txt");
				}
			}

			pos = stop - source->str;

			/* Add to the manifest (if not already included) */
			if (manifest != NULL) {
				temp = strstr(manifest->str,filename->str);

				offset = temp - manifest->str;
				if ((temp != NULL) &&
					((temp == manifest->str) || ((manifest->str)[offset - 1] == '\n')) &&
					(temp[strlen(filename->str)] == '\n') ){
					/* Already on manifest, so don't add again */
				} else {
					g_string_append_printf(manifest,"%s\n",filename->str);
				}
			}


			/* Don't reparse ourselves */
			if (stack != NULL) {
				temp = strstr(stack,filename->str);

				if ((temp != NULL) && (temp[strlen(filename->str)] == '\n')){
					start = strstr(source->str + pos,"{{");
					g_string_free(filename, true);
					continue;
				}
			}

			/* Read file */
#if defined(__WIN32)
			int wchars_num = MultiByteToWideChar(CP_UTF8, 0, filename->str, -1, NULL, 0);
			wchar_t wstr[wchars_num];
			MultiByteToWideChar(CP_UTF8, 0, filename->str, -1, wstr, wchars_num);

			if ((input = _wfopen(wstr, L"r")) != NULL ) {
#else
			if ((input = fopen(filename->str, "r")) != NULL ) {
#endif
				filebuffer = g_string_new("");

				while ((curchar = fgetc(input)) != EOF)
					g_string_append_c(filebuffer, curchar);
				
				fclose(input);

	 			pos = start - source->str;

				g_string_erase(source, pos, 2 + stop - start);

				/* Update stack list */
				stackstring = g_string_new(stack);
				g_string_append_printf(stackstring,"%s\n",filename->str);


				/* Recursively transclude files */

				/* We want to reset the base directory if we enter a subdirectory */
				char * new_dir;
				char * file_only;
				split_path_file(&new_dir, &file_only, filename->str);

				/* transclude_source(filebuffer, folder->str, stackstring->str, output_format, manifest); */
				transclude_source(filebuffer, new_dir, stackstring->str, output_format, manifest);

				free(new_dir);
				free(file_only);
				
				temp = source_without_metadata(filebuffer->str, 0x000000);

				g_string_insert(source, pos, temp);

				pos += strlen(temp);
				g_string_free(filebuffer, true);
				g_string_free(stackstring, true);
			} else {
				/* fprintf(stderr, "error opening file: %s\n", filename->str); */
			}

            g_string_free(filename, true);
        } else {
        	/* Our "match" was > 1000 characters long */
            pos = stop - source->str;
        }
		start = strstr(source->str + pos,"{{");
	}

	g_string_free(folder, true);
	free(path);
	free(base);
}

/* Allow for a footer to specify files to be appended to the end of the text, and then transcluded.
	Useful for appending a list of footnotes, citations, abbreviations, etc. to each separate file,
	but not including multiple copies when processing the master file. */
void append_mmd_footer(GString *source) {
	/* Look for mmd_footer metadata */
	if (has_metadata(source->str, 0x000000)) {
		char *meta = extract_metadata_value(source->str, 0x000000, "mmdfooter");
		if (meta != NULL)
			g_string_append_printf(source, "\n\n{{%s}}\n", meta);
	}
}

void prepend_mmd_header(GString *source) {
	/* Same thing, but to be inserted after metadata and before content */
	if (has_metadata(source->str, 0x000000)) {
		char *meta = extract_metadata_value(source->str, 0x000000, "mmdheader");
		if (meta != NULL) {
			char *content = strstr(source->str, "\n\n");
			if (content != NULL) {
				size_t pos = content - source->str;
				g_string_insert_printf(source, pos, "\n\n{{%s}}", meta);
			} else {
				g_string_append_printf(source, "\n\n{{%s}}\n", meta);
			}
		}
	}
}
Exemplo n.º 7
0
int main(int argc, char *argv[])
{
   FILE **infiles, *outfile = NULL, *scalingfile, *zerolagfile = NULL;
   int filenum, ptsperblock, numlags, numfiles, outnumlags;
   int bytes_per_read, scaling = 0, numscalings, firstfile, firstspec;
   int write_data = 1, update_posn = 0;
   long long N, numconverted = 0, numwritten = 0;
   char *path, *filenm, rawlags[4096];
   char outfilenm[200], filenmbase[200], zerolagnm[200], scalingnm[200];
   unsigned char output_samples[2048];
   float *scalings = NULL, lags[2048], tmp_floats[2048];
   double dt, T, time_offset;
   SPIGOT_INFO *spigots;
   sigprocfb fb;
   infodata idata;
   Cmdline *cmd;

   /* Call usage() if we have no command line arguments */
   if (argc == 1) {
      Program = argv[0];
      usage();
      exit(0);
   }

   /* Parse the command line using the excellent program Clig */
   cmd = parseCmdline(argc, argv);
   // showOptionValues();
   numfiles = cmd->argc;

   /* If requesting that we skip values or only write          */
   /* a specific number of values, require an output file name */
   if ((cmd->skip > 0) || cmd->numoutP){
      if (!cmd->outfileP && !cmd->stdoutP) {
         fprintf(stderr,
                 "\nspigot2filterbank ERROR:  You need to specify an output\n"
                 "     filename (or -stdout) when using the -skip and/or \n"
                 "     -numout options!\n\n");
         exit(1);
      }
   }

   /* Give an error if specifying stdout and an output file */
   if (cmd->stdoutP && cmd->outfileP){
      fprintf(stderr, 
              "\nspigot2filterbank ERROR:  You cannot specify both an output\n"
              "     file and that the data should go to STDOUT!\n\n");
      exit(1);
   }

   if (!cmd->stdoutP)
      printf("\nConverting SPIGOT FITs lags into SIGPROC filterbank format...\n\n");
   
   /* Determine the filename base from the first spigot file */
   split_path_file(cmd->argv[0], &path, &filenm);
   strncpy(filenmbase, filenm, strlen(filenm) - 5);
   filenmbase[strlen(filenm) - 5] = '\0';
   free(path);
   free(filenm);

   /* Open a file to store the zerolags */
   if (cmd->zerolagsP) {
      if (cmd->outfileP) {
         sprintf(zerolagnm, "%s.zerolags", cmd->outfile);
      } else {
         sprintf(zerolagnm, "%s.zerolags", filenmbase);
      }
      zerolagfile = chkfopen(zerolagnm, "wb");
   }

   /* Attempt to read a file with lag scalings in it */
   sprintf(scalingnm, "%s.scaling", filenmbase);
   if ((scalingfile = fopen(scalingnm, "rb"))) {
      /* Determine the length of the file */
      numscalings = (int) chkfilelen(scalingfile, sizeof(float));
      /* Create the array and read 'em */
      scalings = gen_fvect(numscalings);
      chkfread(scalings, sizeof(float), numscalings, scalingfile);
      scaling = 1;
      /* close the scaling file */
      fclose(scalingfile);
      if (!cmd->stdoutP)
         printf("Scaling the lags with the %d values found in '%s'\n\n",
                numscalings, scalingnm);
   }

   /* Read and convert the basic SPIGOT file information */
   if (!cmd->stdoutP)
      printf("Spigot card input file information:\n");
   spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles);
   infiles = (FILE **) malloc(sizeof(FILE *) * numfiles);
   for (filenum = 0; filenum < numfiles; filenum++) {
      if (!cmd->stdoutP)
         printf("  '%s'\n", cmd->argv[filenum]);
      infiles[filenum] = chkfopen(cmd->argv[filenum], "rb");
      read_SPIGOT_header(cmd->argv[filenum], spigots + filenum);
      rewind(infiles[filenum]);
   }
   if (!cmd->stdoutP) 
      printf("\n");

   /* The following is necessary in order to initialize all the */
   /* static variables in spigot.c                              */
   get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N,
                        &ptsperblock, &numlags, &dt, &T, &idata, 
                        !cmd->stdoutP);
   
   /* Compute the first file required */
   firstfile = cmd->skip / spigots[0].samples_per_file;
   firstspec = cmd->skip % spigots[0].samples_per_file;
   if (!cmd->numoutP) {
      cmd->numout = (N - cmd->skip) / cmd->downsamp;
   }
   bytes_per_read = numlags * spigots[0].bits_per_lag / 8;
   outnumlags = numlags - cmd->lokill - cmd->hikill;

   /* Step through the SPIGOT files */
   filenum = firstfile;
   while (numwritten < cmd->numout){
      split_path_file(cmd->argv[filenum], &path, &filenm);
      strncpy(filenmbase, filenm, strlen(filenm) - 5);
      filenmbase[strlen(filenm) - 5] = '\0';
      if (cmd->outfileP) {
         if (filenum==firstfile) {
            sprintf(outfilenm, "%s", cmd->outfile);
            outfile = chkfopen(outfilenm, "wb");
         }
      } else {
         sprintf(outfilenm, "%s.fil", filenmbase);
         if (cmd->stdoutP) {
            outfile = stdout;
         } else {
            outfile = chkfopen(outfilenm, "wb");
         }
      }
      if (!cmd->stdoutP) {
         if (filenum==firstfile)
            printf("Reading Spigot lags from '%s' (starting at sample %d)\n", 
                   cmd->argv[filenum], firstspec);
         else
            printf("Reading Spigot lags from '%s'\n", 
                   cmd->argv[filenum]);
         printf("Writing filterbank spectra to   '%s'\n\n", outfilenm);
      }
      
      /* Update the filterbank header information for each file */
      if (!spigots[filenum].tracking) {
         if (cmd->outfileP || cmd->stdoutP) {
            time_offset = 0.5 * cmd->numout *                   \
               spigots[filenum].dt_us * 1e-6 * cmd->downsamp;
         } else { // Just normal files
            time_offset = 0.5 * spigots[filenum].file_duration;
         }
         update_posn = 1;
      } else {
         update_posn = 0;
         time_offset = 0.0;
      }
      /* Adjust the Spigot start time for the skip */
      spigots[filenum].elapsed_time += cmd->skip * spigots[filenum].dt_us * 1e-6;
      /* Determine the SIGPROC header */
      spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase, 
                       cmd->lokill, cmd->hikill, cmd->downsamp, 
                       update_posn, time_offset);
      /* Correct the structure if we are using floats */
      if (cmd->floatsP) fb.nbits = 32;
      
      /* Write a filterbank header if we have not been told not to.   */
      /* Don't write it, though, if using stdio or a specified output */
      /* file and the input file is not the first.                    */
      if (!cmd->nohdrP) {
         if ((!cmd->stdoutP && !cmd->outfileP) ||
             ((cmd->stdoutP || cmd->outfileP) && filenum==firstfile)) {
            write_filterbank_header(&fb, outfile);
         }
      }

      /* Go to the correct autocorrelation in the correct first FITs file */
      chkfseek(infiles[filenum], 
               spigots[filenum].header_len + bytes_per_read*firstspec,
               SEEK_SET);
      
      /* Loop over the samples in the file */
      while ((numwritten < cmd->numout) && 
             (chkfread(rawlags, bytes_per_read, 1, infiles[filenum]))) {
         if (cmd->zerolagsP) {
            /* Correct the lags so we can write the zerolag */
            get_calibrated_lags(rawlags, lags);
            chkfwrite(lags, sizeof(float), 1, zerolagfile);
         }
         if (scaling) {
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 
                                 scalings[cmd->skip+numconverted]);
         } else {
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0);
         }
         /* If downsampling, average the current spectra */
         if (cmd->downsamp > 1) {
            int ii;
            if (numconverted % cmd->downsamp == 0) {
               write_data = 0;
               /* Zero the array used for averaging */
               for (ii = 0; ii < outnumlags; ii++)
                  tmp_floats[ii] = 0.0;
            } else {
               /* Add the current data to the array used for averaging */
               for (ii = 0; ii < outnumlags; ii++)
                  tmp_floats[ii] += (float) output_samples[ii+cmd->lokill];
               /* If that was the last sample to be added, average them */
               /* and put them back into output_samples */
               if (numconverted % cmd->downsamp == (cmd->downsamp-1)) {
                  write_data = 1;
                  for (ii = 0; ii < outnumlags; ii++) {
                     tmp_floats[ii] /= (float) cmd->downsamp;
                     output_samples[ii+cmd->lokill] = \
                        (unsigned char)(tmp_floats[ii]+0.5);
                  }
               }
            }
         }
         numconverted++;

         if (write_data) {
            int ii;

            /* Invert the band so that the high freqs are first */
            /* This is how SIGPROC stores its data.             */
            if (cmd->floatsP) {
               float tempzz = 0.0, *loptr, *hiptr;
               loptr = tmp_floats;  //  killed channels are already gone
               hiptr = tmp_floats + outnumlags - 1;
               for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) {
                  SWAP(*loptr, *hiptr);
               }
            } else {
               unsigned char tempzz = 0.0, *loptr, *hiptr;
               loptr = output_samples + cmd->lokill;
               hiptr = output_samples + cmd->lokill + outnumlags - 1;
               for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) {
                  SWAP(*loptr, *hiptr);
               }
            }

            /* Now actually write the data */
            if (cmd->floatsP) {
               /* Copy the bytes to floats */
               for (ii = 0; ii < outnumlags; ii++)
                  tmp_floats[ii] = (float) output_samples[ii+cmd->lokill];
               chkfwrite(tmp_floats, sizeof(float), fb.nchans, outfile);
            } else {
               chkfwrite(output_samples+cmd->lokill, 
                         sizeof(unsigned char), fb.nchans, outfile);
            }
            numwritten++;
         }
      }
      if ((!cmd->stdoutP) && (!cmd->outfileP))
         fclose(outfile);
      fclose(infiles[filenum]);
      firstspec = 0;
      filenum++;
      free(path);
      free(filenm);
   }
   if ((!cmd->stdoutP) && (cmd->outfileP))
      fclose(outfile);
   if (cmd->zerolagsP)
      fclose(zerolagfile);
   if (!cmd->stdoutP)
      fprintf(stderr, "Converted %lld samples and wrote %lld.\n\n", 
              numconverted, numwritten);
   if (scaling)
      free(scalings);
   free(spigots);
   free(infiles);
   return 0;
}