PageRenderTime 67ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/src/spigot2filterbank.c

https://github.com/joerivanleeuwen/presto
C | 387 lines | 303 code | 29 blank | 55 comment | 83 complexity | 08dba4c4c4cdadee87cdeac8ef4bedfb MD5 | raw file
  1. #include "presto.h"
  2. #include "mask.h"
  3. #include "spigot.h"
  4. #include "sigproc_fb.h"
  5. #include "fitsfile.h"
  6. #include "fitshead.h"
  7. #include "spigot2filterbank_cmd.h"
  8. #include "slalib.h"
  9. extern void get_calibrated_lags(void *rawlags, float *calibrated_lags);
  10. /* extern void sla_obs_(int *N, char *scope, char *name, */
  11. /* double *lon, double *lat, double *hgt); */
  12. /* extern void sla_oap_(char *type, double *azimuth, double *zendist, */
  13. /* double *MJD, double *dut, double *lon, double *lat, */
  14. /* double *hgt, double *xp, double *yp, double *temp, */
  15. /* double *atm, double *humid, double *microns, */
  16. /* double *tlr, double *rap, double *dap); */
  17. /* extern void sla_amp_(double *rap, double *dap, double *MJD, */
  18. /* double *equinox, double *ramean, double *decmean); */
  19. void spigot2sigprocfb(SPIGOT_INFO * spigot, sigprocfb * fb, char *filenmbase,
  20. int lokill, int hikill, int downsamp,
  21. int update_posn, double time_offset)
  22. {
  23. int h_or_d, m;
  24. double s, dt;
  25. /* Set the time offset for the posn calc */
  26. if (update_posn){
  27. dt = time_offset;
  28. } else {
  29. dt = 0.0;
  30. }
  31. strncpy(fb->inpfile, filenmbase, 40);
  32. strncpy(fb->source_name, spigot->object, 80);
  33. fb->nifs = 1;
  34. if (spigot->num_samplers == 1)
  35. strncpy(fb->ifstream, "YXXX", 8);
  36. else if (spigot->num_samplers == 2)
  37. strncpy(fb->ifstream, "YYXX", 8);
  38. fb->tstart = spigot->MJD_obs + spigot->elapsed_time / SECPERDAY;
  39. fb->tsamp = spigot->dt_us / 1e6 * downsamp;
  40. hours2hms(spigot->ra / 15.0, &h_or_d, &m, &s);
  41. fb->src_raj = h_or_d * 10000.0 + m * 100.0 + s;
  42. deg2dms(spigot->dec, &h_or_d, &m, &s);
  43. fb->src_dej = abs(h_or_d) * 10000.0 + abs(m) * 100.0 + fabs(s);
  44. if (spigot->dec < 0) fb->src_dej = -fb->src_dej;
  45. fb->az_start = spigot->az;
  46. fb->za_start = 90.0-spigot->el;
  47. fb->nchans = spigot->lags_per_sample;
  48. fb->foff = spigot->bandwidth / fb->nchans;
  49. fb->fch1 = spigot->freq_ctr + (fb->nchans / 2 - 0.5) * fb->foff;
  50. fb->fch1 -= fb->foff * hikill;
  51. fb->nchans -= (hikill + lokill);
  52. fb->foff = -fb->foff;
  53. fb->machine_id = 7;
  54. fb->telescope_id = 6;
  55. fb->nbits = 8;
  56. fb->sumifs = spigot->summed_pols;
  57. if (fb->sumifs)
  58. fb->nifs = 1;
  59. else {
  60. if (spigot->num_samplers == 2)
  61. fb->nifs = 2;
  62. else
  63. fb->nifs = 1;
  64. }
  65. /* The following are not necessary for writing filterbank files */
  66. fb->headerlen = 0;
  67. fb->N = spigot->samples_per_file;
  68. /* Update the position if the GBT was not tracking */
  69. /* (i.e. for the driftscan surveys) */
  70. if (update_posn && !spigot->tracking) {
  71. int N=0;
  72. char scope[10]={"GBT"}, type[]={"A"};
  73. char name[40];
  74. double MJD, lon, lat, hgt, microns, az, zd, rap, dap, rmn, dmn;
  75. double dtmp=0.0, atm=1010.0, temp=283.0;
  76. double humid=0.5, tlr=0.0065, eq=2000.0;
  77. /* Compute the RA/DEC using SLALIB from the Az/El */
  78. slaObs(N,scope,name,&lon,&lat,&hgt);
  79. if (fabs(hgt-880.0) > 0.01) {
  80. printf("Warning!: SLALIB is not correctly identifying the GBT!\n\n");
  81. }
  82. //printf("slalib: %d '%s' '%s' %f %f %f\n",
  83. // N, scope, name, lon, lat, hgt);
  84. lon = -lon;
  85. az = fb->az_start * DEGTORAD;
  86. zd = fb->za_start * DEGTORAD;
  87. microns = 3e8/(spigot->freq_ctr*1e6)*1e6;
  88. MJD = fb->tstart + dt/86400.0;
  89. slaOap(type,az,zd,MJD,dtmp,lon,lat,hgt,
  90. dtmp,dtmp,temp,atm,humid,microns,tlr,&rap,&dap);
  91. //printf("slalib: %.15f %.15f\n", rap, dap);
  92. slaAmp(rap,dap,MJD,eq,&rmn,&dmn);
  93. //printf("slalib: %.15f %.15f\n", rmn, dmn);
  94. /* Now update the positions */
  95. hours2hms(rmn * RADTODEG / 15.0, &h_or_d, &m, &s);
  96. fb->src_raj = h_or_d * 10000.0 + m * 100.0 + s;
  97. deg2dms(dmn * RADTODEG, &h_or_d, &m, &s);
  98. fb->src_dej = abs(h_or_d) * 10000.0 + abs(m) * 100.0 + fabs(s);
  99. if (dmn < 0) fb->src_dej = -fb->src_dej;
  100. }
  101. }
  102. int main(int argc, char *argv[])
  103. {
  104. FILE **infiles, *outfile = NULL, *scalingfile, *zerolagfile = NULL;
  105. int filenum, ptsperblock, numlags, numfiles, outnumlags;
  106. int bytes_per_read, scaling = 0, numscalings, firstfile, firstspec;
  107. int write_data = 1, update_posn = 0;
  108. long long N, numconverted = 0, numwritten = 0;
  109. char *path, *filenm, rawlags[4096];
  110. char outfilenm[200], filenmbase[200], zerolagnm[200], scalingnm[200];
  111. unsigned char output_samples[2048];
  112. float *scalings = NULL, lags[2048], tmp_floats[2048];
  113. double dt, T, time_offset;
  114. SPIGOT_INFO *spigots;
  115. sigprocfb fb;
  116. infodata idata;
  117. Cmdline *cmd;
  118. /* Call usage() if we have no command line arguments */
  119. if (argc == 1) {
  120. Program = argv[0];
  121. usage();
  122. exit(0);
  123. }
  124. /* Parse the command line using the excellent program Clig */
  125. cmd = parseCmdline(argc, argv);
  126. // showOptionValues();
  127. numfiles = cmd->argc;
  128. /* If requesting that we skip values or only write */
  129. /* a specific number of values, require an output file name */
  130. if ((cmd->skip > 0) || cmd->numoutP){
  131. if (!cmd->outfileP && !cmd->stdoutP) {
  132. fprintf(stderr,
  133. "\nspigot2filterbank ERROR: You need to specify an output\n"
  134. " filename (or -stdout) when using the -skip and/or \n"
  135. " -numout options!\n\n");
  136. exit(1);
  137. }
  138. }
  139. /* Give an error if specifying stdout and an output file */
  140. if (cmd->stdoutP && cmd->outfileP){
  141. fprintf(stderr,
  142. "\nspigot2filterbank ERROR: You cannot specify both an output\n"
  143. " file and that the data should go to STDOUT!\n\n");
  144. exit(1);
  145. }
  146. if (!cmd->stdoutP)
  147. printf("\nConverting SPIGOT FITs lags into SIGPROC filterbank format...\n\n");
  148. /* Determine the filename base from the first spigot file */
  149. split_path_file(cmd->argv[0], &path, &filenm);
  150. strncpy(filenmbase, filenm, strlen(filenm) - 5);
  151. filenmbase[strlen(filenm) - 5] = '\0';
  152. free(path);
  153. free(filenm);
  154. /* Open a file to store the zerolags */
  155. if (cmd->zerolagsP) {
  156. if (cmd->outfileP) {
  157. sprintf(zerolagnm, "%s.zerolags", cmd->outfile);
  158. } else {
  159. sprintf(zerolagnm, "%s.zerolags", filenmbase);
  160. }
  161. zerolagfile = chkfopen(zerolagnm, "wb");
  162. }
  163. /* Attempt to read a file with lag scalings in it */
  164. sprintf(scalingnm, "%s.scaling", filenmbase);
  165. if ((scalingfile = fopen(scalingnm, "rb"))) {
  166. /* Determine the length of the file */
  167. numscalings = (int) chkfilelen(scalingfile, sizeof(float));
  168. /* Create the array and read 'em */
  169. scalings = gen_fvect(numscalings);
  170. chkfread(scalings, sizeof(float), numscalings, scalingfile);
  171. scaling = 1;
  172. /* close the scaling file */
  173. fclose(scalingfile);
  174. if (!cmd->stdoutP)
  175. printf("Scaling the lags with the %d values found in '%s'\n\n",
  176. numscalings, scalingnm);
  177. }
  178. /* Read and convert the basic SPIGOT file information */
  179. if (!cmd->stdoutP)
  180. printf("Spigot card input file information:\n");
  181. spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles);
  182. infiles = (FILE **) malloc(sizeof(FILE *) * numfiles);
  183. for (filenum = 0; filenum < numfiles; filenum++) {
  184. if (!cmd->stdoutP)
  185. printf(" '%s'\n", cmd->argv[filenum]);
  186. infiles[filenum] = chkfopen(cmd->argv[filenum], "rb");
  187. read_SPIGOT_header(cmd->argv[filenum], spigots + filenum);
  188. rewind(infiles[filenum]);
  189. }
  190. if (!cmd->stdoutP)
  191. printf("\n");
  192. /* The following is necessary in order to initialize all the */
  193. /* static variables in spigot.c */
  194. get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N,
  195. &ptsperblock, &numlags, &dt, &T, &idata,
  196. !cmd->stdoutP);
  197. /* Compute the first file required */
  198. firstfile = cmd->skip / spigots[0].samples_per_file;
  199. firstspec = cmd->skip % spigots[0].samples_per_file;
  200. if (!cmd->numoutP) {
  201. cmd->numout = (N - cmd->skip) / cmd->downsamp;
  202. }
  203. bytes_per_read = numlags * spigots[0].bits_per_lag / 8;
  204. outnumlags = numlags - cmd->lokill - cmd->hikill;
  205. /* Step through the SPIGOT files */
  206. filenum = firstfile;
  207. while (numwritten < cmd->numout){
  208. split_path_file(cmd->argv[filenum], &path, &filenm);
  209. strncpy(filenmbase, filenm, strlen(filenm) - 5);
  210. filenmbase[strlen(filenm) - 5] = '\0';
  211. if (cmd->outfileP) {
  212. if (filenum==firstfile) {
  213. sprintf(outfilenm, "%s", cmd->outfile);
  214. outfile = chkfopen(outfilenm, "wb");
  215. }
  216. } else {
  217. sprintf(outfilenm, "%s.fil", filenmbase);
  218. if (cmd->stdoutP) {
  219. outfile = stdout;
  220. } else {
  221. outfile = chkfopen(outfilenm, "wb");
  222. }
  223. }
  224. if (!cmd->stdoutP) {
  225. if (filenum==firstfile)
  226. printf("Reading Spigot lags from '%s' (starting at sample %d)\n",
  227. cmd->argv[filenum], firstspec);
  228. else
  229. printf("Reading Spigot lags from '%s'\n",
  230. cmd->argv[filenum]);
  231. printf("Writing filterbank spectra to '%s'\n\n", outfilenm);
  232. }
  233. /* Update the filterbank header information for each file */
  234. if (!spigots[filenum].tracking) {
  235. if (cmd->outfileP || cmd->stdoutP) {
  236. time_offset = 0.5 * cmd->numout * \
  237. spigots[filenum].dt_us * 1e-6 * cmd->downsamp;
  238. } else { // Just normal files
  239. time_offset = 0.5 * spigots[filenum].file_duration;
  240. }
  241. update_posn = 1;
  242. } else {
  243. update_posn = 0;
  244. time_offset = 0.0;
  245. }
  246. /* Adjust the Spigot start time for the skip */
  247. spigots[filenum].elapsed_time += cmd->skip * spigots[filenum].dt_us * 1e-6;
  248. /* Determine the SIGPROC header */
  249. spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase,
  250. cmd->lokill, cmd->hikill, cmd->downsamp,
  251. update_posn, time_offset);
  252. /* Correct the structure if we are using floats */
  253. if (cmd->floatsP) fb.nbits = 32;
  254. /* Write a filterbank header if we have not been told not to. */
  255. /* Don't write it, though, if using stdio or a specified output */
  256. /* file and the input file is not the first. */
  257. if (!cmd->nohdrP) {
  258. if ((!cmd->stdoutP && !cmd->outfileP) ||
  259. ((cmd->stdoutP || cmd->outfileP) && filenum==firstfile)) {
  260. write_filterbank_header(&fb, outfile);
  261. }
  262. }
  263. /* Go to the correct autocorrelation in the correct first FITs file */
  264. chkfseek(infiles[filenum],
  265. spigots[filenum].header_len + bytes_per_read*firstspec,
  266. SEEK_SET);
  267. /* Loop over the samples in the file */
  268. while ((numwritten < cmd->numout) &&
  269. (chkfread(rawlags, bytes_per_read, 1, infiles[filenum]))) {
  270. if (cmd->zerolagsP) {
  271. /* Correct the lags so we can write the zerolag */
  272. get_calibrated_lags(rawlags, lags);
  273. chkfwrite(lags, sizeof(float), 1, zerolagfile);
  274. }
  275. if (scaling) {
  276. convert_SPIGOT_point(rawlags, output_samples, SUMIFS,
  277. scalings[cmd->skip+numconverted]);
  278. } else {
  279. convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0);
  280. }
  281. /* If downsampling, average the current spectra */
  282. if (cmd->downsamp > 1) {
  283. int ii;
  284. if (numconverted % cmd->downsamp == 0) {
  285. write_data = 0;
  286. /* Zero the array used for averaging */
  287. for (ii = 0; ii < outnumlags; ii++)
  288. tmp_floats[ii] = 0.0;
  289. } else {
  290. /* Add the current data to the array used for averaging */
  291. for (ii = 0; ii < outnumlags; ii++)
  292. tmp_floats[ii] += (float) output_samples[ii+cmd->lokill];
  293. /* If that was the last sample to be added, average them */
  294. /* and put them back into output_samples */
  295. if (numconverted % cmd->downsamp == (cmd->downsamp-1)) {
  296. write_data = 1;
  297. for (ii = 0; ii < outnumlags; ii++) {
  298. tmp_floats[ii] /= (float) cmd->downsamp;
  299. output_samples[ii+cmd->lokill] = \
  300. (unsigned char)(tmp_floats[ii]+0.5);
  301. }
  302. }
  303. }
  304. }
  305. numconverted++;
  306. if (write_data) {
  307. int ii;
  308. /* Invert the band so that the high freqs are first */
  309. /* This is how SIGPROC stores its data. */
  310. if (cmd->floatsP) {
  311. float tempzz = 0.0, *loptr, *hiptr;
  312. loptr = tmp_floats; // killed channels are already gone
  313. hiptr = tmp_floats + outnumlags - 1;
  314. for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) {
  315. SWAP(*loptr, *hiptr);
  316. }
  317. } else {
  318. unsigned char tempzz = 0.0, *loptr, *hiptr;
  319. loptr = output_samples + cmd->lokill;
  320. hiptr = output_samples + cmd->lokill + outnumlags - 1;
  321. for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) {
  322. SWAP(*loptr, *hiptr);
  323. }
  324. }
  325. /* Now actually write the data */
  326. if (cmd->floatsP) {
  327. /* Copy the bytes to floats */
  328. for (ii = 0; ii < outnumlags; ii++)
  329. tmp_floats[ii] = (float) output_samples[ii+cmd->lokill];
  330. chkfwrite(tmp_floats, sizeof(float), fb.nchans, outfile);
  331. } else {
  332. chkfwrite(output_samples+cmd->lokill,
  333. sizeof(unsigned char), fb.nchans, outfile);
  334. }
  335. numwritten++;
  336. }
  337. }
  338. if ((!cmd->stdoutP) && (!cmd->outfileP))
  339. fclose(outfile);
  340. fclose(infiles[filenum]);
  341. firstspec = 0;
  342. filenum++;
  343. free(path);
  344. free(filenm);
  345. }
  346. if ((!cmd->stdoutP) && (cmd->outfileP))
  347. fclose(outfile);
  348. if (cmd->zerolagsP)
  349. fclose(zerolagfile);
  350. if (!cmd->stdoutP)
  351. fprintf(stderr, "Converted %lld samples and wrote %lld.\n\n",
  352. numconverted, numwritten);
  353. if (scaling)
  354. vect_free(scalings);
  355. free(spigots);
  356. free(infiles);
  357. return 0;
  358. }