Ejemplo n.º 1
0
void wapp2fb(FILE *input, FILE *output) /* includefile */
{
  FILE *bptr, *fpou, *alfa[2];
  int pixel[2];
  double pra, pdec;
  double bw, bandwidth, scale, power, hweight, tsamp_us, crate, lmst;
  double *lag, *sum, *acf, *window, jan1, days, epoch, ras,des,rahr,dede; 
  float zerolag,*block,smin,smax;
  int doit,i,j,k,two_nlags,nlags,stat,rec_size,idump,swap_bytes,ifnum,opened;
  int filesize,headersize,beam,utsecs,iymdf[4],rah,ram,ded,dem;
  unsigned char *cblock, zuc;
  unsigned short *sblock, zus; 
  unsigned int zul;
  char message[80], outfile[80];
  void *dump;
  static float realtime=0.0;

#ifdef FFTW
  fftw_plan fftplan;
#endif
  /* establish whether we need to swap bytes (WAPP is little endian) */
  swap_bytes=big_endian();

  /* initialise correlator parameters used below */
  nlags=nchans;  
  two_nlags=2*nlags;  
  bandwidth=foff*nlags;
  tsamp_us=tsamp*1.0e6;
  if (bandwidth<0.0) bandwidth *= -1.0;

#ifdef FFTW
  acf = fftw_malloc(sizeof(double) * two_nlags);
  lag = fftw_malloc(sizeof(double) * two_nlags);
  /* set up fftw table and acf array when computing power spectra */
  fftplan=fftw_plan_r2r_1d(two_nlags,acf,lag,FFTW_R2HC,FFTW_PATIENT);
#endif
#ifndef FFTW
  /* set up acf array when computing power spectra */
  acf = (double *) malloc(two_nlags * sizeof(double));
  lag = (double *) malloc(two_nlags * sizeof(double));
#endif

  if (compute_spectra) {
    /* ranges for scaling spectra */
    smin=0.0;smax=3.0;
  } else {
    /* ranges for scaling correlation functions */
    smin=-0.5;smax=1.0;
  }

  /* set up the weights for windowing of ACF to monimize FFT leakage */
  if (hanning) {
    /* Hanning window */
    hweight=0.50;
  } else if (hamming) {
    /* Hamming window */
    hweight=0.54;
  } else {
    /* no window (default) */
    hweight=1.00;
  }

  /* define the smoothing window to be applied base on the above weight */
  window = (double *) malloc(nlags * sizeof(double));
  for (j=0; j<nlags; j++) window[j]=(hweight+(1.0-hweight)*cos(PI*j/nlags));

  /* work out number of IFs to loop over */
  if (sumifs && (nifs>1)) {
    smin*=2.0;
    smax*=2.0;
    ifnum=2;
  } else {
    sumifs=0;
    ifnum=nifs;
  }

  /* calculate required record size for reading - i.e. number of bytes/dump */
  rec_size = nifs*nlags*(nbits/8);
  dump = malloc(rec_size); /* pointer to the correlator dump */

  /* correlator data rate */
  crate = 1.0/(tsamp_us-WAPP_DEAD_TIME); 
  /* scale factor to normalize correlation functions */
  if (bandwidth < 50.0) 
    bw=50.0; /* correct scaling for narrow-band use */
  else
    bw=bandwidth;

  scale = crate/bw;
  if (wapp_level==9) scale/=16.0; /* 9-level sampling */
  if (wapp_sum) scale/=2.0;  /* summed IFs (search mode) */
  scale*=pow(2.0,(double)wapp_lagtrunc); /* needed for truncation modes */

  /* now define a number of working arrays to store lags and spectra */
  block = (float *) malloc(nlags * sizeof(float));
  cblock = (unsigned char *) malloc(nlags * sizeof(unsigned char));
  sblock = (unsigned short *) malloc(nlags * sizeof(unsigned short));

  /* if the file is ALFA data --- do the demultiplexing to two files */
  if (wapp_isalfa) {

    angle_split(src_raj,&rah,&ram,&ras);
    rahr=(double)rah+(double)ram/60.0+(double)ras/3600.0;
    angle_split(src_dej,&ded,&dem,&des);
    if (ded>0)
      dede=(double)ded+(double)dem/60.0+(double)des/3600.0;
    else
      dede=(double)ded-(double)dem/60.0-(double)des/3600.0;
    /* calculate local sidereal time in hours */
    lmst=slaGmst(tstart)*12.0/4.0/atan(1.0)-4.4502051459439667;
    if (lmst<0.0) lmst+=24.0;
    slaDjcal(5,tstart,iymdf,&stat);
    slaCaldj(iymdf[0],1,1,&jan1,&stat);
    days=tstart-jan1+1.0;
    epoch=(double)iymdf[0]+days/365.25;
    utsecs=86400*(tstart-floor(tstart));

    pixel[0]=(wapp_number-1)*2;
    pixel[1]=pixel[0]+1;
    puts("opening output files for demultiplexed ALFA data...");
    for (i=0; i<2; i++) {
      if (alfa_raj[pixel[i]] == 0.0) {
      alfa_position(rahr,dede,lmst,epoch,alfa_ang,0.0,0.0,pixel[i],&pra,&pdec);
      src_raj=h2hms(pra);
      src_dej=deg2dms(pdec);
      } else {
      src_raj=h2hms(alfa_raj[pixel[i]]);
      src_dej=deg2dms(alfa_dej[pixel[i]]);
      }
      sprintf(outfile,"%s_%.0f_%05d_%04d_%s_%d.fil",
	    project,floor(tstart),utsecs,
	    scan_number,source_name,pixel[i]);
      alfa[i]=open_file(outfile,"wb");
      puts(outfile);
      filterbank_header(alfa[i]);
    }
    beam=0;
  }

  if (headerfile) {
    /* write output ASCII header file */
    fpou=open_file("head","w");  
    fprintf(fpou,"Original WAPP file: %s\n",inpfile);
    fprintf(fpou,"Sample time (us): %f\n",tsamp_us);
    fprintf(fpou,"Observation time (s): %f\n",wapp_obstime);
    fprintf(fpou,"Time stamp (MJD): %18.12f\n",tstart);
    fprintf(fpou,"Number of samples/record: %d\n",512);
    fprintf(fpou,"Center freq (MHz): %f\n",fch1+(float)nlags*foff/2.0);
    fprintf(fpou,"Channel band (kHz): %f\n",bandwidth*1000.0/nlags);
    fprintf(fpou,"Number of channels/record: %d\n",nlags);
    fprintf(fpou,"Nifs: %d\n",ifnum);
    fprintf(fpou,"RA (J2000): %f\n",src_raj);
    fprintf(fpou,"DEC (J2000):  %f\n",src_dej);
    fprintf(fpou,"Gal l: %.4f\n",srcl);
    fprintf(fpou,"Gal b: %.4f\n",srcb); 
    fprintf(fpou,"Name: %s\n",source_name);
    fprintf(fpou,"Lagformat: %d\n",wapp_lagformat);
    fprintf(fpou,"Sum: %d\n",wapp_sum);
    fprintf(fpou,"Level: %d\n",wapp_level);
    fprintf(fpou,"AZ at start: %f\n",az_start);
    fprintf(fpou,"ZA at start: %f\n",za_start);
    fprintf(fpou,"AST at start: %f\n",ast0);
    fprintf(fpou,"LST at start: %f\n",lst0);
    fprintf(fpou,"Project ID: %s\n",project);
    fprintf(fpou,"Observers: %s\n",culprits);
    filesize=sizeof_file(inpfile);
    fprintf(fpou,"File size (bytes): %d\n",filesize);
    headersize=wapp_header_size+wapp_incfile_length;
    fprintf(fpou,"Data size (bytes): %d\n",filesize-headersize);
    fprintf(fpou,"Number of samples: %d\n",nsamples(inpfile,headersize,nbits,nifs,nchans));
    fclose(fpou);
  }

  /* initialise various counters and flags */
  opened=idump=i=j=0; 

  /* main loop reading data from infile until no more left to read */
  while( (stat=read(wapp_file,dump,rec_size)) == rec_size) {

    /* calculate elapsed time and determine whether we process this record */
    realtime += (float) tsamp;
    if ( (doit=process(realtime,start_time,final_time)) == -1) break;

    if (doit) {

      /* set ALFA beam output if necessary */
      if (wapp_isalfa) {
	output=alfa[beam];       /* set output file for this loop */
	beam=!(beam);            /* flip file for next iteration */
      }

      /* clear zerolag and blocksum arrays */
      zerolag=0.0;
      for (j=0; j<nlags; j++) block[j]=0.0;

      /* loop over the IFs */
      for (i=0; i<ifnum; i++) {
	if (ifstream[i]=='Y') {
	  if (zerolagdump) {
	    /* only interested in the zero lag term for each IF */
	    switch (nbits) {
	    case 8:
	      zuc = *(((unsigned char *)dump)+i*nlags);
	      zerolag+=zuc;
	      break;
	    case 16:
	      zus = *(((unsigned short *)dump)+i*nlags);
	      if (swap_bytes) swap_short(&zus); 
	      zerolag+=zus;
	      break;
	    case 32:
	      zul = *(((unsigned int *)dump)+i*nlags);
	      if (swap_bytes) swap_int(&zul); 
	      zerolag+=zul;
	      break;
	    }
	    /* write out the data checking IF number for summed mode */
	    if ( (sumifs && (i==1)) || (!sumifs) ) {
	      if (obits==32) {
		if (swapout) swap_float(&zerolag);
		fwrite(&zerolag,sizeof(float),1,output);
	      } else {
		sprintf(message,"cannot write %d bits in zerolag mode",obits);
		error_message(message);
	      }
	    }
	  } else {
	    /* fill lag array with scaled CFs */
	    for (j=0; j<nlags; j++) {
	      switch (nbits) {
	      case 8:
		zuc = *(((unsigned char *)dump)+j+i*nlags);
		lag[j] = scale * (double) zuc - 1.0;
		break;
	      case 16:
		zus = *(((unsigned short *)dump)+j+i*nlags);
		if (swap_bytes) swap_short(&zus);
		lag[j] = scale * (double) zus - 1.0;
		break;
	      case 32:
		zul = *(((unsigned int  *)dump)+j+i*nlags);
		if (swap_bytes) swap_int(&zul);
		lag[j] = scale * (double) zul - 1.0;
		break;
	      }
	    }
	    /* calculate power and correct for finite level quantization */
	    power = inv_cerf(lag[0]);
	    power = 0.1872721836/power/power;
	    if (i<2) {
	      if (do_vanvleck) { 
		if (wapp_level==3) {
		  /* apply standard 3-level van vleck correction */
		  vanvleck3lev(lag,nlags);
		} else if (wapp_level==9) {
		  /* apply 9-level van vleck correction */
		  vanvleck9lev(lag,nlags);
		}
	      }
	    }

	    if (compute_spectra) {
	      /* form windowed even ACF in array */
	      for(j=1; j<nlags; j++) {
		acf[j]=window[j]*lag[j]*power;
		acf[two_nlags-j]=acf[j];
	      }   
	      acf[nlags]=0.0;
	      acf[0]=lag[0]*power; 
	      /* FFT the ACF (which is real and even) -> real and even FFT */
#ifdef FFTW
	      fftw_execute(fftplan);
#endif
#ifndef FFTW
	      rfft(two_nlags,acf,lag);
#endif
	      /* if the band needs to be flipped --- do it here */
	      if (wapp_flip) {
		/* use acf as temporary array */
		for (j=0;j<nlags;j++) acf[j]=lag[j]; 
		k=nlags-1;
		for (j=0;j<nlags;j++) {
		  lag[k]=acf[j];
		  k--;
		}
	      }
  	      /* add lags to block array */
	      for (j=0; j<nlags; j++) block[j]+=lag[j];
	    } else {			
	      /* just copy correlation functions into block */
	      for (j=0; j<nlags; j++) block[j]=lag[j];	
	    }
	    /* write out data block checking IF number for summed mode */
	    if ( (sumifs && (i==1)) || (!sumifs) ) {
	      if (obits==32) {
		if (swapout) for (j=0; j<nlags; j++) swap_float(&block[j]);
		fwrite(block,sizeof(float),nlags,output);
	      } else if (obits==16) {
		float2short(block,nlags,smin,smax,sblock);
		if (swapout) for (j=0; j<nlags; j++) swap_short(&sblock[j]);
		fwrite(sblock,sizeof(unsigned short),nlags,output);
	      } else if (obits==8) {
		float2char(block,nlags,smin,smax,cblock);
		fwrite(cblock,sizeof(unsigned char),nlags,output);
	      } else if (obits==4) {
		float2four(block,nlags,smin,smax,cblock);
		fwrite(cblock,sizeof(unsigned char),nlags/2,output);
	      } else {
		sprintf(message,"cannot write %d bits in wapp2fb",obits);
		error_message(message);
	      }
	    }
	  } /* end of zerolagdump if */

	  if (!sumifs) { /* reset block and zerolag if not summing */
	    zerolag=0.0;
	    for (j=0; j<nlags; j++) block[j]=0.0;
	  }
	}          /* end of IFstream if */
      }            /* end of loop over IFs */
    }              /* end of processing if */

    /* increment dump counter and update logfile every 512 dumps */
    idump++;
    if (idump%512 == 0) {
      if (!opened) {
	/* open up logfile */
	open_log("filterbank.monitor");
	opened=1;
      }
      sprintf(message,"time:%.1fs",realtime);
      update_log(message);
    }
  }                /* end of main read loop*/

    
  /* job done - free up remaining arrays */
  free(dump);free(block);free(sblock);free(cblock);free(window);
#ifdef FFTW
  fftw_destroy_plan(fftplan);
  fftw_free(acf); fftw_free(lag);
#endif
#ifndef FFTW
  free(acf); free(lag);
#endif
}
Ejemplo n.º 2
0
void WAPP_lags_to_spectra(int numwapps, struct wappinfo *w,
                          void *rawdata, float *spectra, float *lags,
                          fftwf_plan fftplan)
// This routine converts a single point of WAPP lags
// into a filterbank style spectrum array of floats.
// Van Vleck corrections are applied.
{
    int ii, ifnum = 0, wappnum = 0, index = 0;
    double power;

    // Loop over the WAPPs
    for (wappnum = 0; wappnum < numwapps; wappnum++) {
        index = wappnum * w->numifs * w->numchans;

        // Loop over the IFs
        for (ifnum = 0; ifnum < w->numifs; ifnum++, index += w->numchans) {

            // Fill lag array with scaled CFs
            if (w->bits_per_lag == 16) {
                unsigned short *sdata = (unsigned short *) rawdata;
                for (ii = 0; ii < w->numchans; ii++)
                    lags[ii] = w->corr_scale * sdata[ii + index] - 1.0;
            } else {
                unsigned int *idata = (unsigned int *) rawdata;
                for (ii = 0; ii < w->numchans; ii++)
                    lags[ii] = w->corr_scale * idata[ii + index] - 1.0;
            }

            // Calculate power
            power = inv_cerf(lags[0]);
            power = 0.1872721836 / (power * power);

            // Apply Van Vleck Corrections to the Lags
            if (w->corr_level == 3)
                vanvleck3lev(lags, w->numchans);
            else
                vanvleck9lev(lags, w->numchans);

            for (ii = 0; ii < w->numchans; ii++)
                lags[ii] *= power;

            // FFT the ACF lags (which are real and even) -> real and even FFT
            fftwf_execute(fftplan);

#if 0
            printf("\n");
            for (ii = 0; ii < w->numchans; ii++)
                printf("%d  %.7g\n", ii, lags[ii]);
            printf("\n");
            exit(0);
#endif

            // Reverse the band if it needs it
            if (w->invertband) {
                float tempzz = 0.0, *loptr, *hiptr;
                loptr = lags + 0;
                hiptr = lags + w->numchans - 1;
                for (ii = 0; ii < w->numchans / 2; ii++, loptr++, hiptr--) {
                    SWAP(*loptr, *hiptr);
                }
            }
            // Copy the spectra into the proper portion of the spectra array
            for (ii = 0; ii < w->numchans; ii++)
                spectra[index + ii] = lags[ii];
        }
    }
}