int main(int argc, char *argv[]) { /* Cmd line */ static struct option long_opts[] = { {"output", 1, NULL, 'o'}, {"npulse", 1, NULL, 'n'}, {"nbin", 1, NULL, 'b'}, {"nthread", 1, NULL, 'j'}, {"initial", 1, NULL, 'i'}, {"final", 1, NULL, 'f'}, {"time", 1, NULL, 'T'}, {"length", 1, NULL, 'L'}, {"src", 1, NULL, 's'}, {"polyco", 1, NULL, 'p'}, {"parfile", 1, NULL, 'P'}, {"foldfreq",1, NULL, 'F'}, {"cal", 0, NULL, 'C'}, {"unsigned",0, NULL, 'u'}, {"quiet", 0, NULL, 'q'}, {"help", 0, NULL, 'h'}, {0,0,0,0} }; int opt, opti; int nbin=256, nthread=4, fnum_start=1, fnum_end=0; int quiet=0, raw_signed=1, use_polycos=1, cal=0; int npulse_per_file = 64; double start_time=0.0, process_time=0.0; double fold_frequency=0.0; char output_base[256] = ""; char polyco_file[256] = ""; char par_file[256] = ""; char source[24]; source[0]='\0'; while ((opt=getopt_long(argc,argv,"o:n:b:j:i:f:T:L:s:p:P:F:Cuqh",long_opts,&opti))!=-1) { switch (opt) { case 'o': strncpy(output_base, optarg, 255); output_base[255]='\0'; break; case 'n': npulse_per_file = atoi(optarg); break; case 'b': nbin = atoi(optarg); break; case 'j': nthread = atoi(optarg); break; case 'i': fnum_start = atoi(optarg); break; case 'f': fnum_end = atoi(optarg); break; case 'T': start_time = atof(optarg); break; case 'L': process_time = atof(optarg); break; case 's': strncpy(source, optarg, 24); source[23]='\0'; break; case 'p': strncpy(polyco_file, optarg, 255); polyco_file[255]='\0'; use_polycos = 1; break; case 'P': strncpy(par_file, optarg, 255); par_file[255] = '\0'; break; case 'F': fold_frequency = atof(optarg); use_polycos = 0; break; case 'C': cal = 1; use_polycos = 0; break; case 'u': raw_signed=0; break; case 'q': quiet=1; break; case 'h': default: usage(); exit(0); break; } } if (optind==argc) { usage(); exit(1); } /* If no polyco/par file given, default to polyco.dat */ if (use_polycos && (par_file[0]=='\0' && polyco_file[0]=='\0')) sprintf(polyco_file, "polyco.dat"); /* Open first file */ struct psrfits pf; strcpy(pf.basefilename, argv[optind]); pf.filenum = fnum_start; pf.tot_rows = pf.N = pf.T = pf.status = 0; pf.hdr.chan_dm = 0.0; // What if folding data that has been partially de-dispersed? pf.filename[0]='\0'; int rv = psrfits_open(&pf); if (rv) { fits_report_error(stderr, rv); exit(1); } /* Check any constraints */ if (pf.hdr.nbits!=8) { fprintf(stderr, "Only implemented for 8-bit data (read nbits=%d).\n", pf.hdr.nbits); exit(1); } /* Check for calfreq */ if (cal) { if (pf.hdr.cal_freq==0.0) { if (fold_frequency==0.0) { fprintf(stderr, "Error: Cal mode selected, but CAL_FREQ=0. " "Set cal frequency with -F\n"); exit(1); } else { pf.hdr.cal_freq = fold_frequency; } } else { fold_frequency = pf.hdr.cal_freq; } } /* Set up output file */ struct psrfits pf_out; memcpy(&pf_out, &pf, sizeof(struct psrfits)); if (source[0]!='\0') { strncpy(pf_out.hdr.source, source, 24); } else { strncpy(source, pf.hdr.source, 24); source[23]='\0'; } if (output_base[0]=='\0') { /* Set up default output filename */ if (start_time>0.0) sprintf(output_base, "%s_SP_%s_%5.5d_%5.5d_%4.4d_%3.3d%s", pf_out.hdr.backend, pf_out.hdr.source, pf_out.hdr.start_day, (int)pf_out.hdr.start_sec, fnum_start, (int)start_time, cal ? "_cal" : ""); else sprintf(output_base, "%s_SP_%s_%5.5d_%5.5d%s", pf_out.hdr.backend, pf_out.hdr.source, pf_out.hdr.start_day, (int)pf_out.hdr.start_sec, cal ? "_cal" : ""); } strcpy(pf_out.basefilename, output_base); if (cal) { sprintf(pf_out.hdr.obs_mode, "CAL"); sprintf(pf_out.hdr.cal_mode, "SYNC"); } else sprintf(pf_out.hdr.obs_mode, "PSR"); strncpy(pf_out.fold.parfile,par_file,255); pf_out.fold.parfile[255]='\0'; pf_out.fptr = NULL; pf_out.filenum=0; pf_out.status=0; pf_out.hdr.nbin=nbin; pf_out.sub.FITS_typecode = TFLOAT; pf_out.sub.bytes_per_subint = sizeof(float) * pf_out.hdr.nchan * pf_out.hdr.npol * pf_out.hdr.nbin; pf_out.multifile = 1; pf_out.quiet = 1; pf_out.rows_per_file = npulse_per_file; rv = psrfits_create(&pf_out); if (rv) { fits_report_error(stderr, rv); exit(1); } /* Alloc data buffers */ pf.sub.dat_freqs = (float *)malloc(sizeof(float) * pf.hdr.nchan); pf_out.sub.dat_freqs = pf.sub.dat_freqs; pf.sub.dat_weights = (float *)malloc(sizeof(float) * pf.hdr.nchan); pf_out.sub.dat_weights = (float *)malloc(sizeof(float) * pf.hdr.nchan); pf.sub.dat_offsets = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf_out.sub.dat_offsets = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf.sub.dat_scales = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf_out.sub.dat_scales = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf_out.sub.data = (unsigned char *)malloc(pf_out.sub.bytes_per_subint); /* Output scale/offset */ int i, j, ipol, ichan; float offset_uv=0.0; // Extra cross-term offset for GUPPI if (strcmp("GUPPI",pf.hdr.backend)==0) { offset_uv=0.5; fprintf(stderr, "Found backend=GUPPI, setting offset_uv=%f\n", offset_uv); } // TODO: copy these from the input file for (ipol=0; ipol<pf.hdr.npol; ipol++) { for (ichan=0; ichan<pf.hdr.nchan; ichan++) { float offs = 0.0; if (ipol>1) offs = offset_uv; pf_out.sub.dat_scales[ipol*pf.hdr.nchan + ichan] = 1.0; pf_out.sub.dat_offsets[ipol*pf.hdr.nchan + ichan] = offs; } } for (i=0; i<pf.hdr.nchan; i++) { pf_out.sub.dat_weights[i]=1.0; } /* Read or make polycos */ int npc=0, ipc=0; struct polyco *pc = NULL; if (use_polycos) { if (polyco_file[0]=='\0') { /* Generate from par file */ npc = make_polycos(par_file, &pf.hdr, source, &pc); if (npc<=0) { fprintf(stderr, "Error generating polycos.\n"); exit(1); } printf("Auto-generated %d polycos, src=%s\n", npc, source); } else { /* Read from polyco file */ FILE *pcfile = fopen(polyco_file, "r"); if (pcfile==NULL) { fprintf(stderr, "Couldn't open polyco file.\n"); exit(1); } npc = read_all_pc(pcfile, &pc); if (npc==0) { fprintf(stderr, "Error parsing polyco file.\n"); exit(1); } fclose(pcfile); } } else { // Const fold period mode, generate a fake polyco? pc = (struct polyco *)malloc(sizeof(struct polyco)); sprintf(pc[0].psr, "CONST"); pc[0].mjd = (int)pf.hdr.MJD_epoch; pc[0].fmjd = fmod(pf.hdr.MJD_epoch,1.0); pc[0].rphase = 0.0; pc[0].f0 = fold_frequency; pc[0].nsite = 0; // Does this matter? pc[0].nmin = 24 * 60; pc[0].nc = 1; pc[0].rf = pf.hdr.fctr; pc[0].c[0] = 0.0; pc[0].used = 0; npc = 1; } int *pc_written = (int *)malloc(sizeof(int) * npc); for (i=0; i<npc; i++) pc_written[i]=0; /* Set up fold buf */ struct foldbuf fb; fb.nchan = pf.hdr.nchan; fb.npol = pf.hdr.npol; fb.nbin = pf_out.hdr.nbin; malloc_foldbuf(&fb); clear_foldbuf(&fb); struct fold_args fargs; fargs.data = (char *)malloc(sizeof(char)*pf.sub.bytes_per_subint); fargs.fb = &fb; fargs.nsamp = 1; fargs.tsamp = pf.hdr.dt; fargs.raw_signed = raw_signed; /* Main loop */ rv=0; int imjd; double fmjd, fmjd0=0, fmjd_samp, fmjd_epoch; long long cur_pulse=0, last_pulse=0; double psr_freq=0.0; int first_loop=1, first_data=1, sampcount=0, last_filenum=0; int bytes_per_sample = pf.hdr.nchan * pf.hdr.npol; signal(SIGINT, cc); while (run) { /* Read data block */ pf.sub.data = (unsigned char *)fargs.data; rv = psrfits_read_subint(&pf); if (rv) { if (rv==FILE_NOT_OPENED) rv=0; // Don't complain on file not found run=0; break; } /* If we've passed final file, exit */ if (fnum_end && pf.filenum>fnum_end) { run=0; break; } /* Get start date, etc */ imjd = (int)pf.hdr.MJD_epoch; fmjd = (double)(pf.hdr.MJD_epoch - (long double)imjd); fmjd += (pf.sub.offs-0.5*pf.sub.tsubint)/86400.0; /* Select polyco set. * We'll assume same one is valid for whole data block. */ if (use_polycos) { ipc = select_pc(pc, npc, source, imjd, fmjd); //ipc = select_pc(pc, npc, NULL, imjd, fmjd); if (ipc<0) { fprintf(stderr, "No matching polycos (src=%s, imjd=%d, fmjd=%f)\n", source, imjd, fmjd); break; } } else { ipc = 0; } pc[ipc].used = 1; // Mark this polyco set as used for folding /* First time stuff */ if (first_loop) { fmjd0 = fmjd; psr_phase(&pc[ipc], imjd, fmjd, NULL, &last_pulse); pf_out.sub.offs=0.0; first_loop=0; for (i=0; i<pf.hdr.nchan; i++) { pf_out.sub.dat_weights[i]=pf.sub.dat_weights[i]; } last_filenum = pf_out.filenum; } /* Check to see if its time to process data */ if (start_time>0.0) { double cur_time = (fmjd - fmjd0) * 86400.0; if (cur_time<start_time) continue; } if (first_data) { psr_phase(&pc[ipc], imjd, fmjd, NULL, &last_pulse); first_data=0; } /* Check to see if we're done */ if (process_time>0.0) { double cur_time = (fmjd - fmjd0) * 86400.0; if (cur_time > start_time + process_time) { run=0; break; } } /* for singlepulse: loop over samples, output a new subint * whenever pulse number increases. */ for (i=0; i<pf.hdr.nsblk; i++) { /* Keep track of timestamp */ // TODO also pointing stuff? fmjd_samp = fmjd + i*pf.hdr.dt/86400.0; pf_out.sub.offs += pf.sub.offs - 0.5*pf.sub.tsubint + i*pf.hdr.dt; sampcount++; /* Calc current pulse number */ psr_phase(&pc[ipc], imjd, fmjd_samp, &psr_freq, &cur_pulse); /* TODO: deal with scale/offset? */ /* Fold this sample */ fargs.pc = &pc[ipc]; fargs.imjd = imjd; fargs.fmjd = fmjd_samp; rv = fold_8bit_power(fargs.pc, fargs.imjd, fargs.fmjd, fargs.data + i*bytes_per_sample, fargs.nsamp, fargs.tsamp, fargs.raw_signed, fargs.fb); if (rv!=0) { fprintf(stderr, "Fold error.\n"); exit(1); } /* See if integration needs to be written, etc */ if (cur_pulse > last_pulse) { /* Figure out timestamp */ pf_out.sub.offs /= (double)sampcount; pf_out.sub.tsubint = 1.0/psr_freq; fmjd_epoch = fmjd0 + pf_out.sub.offs/86400.0; /* Transpose, output subint */ normalize_transpose_folds((float *)pf_out.sub.data, &fb); psrfits_write_subint(&pf_out); /* If file incremented, clear polyco flags */ if (pf_out.filenum > last_filenum) for (j=0; j<npc; j++) pc_written[j]=0; /* Write this polyco if needed */ if (pc_written[ipc]==0) { psrfits_write_polycos(&pf_out, pc, npc); pc_written[ipc] = 1; } /* Check for write errors */ if (pf_out.status) { fprintf(stderr, "Error writing subint.\n"); fits_report_error(stderr, pf_out.status); exit(1); } /* Clear counters, avgs */ clear_foldbuf(&fb); pf_out.sub.offs = 0.0; sampcount=0; last_pulse = cur_pulse; last_filenum = pf_out.filenum; } } /* Progress report */ if (!quiet) { printf("\rFile %d %5.1f%%", pf.filenum, 100.0 * (float)(pf.rownum-1)/(float)pf.rows_per_file); fflush(stdout); } } psrfits_close(&pf_out); psrfits_close(&pf); if (rv) { fits_report_error(stderr, rv); } exit(0); }
Boolean handle_menu (short item, HMENU) { short choice,i; POINT x = {1001,0},pass_point; Boolean to_return = false; switch (item) { case 1: // File Menu if (in_startup_mode == true) startup_load(); else do_load(); break; case 2: do_save(0); break; case 3: if (in_startup_mode == true) save_file(1); else do_save(1); break; case 4: if (in_startup_mode == false) { choice = FCD(1091,0); if (choice == 1) return false; for (i = 0; i < 6; i++) adven[i].main_status = MAIN_STATUS_ABSENT; party_in_memory = false; reload_startup(); in_startup_mode = true; draw_startup(0); } start_new_game(); draw_startup(0); break; case 6: pick_preferences(); break; case 7: pick_compatibility(); break; case 8: // Quit if (in_startup_mode == true) { to_return = All_Done = true; break; } if (overall_mode > MODE_TOWN) { choice = FCD(1067,0); if (choice == 1) return All_Done; } else { choice = FCD(1066,0); if (choice == 3) break; if (choice == 1) save_file(0); } to_return = All_Done = true; break; // Options menu case 21: choice = char_select_pc(0,0,"New graphic for who?"); if (choice < 6) pick_pc_graphic(choice,1,0); initiate_redraw(); break; case 22: choice = select_pc(0,0); if (choice < 6) pick_pc_name(choice,0); put_pc_screen(); put_item_screen(stat_window,0); break; case 23: if (!(is_town())) { add_string_to_buf("Add PC: Town mode only."); print_buf(); break; } for (i = 0; i < NUM_OF_PCS; i++) if (adven[i].main_status == MAIN_STATUS_ABSENT) i = 20; if (i == INVALID_PC) { ASB("Add PC: You already have 6 PCs."); print_buf(); } if (c_town.town_num == scenario.which_town_start) { give_help(56,0,0); create_pc(6,0); } else { add_string_to_buf("Add PC: You can only make new"); add_string_to_buf(" characters in the town you "); add_string_to_buf(" started in."); } print_buf(); put_pc_screen(); put_item_screen(stat_window,0); break; case 24: if (prime_time() == false) { ASB("Finish what you're doing first."); print_buf(); } else { choice = char_select_pc(0,0,"Delete who?"); if (choice < 6) { if ((i = FCD(1053,0)) == 2) adven[choice].kill(0); } initiate_redraw(); } break; case 27: if (overall_mode == MODE_TALKING) { ASB("Talking notes: Can't read while talking."); print_buf(); return to_return; } talk_notes(); break; case 28: adventure_notes(); break; case 29: if (in_startup_mode == false) print_party_stats(); break; // Help menu case 41: FCD(1079,0); break; case 42: FCD(1080,0); break; case 43: FCD(1081,0); break; case 44: FCD(1072,0); break; // magic barriers case 46: FCD(1084,0); break; case 47: FCD(1088,0); break; // Library case 61: display_spells(0,100,0); break; case 62: display_spells(1,100,0); break; case 63: display_skills(100,0); break; case 64: display_help(0,0); break; case 65: tip_of_day(); break; case 67: FCD(986,0); break; // Actions case 81: if (overall_mode != MODE_TOWN) { ASB("Alchemy: In town mode only."); print_buf(); break; } pass_point.x = 1000; pass_point.y = 405; to_return = handle_action(pass_point,(WPARAM) 0,(LPARAM)-1); break; case 82: to_return = handle_action(x,(WPARAM) 0,(LPARAM)-1); break; case 84: if (prime_time() == false) { ASB("Finish what you're doing first."); print_buf(); } else { give_help(62,0,0); display_map(); } SetCursor(sword_curs); break; // Mage is 399 case 399: give_help(209,0,0); party.help_received[9] = false; break; // Priest is 499 case 499: give_help(209,0,0); party.help_received[9] = false; break; // Monsters is 599 case 599: give_help(212,0,0); break; case 100: // Index WinHelp(mainPtr,"Blades of Exile.hlp",HELP_CONTENTS,0L); break; case 200: // About FCD(1062,0); break; default: if ((item >= 400) && (item < 500)) { // mage spell if (prime_time() == false) { ASB("Finish what you're doing first."); print_buf(); } else handle_menu_spell(item - 400,0); break; } if ((item >= 500) && (item < 600)) { // priest spell if (prime_time() == false) { ASB("Finish what you're doing first."); print_buf(); } else handle_menu_spell(item - 500,1); break; } if ((item >= 600) && (item < 700)) { // monster spell display_monst(item - 600,(creature_data_type *) NULL,1); break; } break; } if (in_startup_mode == true) menu_activate(0); else menu_activate(1); return to_return; }
int main(int argc, char *argv[]) { /* Cmd line */ static struct option long_opts[] = { {"output", 1, NULL, 'o'}, {"nbin", 1, NULL, 'b'}, {"tsub", 1, NULL, 't'}, {"nthread", 1, NULL, 'j'}, {"initial", 1, NULL, 'i'}, {"final", 1, NULL, 'f'}, {"src", 1, NULL, 's'}, {"polyco", 1, NULL, 'p'}, {"parfile", 1, NULL, 'P'}, {"foldfreq",1, NULL, 'F'}, {"cal", 0, NULL, 'C'}, {"unsigned",0, NULL, 'u'}, {"nunsigned",1, NULL, 'U'}, {"split", 1, NULL, 'S'}, {"apply", 0, NULL, 'A'}, {"quiet", 0, NULL, 'q'}, {"help", 0, NULL, 'h'}, {0,0,0,0} }; int opt, opti; int nbin=256, nthread=4, fnum_start=1, fnum_end=0; int quiet=0, raw_signed=1, use_polycos=1, cal=0, apply_scale=0; double split_size_gb = 1.0; double tfold = 60.0; double fold_frequency=0.0; char output_base[256] = ""; char polyco_file[256] = ""; char par_file[256] = ""; char source[24]; source[0]='\0'; while ((opt=getopt_long(argc,argv,"o:b:t:j:i:f:s:p:P:F:CuU:S:Aqh",long_opts,&opti))!=-1) { switch (opt) { case 'o': strncpy(output_base, optarg, 255); output_base[255]='\0'; break; case 'b': nbin = atoi(optarg); break; case 't': tfold = atof(optarg); break; case 'j': nthread = atoi(optarg); break; case 'i': fnum_start = atoi(optarg); break; case 'f': fnum_end = atoi(optarg); break; case 's': strncpy(source, optarg, 24); source[23]='\0'; break; case 'p': strncpy(polyco_file, optarg, 255); polyco_file[255]='\0'; use_polycos = 1; break; case 'P': strncpy(par_file, optarg, 255); par_file[255] = '\0'; break; case 'F': fold_frequency = atof(optarg); use_polycos = 0; break; case 'C': cal = 1; use_polycos = 0; break; case 'u': raw_signed=0; break; case 'U': raw_signed = 4 - atoi(optarg); break; case 'S': split_size_gb = atof(optarg); break; case 'A': apply_scale = 1; break; case 'q': quiet=1; break; case 'h': default: usage(); exit(0); break; } } if (optind==argc) { usage(); exit(1); } /* If no polyco/par file given, default to polyco.dat */ if (use_polycos && (par_file[0]=='\0' && polyco_file[0]=='\0')) sprintf(polyco_file, "polyco.dat"); /* Open first file */ struct psrfits pf; sprintf(pf.basefilename, argv[optind]); pf.filenum = fnum_start; pf.tot_rows = pf.N = pf.T = pf.status = 0; pf.hdr.chan_dm = 0.0; // What if folding data that has been partially de-dispersed? pf.filename[0]='\0'; int rv = psrfits_open(&pf); if (rv) { fits_report_error(stderr, rv); exit(1); } /* Check any constraints */ if (pf.hdr.nbits!=8) { fprintf(stderr, "Only implemented for 8-bit data (read nbits=%d).\n", pf.hdr.nbits); exit(1); } /* Check for calfreq */ if (cal) { if (pf.hdr.cal_freq==0.0) { if (fold_frequency==0.0) { fprintf(stderr, "Error: Cal mode selected, but CAL_FREQ=0. " "Set cal frequency with -F\n"); exit(1); } else { pf.hdr.cal_freq = fold_frequency; } } else { fold_frequency = pf.hdr.cal_freq; } } /* Set up output file */ struct psrfits pf_out; memcpy(&pf_out, &pf, sizeof(struct psrfits)); if (source[0]!='\0') { strncpy(pf_out.hdr.source, source, 24); } else { strncpy(source, pf.hdr.source, 24); source[23]='\0'; } if (output_base[0]=='\0') { /* Set up default output filename */ sprintf(output_base, "%s_%s_%5.5d_%5.5d%s", pf_out.hdr.backend, pf_out.hdr.source, pf_out.hdr.start_day, (int)pf_out.hdr.start_sec, cal ? "_cal" : ""); } sprintf(pf_out.basefilename, output_base); if (cal) { sprintf(pf_out.hdr.obs_mode, "CAL"); sprintf(pf_out.hdr.cal_mode, "SYNC"); } else sprintf(pf_out.hdr.obs_mode, "PSR"); strncpy(pf_out.fold.parfile,par_file,255); pf_out.fold.parfile[255]='\0'; pf_out.fptr = NULL; pf_out.filenum=0; pf_out.status=0; pf_out.quiet=0; pf_out.hdr.nbin=nbin; pf_out.sub.FITS_typecode = TFLOAT; pf_out.sub.bytes_per_subint = sizeof(float) * pf_out.hdr.nchan * pf_out.hdr.npol * pf_out.hdr.nbin; if (split_size_gb > 0.0) { pf_out.multifile = 1; pf_out.rows_per_file = (int) (split_size_gb * (1024.0*1024.0*1024.0) / (double)pf_out.sub.bytes_per_subint); printf("Writing a maximum of %d subintegrations (~%.1f GB) per output file.\n", pf_out.rows_per_file, split_size_gb); } else { pf_out.multifile = 0; printf("Writing a single output file.\n"); } rv = psrfits_create(&pf_out); if (rv) { fits_report_error(stderr, rv); exit(1); } /* Alloc data buffers */ pf.sub.dat_freqs = (float *)malloc(sizeof(float) * pf.hdr.nchan); pf_out.sub.dat_freqs = pf.sub.dat_freqs; pf.sub.dat_weights = (float *)malloc(sizeof(float) * pf.hdr.nchan); pf_out.sub.dat_weights = (float *)malloc(sizeof(float) * pf.hdr.nchan); pf.sub.dat_offsets = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf_out.sub.dat_offsets = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf.sub.dat_scales = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf_out.sub.dat_scales = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); pf_out.sub.data = (unsigned char *)malloc(pf_out.sub.bytes_per_subint); /* Output scale/offset */ int i, ipol, ichan; float offset_uv=0.0; // Extra cross-term offset for GUPPI if (strcmp("GUPPI",pf.hdr.backend)==0 && apply_scale==0) { offset_uv=0.5; fprintf(stderr, "Found backend=GUPPI, setting offset_uv=%f\n", offset_uv); } // Initialize scale/output and weights. // These get copied from the input file later during the main loop. for (ipol=0; ipol<pf.hdr.npol; ipol++) { for (ichan=0; ichan<pf.hdr.nchan; ichan++) { float offs = 0.0; if (ipol>1) offs = offset_uv; pf_out.sub.dat_scales[ipol*pf.hdr.nchan + ichan] = 1.0; pf_out.sub.dat_offsets[ipol*pf.hdr.nchan + ichan] = offs; } } for (i=0; i<pf.hdr.nchan; i++) { pf_out.sub.dat_weights[i]=1.0; } /* Read or make polycos */ int npc=0, ipc=0; struct polyco *pc = NULL; if (use_polycos) { if (polyco_file[0]=='\0') { /* Generate from par file */ npc = make_polycos(par_file, &pf.hdr, source, &pc); if (npc<=0) { fprintf(stderr, "Error generating polycos.\n"); exit(1); } printf("Auto-generated %d polycos, src=%s\n", npc, source); } else { /* Read from polyco file */ FILE *pcfile = fopen(polyco_file, "r"); if (pcfile==NULL) { fprintf(stderr, "Couldn't open polyco file.\n"); exit(1); } npc = read_all_pc(pcfile, &pc); if (npc==0) { fprintf(stderr, "Error parsing polyco file.\n"); exit(1); } fclose(pcfile); } } else { // Const fold period mode, generate a fake polyco? pc = (struct polyco *)malloc(sizeof(struct polyco)); sprintf(pc[0].psr, "CONST"); pc[0].mjd = (int)pf.hdr.MJD_epoch; pc[0].fmjd = fmod(pf.hdr.MJD_epoch,1.0); pc[0].rphase = 0.0; pc[0].f0 = fold_frequency; pc[0].nsite = 0; // Does this matter? pc[0].nmin = 24 * 60; pc[0].nc = 1; pc[0].rf = pf.hdr.fctr; pc[0].c[0] = 0.0; pc[0].used = 0; npc = 1; } int *pc_written = (int *)malloc(sizeof(int) * npc); for (i=0; i<npc; i++) pc_written[i]=0; /* Alloc total fold buf */ struct foldbuf fb; fb.nchan = pf.hdr.nchan; fb.npol = pf.hdr.npol; fb.nbin = pf_out.hdr.nbin; malloc_foldbuf(&fb); clear_foldbuf(&fb); /* Set up thread management */ pthread_t *thread_id; struct fold_args *fargs; thread_id = (pthread_t *)malloc(sizeof(pthread_t) * nthread); fargs = (struct fold_args *)malloc(sizeof(struct fold_args) * nthread); for (i=0; i<nthread; i++) { thread_id[i] = 0; fargs[i].data = (char *)malloc(sizeof(char)*pf.sub.bytes_per_subint); fargs[i].fb = (struct foldbuf *)malloc(sizeof(struct foldbuf)); fargs[i].fb->nbin = pf_out.hdr.nbin; fargs[i].fb->nchan = pf.hdr.nchan; fargs[i].fb->npol = pf.hdr.npol; fargs[i].nsamp = pf.hdr.nsblk; fargs[i].tsamp = pf.hdr.dt; fargs[i].raw_signed=raw_signed; malloc_foldbuf(fargs[i].fb); clear_foldbuf(fargs[i].fb); fargs[i].scale = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); fargs[i].offset = (float *)malloc(sizeof(float) * pf.hdr.nchan * pf.hdr.npol); } /* Main loop */ rv=0; int imjd; double fmjd, fmjd0=0, fmjd_next=0, fmjd_epoch; double offs0=0, offs1=0; //double phase=0.0, freq=1.0; int first=1, subcount=0; int cur_thread = 0; signal(SIGINT, cc); while (run) { /* Read data block */ pf.sub.data = (unsigned char *)fargs[cur_thread].data; rv = psrfits_read_subint(&pf); if (rv) { if (rv==FILE_NOT_OPENED) rv=0; // Don't complain on file not found run=0; break; } /* If we've passed final file, exit */ if (fnum_end && pf.filenum>fnum_end) { run=0; break; } /* Get start date, etc */ imjd = (int)pf.hdr.MJD_epoch; fmjd = (double)(pf.hdr.MJD_epoch - (long double)imjd); fmjd += (pf.sub.offs-0.5*pf.sub.tsubint)/86400.0; /* First time stuff */ if (first) { fmjd0 = fmjd; fmjd_next = fmjd + tfold/86400.0; pf_out.sub.offs=0.0; offs0 = pf.sub.offs - 0.5*pf.sub.tsubint; offs1 = pf.sub.offs + 0.5*pf.sub.tsubint; first=0; for (i=0; i<pf.hdr.nchan; i++) { pf_out.sub.dat_weights[i]=pf.sub.dat_weights[i]; } } /* Keep track of timestamp */ // TODO also pointing stuff. pf_out.sub.offs += pf.sub.offs; subcount++; /* Update output block end time */ offs1 = pf.sub.offs + 0.5*pf.sub.tsubint; /* Select polyco set */ if (use_polycos) { ipc = select_pc(pc, npc, source, imjd, fmjd); //ipc = select_pc(pc, npc, NULL, imjd, fmjd); if (ipc<0) { fprintf(stderr, "No matching polycos (src=%s, imjd=%d, fmjd=%f)\n", source, imjd, fmjd); break; } } else { ipc = 0; } pc[ipc].used = 1; // Mark this polyco set as used for folding /* Copy scale/offset from input to output if we're not applying it */ if (apply_scale==0) { for (i=0; i<pf.hdr.nchan*pf.hdr.npol; i++) { pf_out.sub.dat_scales[i] = pf.sub.dat_scales[i]; pf_out.sub.dat_offsets[i] = pf.sub.dat_offsets[i]; } } /* Fold this subint */ fargs[cur_thread].pc = &pc[ipc]; fargs[cur_thread].imjd = imjd; fargs[cur_thread].fmjd = fmjd; rv = pthread_create(&thread_id[cur_thread], NULL, fold_8bit_power_thread, &fargs[cur_thread]); if (rv) { fprintf(stderr, "Thread creation error.\n"); exit(1); } if (apply_scale) { for (i=0; i<pf.hdr.nchan*pf.hdr.npol; i++) { fargs[cur_thread].scale[i] = pf.sub.dat_scales[i]; fargs[cur_thread].offset[i] = pf.sub.dat_offsets[i]; } } cur_thread++; /* Combine thread results if needed */ if (cur_thread==nthread || fmjd>fmjd_next) { /* Loop over active threads */ for (i=0; i<cur_thread; i++) { /* Wait for thread to finish */ rv = pthread_join(thread_id[i], NULL); if (rv) { fprintf(stderr, "Thread join error.\n"); exit(1); } /* Apply scale and offset here */ if (apply_scale) scale_offset_folds(fargs[i].fb, fargs[i].scale, fargs[i].offset); /* Combine its result into total fold */ accumulate_folds(&fb, fargs[i].fb); /* Reset thread info */ clear_foldbuf(fargs[i].fb); thread_id[i] = 0; } /* Reset active thread count */ cur_thread = 0; } /* See if integration needs to be written, etc */ if (fmjd > fmjd_next) { /* Figure out timestamp */ pf_out.sub.offs /= (double)subcount; pf_out.sub.tsubint = offs1 - offs0; fmjd_epoch = fmjd0 + pf_out.sub.offs/86400.0; /* // Don't need this stuff if we set EPOCHS=MIDTIME ipc = select_pc(pc, npc, pf.hdr.source, imjd, fmjd_epoch); if (ipc<0) { fprintf(stderr, "Polyco error, exiting.\n"); exit(1); } phase = psr_phase(&pc[ipc], imjd, fmjd_epoch, &freq); phase = fmod(phase, 1.0); pf_out.sub.offs -= phase/freq; // ref epoch needs 0 phase */ /* Transpose, output subint */ normalize_transpose_folds((float *)pf_out.sub.data, &fb); int last_filenum = pf_out.filenum; psrfits_write_subint(&pf_out); /* Check for write errors */ if (pf_out.status) { fprintf(stderr, "Error writing subint.\n"); fits_report_error(stderr, pf_out.status); exit(1); } /* Check if we started a new file */ if (pf_out.filenum!=last_filenum) { /* No polycos yet written to this file */ for (i=0; i<npc; i++) pc_written[i]=0; } /* Write the current polyco if needed */ if (pc_written[ipc]==0) { psrfits_write_polycos(&pf_out, &pc[ipc], 1); if (pf_out.status) { fprintf(stderr, "Error writing polycos.\n"); fits_report_error(stderr, pf_out.status); exit(1); } pc_written[ipc] = 1; } /* Clear counters, avgs */ clear_foldbuf(&fb); pf_out.sub.offs = 0.0; offs0 = pf.sub.offs - 0.5*pf.sub.tsubint; subcount=0; /* Set next output time */ fmjd_next = fmjd + tfold/86400.0; } /* Progress report */ if (!quiet) { printf("\rFile %d %5.1f%%", pf.filenum, 100.0 * (float)(pf.rownum-1)/(float)pf.rows_per_file); fflush(stdout); } } /* Join any running threads */ for (i=0; i<cur_thread; i++) if (thread_id[i]) pthread_join(thread_id[i], NULL); /* Remove polyco table in cal mode */ if (cal) { rv = psrfits_remove_polycos(&pf_out); if (rv) { fits_report_error(stderr, rv); } } psrfits_close(&pf_out); psrfits_close(&pf); if (rv) { fits_report_error(stderr, rv); } exit(0); }