// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I #include #include // private void phiex_position::_normalise(void) { while (_datum < 0) { _line--; _datum += 400; } while (_datum > 399) { _line++; _datum -= 400; } } void phiex_position::operator+=(const int data) { _datum += data; _normalise(); } phiex_position phiex_position::operator+(const int data) { phiex_position rv = *this; rv += data; return rv; } void phiex_position::operator+=(const phiex_position& pos) { _datum += pos._datum; _line += pos._line; _normalise(); } phiex_position phiex_position::operator+(const phiex_position& pos) { phiex_position rv = *this; rv += pos; return rv; } void phiex_position::operator-=(const phiex_position& pos) { _datum -= pos._datum; _line -= pos._line; _normalise(); } phiex_position phiex_position::operator-(const phiex_position& pos) { phiex_position rv = *this; rv -= pos; return rv; } // constructor phiex_frame::phiex_frame(void): _data(800, 800) { heap_check(_line = new octet [800]); heap_check(_data_pair = new octet [2]); heap_check(_header = new octet [1280]); } // constructor from file phiex_frame::phiex_frame(char* filename) : _data(800, 800) { heap_check(_line = new octet [800]); heap_check(_data_pair = new octet [2]); heap_check(_header = new octet [1280]); read(filename); } // destructor phiex_frame::~phiex_frame(void) { destroy_array(_header); destroy_array(_line); destroy_array(_data_pair); } // copy constructor phiex_frame::phiex_frame(const phiex_frame& f) : _data(800, 800) { heap_check(_header = new octet [1280]); for (int octet_nr = 0; octet_nr < 1280; octet_nr++) _header[octet_nr] = f._header[octet_nr]; heap_check(_line = new octet [800]); heap_check(_data_pair = new octet [2]); _data = f._data; } // return a line of data octet* phiex_frame::line(const int line_nr) { for (int n = 0; n < 800; n++) _line[n] = _data.element(line_nr, n); return _line; } // return a pointer to a pair of data octet* phiex_frame::data_pair(const int ln, const int dn) { for (int n = 0; n < 2; n++) _data_pair[n] = _data.element(ln, (2 * dn) + n); return _data_pair; } // 0 <= l < 800; 0 <= d < 400; 1 <= c < 3 uint16 phiex_frame::datum(const int l, const int d, const int c) { /* octet* temp = data_pair(l, d); octet temp1 = temp[c - 1]; return temp1; */ return (data_pair(l, d))[c - 1]; } // read from unopened file int phiex_frame::read(const char* filename) { FILE* fp = fopen(filename, "rb"); if (!fp) then fatal_error((DREstring)"Unable to open file " + (DREstring)filename + (DREstring)" in phiex_frame::read(const char*)"); int status = read(fp); fclose(fp); return status; } // read from file int phiex_frame::read(FILE* fp) { TEST((uint)fread((char*)_header, 1280, 1, fp), (uint)1, "Cannot read header information"); for (int n = 0; n < 800; n++) { if (!(n % 10)) then yield(); TEST((uint)fread((char*)_line, 800, 1, fp), (uint)1, "Cannot read High rate data"); for (int dn = 0; dn < 800; dn++) _data.element(n, dn) = _line[dn]; } _swap_100_lines(); return 1; } // write to a file int phiex_frame::write(FILE* fp) { if (!fwrite(_header, 1280, 1, fp)) then return 0; // swap octets in first 100 lines before output _swap_100_lines(); for (int n = 0; n < 800; n++) { if (!fwrite(line(n), 800, 1, fp)) then { _swap_100_lines(); return 0; } } // put them back in internal order _swap_100_lines(); return 1; } // write to an unopened file int phiex_frame::write(const char* filename) { FILE* fp = fopen(filename, "w"); if (!fp) then fatal_error((DREstring)"Unable to open file " + (DREstring)filename + (DREstring)" in phiex_frame::write(char*)"); int status = write(fp); fclose(fp); return status; } // private -- swap the octets in the first 100 lines void phiex_frame::_swap_100_lines(void) { for (int n = 0; n < 100; n++) { line(n); for (int d = 0; d < 400; d++) { octet t = _line[2 * d]; _line[2 * d] = _line[2 * d + 1]; _line[2 * d + 1] = t; } } } #ifdef SUN // read from a magtape; this is based on the very ancient getgs2.for int phiex_frame::read(magtape& tape) { // Of course, JPL habitually send us tapes which are formatted // incorrectly. Often this takes the form that there is a seperate // _header of only 1040 octets if (tape.read(_header, 1280) < 1040) then return 0; // the following shenanigans are necessary because of the bizarre way // in which the data are placed on the tapes for (int n = 0; n < 800; n++) { octet temporary_buffer [1040]; if (tape.read(temporary_buffer, 1040) < 800) then return 0; for (int octet_nr = 0; octet_nr < 800; octet_nr++) _line[n][octet_nr] = temporary_buffer[220 + octet_nr]; } // swap the first 100 lines -- internally we keep the data in freq pairs // pairs, not polarisation pairs _swap_100_lines(); return 1; } #endif // return fds count double phiex_frame::fds_count(void) const { return ((_header[18] << 8) + (_header[19]) + ((_header[20] << 8) + (_header[21])) / 100.0); } // return integral portion of the FDS count uint16 phiex_frame::fds_integer(void) const { return ((_header[18] << 8) + (_header[19])); } // return fractional portion of the FDS count octet phiex_frame::fds_fraction(void) const { return ((_header[20] << 8) + (_header[21])); } // return the SCET scet_type phiex_frame::scet(void) const { scet_type rv; rv._year = _header[30] >> 1; rv._day = ((_header[30] & 0x1) << 8) | _header[31]; rv._hour = (_header[32] << 8) + _header[33]; rv._minute = rv._hour - (rv._hour / 60) * 60; rv._hour = rv._hour / 60; int16 millisecond = (_header[34] << 8) + _header[35]; rv._second = (int16)(floor(millisecond / 1000.0)); return rv; } // return spacecraft number (1 or 2) octet phiex_frame::sc(void) const { return (2 - (_header[118] & 1)); } // merge operator -- phiex_frame + phiex_frame void phiex_frame::operator+=(phiex_frame& f) { // calculate the averages int n[4], total[4], index = 0; for (int channel = 0; channel < 2; channel++) { for (int start_line = 0; start_line < 800; (start_line += 400, index++)) { n[index] = 0; total[index] = 0; for (int line = 0; line < 400; line++) { if (!(line % 10)) then yield(); for (int datum_nr = 0; datum_nr < 400; datum_nr++) { octet* data = data_pair(line + start_line, datum_nr); if (data[channel]) then { n[index]++; total[index] += data[channel]; } data = f.data_pair(line + start_line, datum_nr); if (data[channel]) then { n[index]++; total[index] += data[channel]; } } } } } int mean[4]; for (index = 0; index < 4; index++) mean[index] = total[index] / n[index]; index = 0; // now do the actual merge for (channel = 0; channel < 2; channel++) { for (int start_line = 0; start_line < 800; (start_line += 400, index++)) { for (int line = 0; line < 400; line++) { if (!(line % 10)) then yield(); for (int datum_nr = 0; datum_nr < 400; datum_nr++) { octet* data1 = data_pair(line + start_line, datum_nr); const octet* data2 = f.data_pair(line + start_line, datum_nr); const int target = mean[index], diff1 = abs(data1[channel] - target), diff2 = abs(data2[channel] - target); if (diff2 < diff1) then data1[channel] = data2[channel]; } } } } } // merge -- not in place phiex_frame phiex_frame::operator+(phiex_frame& f) { phiex_frame rv(*this); rv += f; return rv; } // constructor from JPL format frame pds_phiex_frame::pds_phiex_frame(phiex_frame* pframe, const long int* c, int bw) : _bandwidth(bw), _data(800, 800) { phiex_frame& j = *pframe; for (int n = 0; n < 4; n++) ch[n] = c[n]; _sc = j.sc(); _year = j.year(); _day = j.day(); _hour = j.hour(); _minute = j.minute(); _second = j.second(); _fds_integer = j.fds_integer(); _fds_fraction = j.fds_fraction(); _calibrate(&j); } // copy constructor pds_phiex_frame::pds_phiex_frame(const pds_phiex_frame& p) : _data(800, 800) { for (int n = 0; n < 4; ch[n++] = p.ch[n]) ; _bandwidth = p._bandwidth; _sc = p._sc; _hour = p._hour; _minute = p._minute; _second = p._second; _fds_fraction = p._fds_fraction; _year = p._year; _day = p._day; _fds_integer = p._fds_integer; _data = p._data; } // pds_phiex_frame = pds_phiex_frame void pds_phiex_frame::operator=(const pds_phiex_frame& p) { for (int n = 0; n < 4; ch[n++] = p.ch[n]) ; _bandwidth = p._bandwidth; _sc = p._sc; _hour = p._hour; _minute = p._minute; _second = p._second; _fds_fraction = p._fds_fraction; _year = p._year; _day = p._day; _fds_integer = p._fds_integer; _data = p._data; } // private -- calibration; note that we should pass const phiex frame, but this is not // possible as the ~const syntax is not yet approved void pds_phiex_frame::_calibrate(phiex_frame* param) { phiex_frame& j = *param; static int array[2][2][256] = // flight unit 1 // upper {{{1460, 1496, 1530, 1561, 1591, 1619, 1646, 1671, 1696, 1719, 1742, 1765, 1786, 1807, 1828, 1848, 1868, 1887, 1906, 1925, 1943, 1961, 1979, 1997, 2014, 2032, 2049, 2066, 2082, 2099, 2115, 2131, 2147, 2163, 2179, 2195, 2210, 2226, 2241, 2256, 2272, 2287, 2302, 2316, 2331, 2346, 2361, 2375, 2390, 2404, 2418, 2433, 2447, 2461, 2475, 2489, 2503, 2517, 2531, 2545, 2558, 2572, 2586, 2599, 2613, 2626, 2640, 2653, 2667, 2680, 2693, 2707, 2720, 2733, 2746, 2759, 2772, 2785, 2799, 2812, 2824, 2837, 2850, 2863, 2876, 2889, 2902, 2915, 2927, 2940, 2953, 2966, 2978, 2991, 3004, 3017, 3029, 3042, 3055, 3067, 3080, 3093, 3105, 3118, 3131, 3144, 3156, 3169, 3182, 3194, 3207, 3220, 3233, 3246, 3259, 3271, 3284, 3297, 3310, 3323, 3337, 3350, 3363, 3376, 3389, 3403, 3416, 3423, 3430, 3443, 3457, 3471, 3484, 3498, 3512, 3526, 3540, 3554, 3569, 3583, 3598, 3612, 3627, 3642, 3657, 3672, 3688, 3703, 3719, 3734, 3750, 3766, 3783, 3799, 3816, 3832, 3849, 3867, 3884, 3902, 3920, 3938, 3956, 3975, 3994, 4013, 4033, 4053, 4073, 4093, 4114, 4135, 4157, 4179, 4201, 4223, 4247, 4270, 4294, 4318, 4343, 4368, 4394, 4420, 4447, 4474, 4502, 4530, 4559, 4588, 4618, 4648, 4679, 4711, 4742, 4775, 4807, 4840, 4874, 4908, 4943, 4977, 5013, 5048, 5084, 5120, 5157, 5194, 5231, 5268, 5305, 5343, 5381, 5419, 5457, 5495, 5533, 5572, 5610, 5649, 5687, 5726, 5764, 5803, 5841, 5880, 5918, 5957, 5995, 6034, 6073, 6112, 6151, 6190, 6230, 6270, 6310, 6351, 6392, 6434, 6477, 6521, 6567, 6614, 6663, 6715, 6769, 6828, 6891, 6961, 7040, 7130, 7238, 7373, 7558, 7859}, // lower {1446, 1482, 1515, 1546, 1576, 1603, 1630, 1655, 1679, 1702, 1725, 1747, 1768, 1789, 1809, 1829, 1848, 1867, 1886, 1904, 1922, 1940, 1957, 1974, 1991, 2008, 2025, 2041, 2057, 2073, 2089, 2105, 2121, 2136, 2151, 2167, 2182, 2197, 2212, 2226, 2241, 2256, 2270, 2284, 2299, 2313, 2327, 2341, 2355, 2369, 2383, 2397, 2411, 2424, 2438, 2451, 2465, 2478, 2492, 2505, 2518, 2532, 2545, 2558, 2571, 2584, 2597, 2610, 2623, 2636, 2649, 2662, 2675, 2688, 2701, 2713, 2726, 2739, 2751, 2764, 2777, 2789, 2802, 2815, 2827, 2840, 2852, 2865, 2877, 2890, 2902, 2915, 2927, 2940, 2952, 2964, 2977, 2989, 3002, 3014, 3026, 3039, 3051, 3064, 3076, 3089, 3101, 3114, 3126, 3139, 3151, 3164, 3176, 3189, 3201, 3214, 3227, 3239, 3252, 3265, 3278, 3291, 3303, 3316, 3329, 3342, 3356, 3362, 3369, 3382, 3395, 3409, 3422, 3436, 3449, 3463, 3477, 3491, 3505, 3519, 3533, 3547, 3562, 3576, 3591, 3606, 3621, 3636, 3651, 3667, 3682, 3698, 3714, 3730, 3746, 3762, 3779, 3796, 3813, 3830, 3848, 3865, 3883, 3902, 3920, 3939, 3958, 3977, 3997, 4017, 4037, 4058, 4079, 4100, 4122, 4144, 4167, 4189, 4213, 4236, 4260, 4285, 4310, 4335, 4361, 4387, 4414, 4441, 4469, 4497, 4526, 4555, 4584, 4614, 4645, 4676, 4707, 4739, 4771, 4803, 4836, 4869, 4902, 4936, 4970, 5004, 5038, 5073, 5107, 5142, 5177, 5212, 5248, 5283, 5319, 5355, 5391, 5427, 5464, 5500, 5537, 5573, 5610, 5647, 5684, 5721, 5759, 5796, 5834, 5871, 5909, 5947, 5985, 6024, 6063, 6102, 6141, 6181, 6222, 6264, 6306, 6349, 6394, 6441, 6489, 6541, 6595, 6653, 6716, 6786, 6864, 6954, 7061, 7196, 7381, 7681}}, // flight unit 2 // upper {{ 1435, 1480, 1523, 1563, 1600, 1636, 1670, 1702, 1734, 1764, 1793, 1822, 1849, 1876, 1902, 1928, 1953, 1978, 2002, 2025, 2048, 2071, 2093, 2115, 2136, 2157, 2178, 2199, 2219, 2239, 2259, 2278, 2297, 2316, 2335, 2353, 2371, 2389, 2407, 2425, 2442, 2459, 2477, 2493, 2510, 2527, 2543, 2560, 2576, 2592, 2608, 2623, 2639, 2655, 2670, 2685, 2701, 2716, 2731, 2746, 2760, 2775, 2790, 2804, 2819, 2833, 2848, 2862, 2876, 2890, 2904, 2918, 2932, 2946, 2960, 2974, 2987, 3001, 3015, 3028, 3042, 3055, 3069, 3082, 3095, 3109, 3122, 3135, 3149, 3162, 3175, 3188, 3201, 3214, 3227, 3240, 3254, 3267, 3280, 3293, 3306, 3319, 3332, 3344, 3357, 3370, 3383, 3396, 3409, 3422, 3435, 3448, 3461, 3474, 3487, 3500, 3513, 3527, 3540, 3553, 3566, 3579, 3593, 3606, 3619, 3633, 3646, 3653, 3660, 3673, 3687, 3700, 3714, 3728, 3742, 3756, 3770, 3784, 3798, 3813, 3827, 3841, 3856, 3871, 3886, 3901, 3916, 3931, 3946, 3962, 3978, 3993, 4009, 4026, 4042, 4058, 4075, 4092, 4109, 4126, 4144, 4162, 4180, 4198, 4216, 4235, 4254, 4273, 4293, 4313, 4333, 4353, 4374, 4395, 4417, 4439, 4461, 4483, 4506, 4530, 4553, 4577, 4602, 4627, 4652, 4678, 4704, 4731, 4758, 4786, 4814, 4842, 4871, 4901, 4931, 4961, 4992, 5023, 5054, 5086, 5119, 5151, 5184, 5218, 5252, 5286, 5321, 5355, 5391, 5426, 5462, 5498, 5534, 5571, 5607, 5644, 5681, 5719, 5756, 5794, 5832, 5870, 5908, 5946, 5985, 6023, 6062, 6101, 6140, 6179, 6218, 6257, 6297, 6337, 6377, 6418, 6459, 6500, 6542, 6585, 6628, 6673, 6719, 6767, 6816, 6868, 6923, 6982, 7046, 7116, 7195, 7286, 7394, 7529, 7714, 8015}, // lower { 1630, 1667, 1701, 1733, 1763, 1791, 1818, 1844, 1869, 1893, 1916, 1938, 1960, 1981, 2002, 2022, 2042, 2061, 2080, 2099, 2118, 2136, 2154, 2171, 2189, 2206, 2223, 2240, 2257, 2273, 2289, 2306, 2322, 2338, 2353, 2369, 2384, 2400, 2415, 2430, 2445, 2460, 2475, 2490, 2505, 2519, 2534, 2548, 2563, 2577, 2592, 2606, 2620, 2634, 2648, 2662, 2676, 2690, 2704, 2718, 2731, 2745, 2759, 2772, 2786, 2799, 2813, 2827, 2840, 2853, 2867, 2880, 2893, 2907, 2920, 2933, 2947, 2960, 2973, 2986, 2999, 3012, 3025, 3039, 3052, 3065, 3078, 3091, 3104, 3117, 3130, 3143, 3156, 3169, 3181, 3194, 3207, 3220, 3233, 3246, 3259, 3272, 3285, 3298, 3311, 3323, 3336, 3349, 3362, 3375, 3388, 3401, 3414, 3427, 3440, 3453, 3466, 3479, 3492, 3506, 3519, 3532, 3545, 3558, 3572, 3585, 3599, 3605, 3612, 3626, 3639, 3653, 3667, 3680, 3694, 3708, 3722, 3736, 3750, 3764, 3779, 3793, 3808, 3822, 3837, 3852, 3867, 3882, 3897, 3912, 3928, 3943, 3959, 3975, 3991, 4007, 4023, 4040, 4057, 4073, 4091, 4108, 4125, 4143, 4161, 4179, 4198, 4216, 4235, 4255, 4274, 4294, 4314, 4334, 4355, 4376, 4398, 4419, 4441, 4464, 4487, 4510, 4534, 4558, 4582, 4607, 4633, 4659, 4685, 4712, 4739, 4767, 4795, 4824, 4853, 4883, 4913, 4943, 4974, 5006, 5038, 5070, 5103, 5136, 5169, 5203, 5237, 5271, 5306, 5341, 5376, 5411, 5447, 5482, 5518, 5554, 5590, 5626, 5662, 5699, 5735, 5772, 5809, 5846, 5883, 5920, 5957, 5994, 6032, 6070, 6108, 6146, 6185, 6224, 6264, 6304, 6344, 6385, 6427, 6469, 6513, 6557, 6603, 6651, 6701, 6753, 6808, 6867, 6931, 7001, 7080, 7171, 7278, 7414, 7599, 7900 }}}; // we assume no attenuation // static int attenuation_array[8] = // { 0, 1500, 3000, 4500, 4500, 6000, 7500, 9000 }; // the following array adjusts for: // low band upper & lower; // harad upper & lower; // polhi upper & lower static int misc_adjustment_array[2][6] = {{ // flight unit 1 -210, 60, 50, 50, 110, 200 }, // flight unit 2 { 210, 300, 320, 300, 70, 120 }}; const int flight_unit = 2 - sc(); for (int line_nr = 0; line_nr < 800; line_nr++) { if (!(line_nr % 10)) yield(); for (int pair_nr = 0; pair_nr < 400; pair_nr++) { // the calibration could be done in a single (long) line, but // the following tortuous series of instructions makes it clearer // what is going on const octet* pair = j.data_pair(line_nr, pair_nr); // the pair is stored internally as f1, f2. f1 is always the higher // frequency, and thus the lower path through the receiver for (int n = 0; n < 2; n++) { octet datum = pair[n]; // an empirical fix for channel 1 since Uranus on V2 if ((year() > 86) && (n == 0) && (line_nr < 400) && datum) then datum = 255 - datum; short int mb = datum ? array[flight_unit][1 - n][datum] : 0; // assume we are in high band (i.e. 200 kHz bandwidth) if (mb) then mb += misc_adjustment_array[flight_unit][5 - n]; _data.element(line_nr, 2 * pair_nr + n) = mb; } } } } // return the frequency corresponding to a channel number int pds_phiex_frame::channel(int n) const { if ((n < 1) || (n > 4)) then return 0; return ch[n - 1]; } // input from a stream istream& operator>>(istream& in, pds_phiex_frame& pf) { in >> pf._year; pf._year -= 1900; in >> pf._day; int temp; in >> temp; pf._hour = temp; in >> temp; pf._minute = temp; in >> temp; pf._second = temp; in >> temp; pf._sc = temp; in >> pf._fds_integer; in >> temp; pf._fds_fraction = temp;; for (int n = 0; n < 4; n++) in >> pf.ch[n]; in >> temp; pf._bandwidth = temp; for (int l = 0; l < 800; l++) { if (!(l % 10)) then yield(); for (int d = 0; d < 400; d++) { for (int c = 1; c <= 2; c++) in >> pf.datum(l, d, c); } } return in; } // output to a stream (ASCII) ostream& operator<<(ostream& out, pds_phiex_frame& pf) { out << (pf.year() + 1900) << " " << pf.day() << " " << (int)pf.hour() << " " << (int)pf.minute() << " " << (int)pf.second() << " " << (int)pf.sc() << " " << pf.fds_integer() << " " << (int)pf.fds_fraction() << " "; for (int n = 1; n <= 4; n++) out << pf.channel(n) << " "; out << pf.bandwidth(); out << "\n"; for (int l = 0; l < 800; l++) { if (!(l % 10)) then yield(); for (int d = 0; d < 400; d++) { for (int c = 1; c <= 2; c++) { out << left_fill(DREstring10(pf.datum(l, d, c)), 4) << " "; } } out << "\n"; } return out; } // return a reference to a single datum; l, d wrt0, c wrt 1 /*short int& pds_phiex_frame::_ref_datum(const int l, const int d, const int c) const { int index = l * 800; index += d * 2; index += (c - 1); return data[index]; }*/ // binary write void pds_phiex_frame::write(FILE* outfile) { // because of the stupid way that fwrite works, we need some dummy // variables octet dummy1; int16 dummy2; uint16 udummy2; int32 dummy4; dummy2 = year() + 1900; fwrite((char*)&dummy2, sizeof(dummy2), 1, outfile); dummy2 = day(); fwrite((char*)&dummy2, sizeof(dummy2), 1, outfile); dummy1 = hour(); fwrite((char*)&dummy1, sizeof(dummy1), 1, outfile); dummy1 = minute(); fwrite((char*)&dummy1, sizeof(dummy1), 1, outfile); dummy1 = second(); fwrite((char*)&dummy1, sizeof(dummy1), 1, outfile); dummy1 = sc(); fwrite((char*)&dummy1, sizeof(dummy1), 1, outfile); udummy2 = fds_integer(); fwrite((char*)&udummy2, sizeof(dummy2), 1, outfile); dummy1 = fds_fraction(); fwrite((char*)&dummy1, sizeof(dummy1), 1, outfile); for (int n = 1; n <= 4; n++) { dummy4 = channel(n); fwrite((char*)&dummy4, sizeof(dummy4), 1, outfile); } dummy1 = bandwidth(); fwrite((char*)&dummy1, sizeof(dummy1), 1, outfile); for (int l = 0; l < 800; l++) { if (!(l % 10)) then yield(); for (int d = 0; d < 400; d++) { for (int c = 1; c <= 2; c++) { dummy2 = datum(l, d, c); fwrite((char*)&dummy2, sizeof(dummy2), 1, outfile); } } } } void pds_phiex_frame::read(FILE* fp) { /* fread(&_year, sizeof(_year), 1, fp); _year -= 1900; fread(&_day, sizeof(_day), 1, fp); fread(&_hour, sizeof(_hour), 1, fp); fread(&_minute, sizeof(_minute), 1, fp); fread(&_second, sizeof(_second), 1, fp); fread(&_sc, sizeof(_sc), 1, fp); fread(&_fds_integer, sizeof(_fds_integer), 1, fp); fread(&_fds_fraction, sizeof(_fds_fraction), 1, fp); fread(&(ch[0]), sizeof(uint32), 4, fp); fread(&_bandwidth, sizeof(_bandwidth), 1, fp); */ read_binary(fp, _year); _year -= 1900; read_binary(fp, _day); read_binary(fp, _hour); read_binary(fp, _minute); read_binary(fp, _second); read_binary(fp, _sc); read_binary(fp, _fds_integer); read_binary(fp, _fds_fraction); for (int n = 0; n < 4; n++) read_binary(fp, ch[n]); read_binary(fp, _bandwidth); for (int l = 0; l < 800; l++) { if (!(l % 10)) then yield(); // read a line at a time for efficiency uint16 temp_line[800]; if (fread(temp_line, sizeof(uint16), 800, fp) != 800) then fatal_error("pds_phiex_frame::read(FILE*)"); // Intel CPUs require that the data be byte swapped #ifdef INTEL char* cp = (char*)temp_line; swab(cp, cp, 1600); #endif for (int d = 0; d < 400; d++) for (int c = 1; c <= 2; c++) _data.element(l, 2 * d + c - 1) = temp_line[2 * d + c - 1]; } } void pds_phiex_frame::read(const char* fn) { FILE* fp = fopen(fn, "rb"); if (!fp) then fatal_error((DREstring)"Unable to open file " + (DREstring)fn + (DREstring)" in pds_phiex_frame::read(char*)"); read(fp); fclose(fp); }