4 using namespace netCDF;
5 using namespace netCDF::exceptions;
9 uint32_t nmcescan, uint32_t nenc, int32_t& ppr_off,
10 double& revpsec,
double&secpline,
11 int16_t& board_id, int32_t *mspin, int32_t *ot_10us,
12 uint8_t *enc_count,
float **hamenc,
float **rtaenc,
17 NcDim mce_dim = l1afile->getDim(
"MCE_block");
18 uint32_t mce_blk = mce_dim.getSize();
19 NcDim ddc_dim = l1afile->getDim(
"DDC_tlm");
20 uint32_t nddc = ddc_dim.getSize();
21 NcDim tlm_dim = l1afile->getDim(
"tlm_packets");
22 uint32_t ntlmpack = tlm_dim.getSize();
24 uint8_t **mtlm =
new uint8_t *[nmcescan];
25 mtlm[0] =
new uint8_t[mce_blk*nmcescan];
26 for (
size_t i=1;
i<nmcescan;
i++) mtlm[
i] = mtlm[
i-1] + mce_blk;
28 int16_t **enc =
new int16_t *[nmcescan];
29 enc[0] =
new int16_t[4*nenc*nmcescan];
30 for (
size_t i=1;
i<nmcescan;
i++) enc[
i] = enc[
i-1] + 4*nenc;
32 uint8_t **ddctlm =
new uint8_t *[ntlmpack];
33 ddctlm[0] =
new uint8_t[nddc*ntlmpack];
34 for (
size_t i=1;
i<ntlmpack;
i++) ddctlm[
i] = ddctlm[
i-1] + nddc;
42 var = egid.getVar(
"MCE_telemetry");
43 var.getVar( &mtlm[0][0]);
45 var = egid.getVar(
"MCE_encoder_data");
47 count.push_back(4*nenc);
48 var.getVar( &enc[0][0]);
50 var = egid.getVar(
"MCE_spin_ID");
53 var = egid.getVar(
"DDC_telemetry");
54 var.getVar( &ddctlm[0][0]);
58 for (
size_t i=0;
i<nmcescan;
i++) {
66 cout <<
"No MCE telemetry in L1A file" << endl;
70 int32_t max_enc_cts = 131072;
77 uint32_t ref_pulse_div[2];
78 memcpy( &ui32, &mtlm[0][0], 4);
79 ref_pulse_div[0] =
SWAP_4( ui32) % 16777216;
80 memcpy( &ui32, &mtlm[0][4], 4);
81 ref_pulse_div[1] =
SWAP_4( ui32) % 16777216;
83 int32_t ref_pulse_sel = mtlm[0][9] / 128;
85 revpsec = clock[ref_pulse_sel] / 2 / max_enc_cts /
86 (ref_pulse_div[ref_pulse_sel]/256.0 + 1);
89 int32_t avg_step_spd = mtlm[0][428]*256+mtlm[0][429];
90 if (
abs(avg_step_spd) < 1000) {
94 cout <<
"OCI static mode" << endl;
95 }
else if (avg_step_spd < 0) {
99 cout <<
"OCI reverse scan" << endl;
103 memcpy( &ui32, &mtlm[0][8], 4);
104 ppr_off =
SWAP_4( ui32) % max_enc_cts;
105 for (
size_t i=0;
i<nmcescan;
i++) {
106 memcpy( &ui32, &mtlm[
i][368], 4);
107 ot_10us[
i] =
SWAP_4( ui32) % 4;
111 board_id = (int16_t) mtlm[0][322] / 16;
115 memcpy( &ui16, &ddctlm[0][346], 2);
116 int32_t tditime =
SWAP_2( ui16);
117 secpline = (tditime+1) / clock[0];
120 for (
size_t i=0;
i<nmcescan;
i++) enc_count[
i] = mtlm[
i][475];
122 for (
size_t i=0;
i<nmcescan;
i++) {
123 for (
size_t j=0;
j<nenc;
j++) {
143 uint16_t& pcdim, uint16_t& psdim,
double& ev_toff,
144 float *clines,
float *slines,
double *deltc,
double *delts,
145 bool dark, int16_t &iret) {
148 int16_t iz=0, line0=0;
150 while (
dtype[iz] == 0) {
154 if (iz == 10)
return 0;
159 int16_t linen = line0;
161 uint8_t ltype[] = {0,1,0,1,1,1,1,1,1,1,0,0,0};
162 if (dark) ltype[2] = 1;
164 for (
size_t i=iz;
i<9;
i++) {
166 if ( ltype[
dtype[
i]] == 1) {
169 uint16_t np =
lines[
i] / iagg[
i];
170 for (
size_t j=0;
j<np;
j++) {
171 clines[pcdim+
j] = linen +
j*iagg[
i] + 0.5*iagg[
i] - 64;
174 uint16_t ns =
lines[
i] / 8;
175 for (
size_t j=0;
j<ns;
j++) {
176 slines[psdim+
j] = linen +
j*8 + 4 - 64;
185 for (
size_t i=0;
i<(size_t) pcdim;
i++) deltc[
i] = secpline * clines[
i];
186 ev_toff = 0.5 * (deltc[0] + deltc[pcdim-1]);
187 for (
size_t i=0;
i<(size_t) pcdim;
i++) deltc[
i] -= ev_toff;
189 for (
size_t i=0;
i<(size_t) psdim;
i++)
190 delts[
i] = secpline * slines[
i] - ev_toff;
195 int get_oci_vecs( uint32_t nscan, uint16_t pdim,
double as_planarity[5],
196 double at_planarity[5], int32_t *rta_nadir,
197 double ham_ct_angles[2],
double ev_toff, int32_t
spin,
198 uint8_t hside,
float *clines,
199 double *delt,
double revpsec, int32_t ppr_off,
200 int16_t board_id, uint32_t nmcescan, int32_t *mspin,
201 uint8_t *enc_count,
float **hamenc,
float **rtaenc,
202 float **pview,
double *theta, int16_t& iret) {
210 int32_t max_enc_cts = 131072;
211 double dtenc = 0.001;
212 constexpr
double pi = 3.14159265358979323846;
213 int16_t bd_id = board_id % 2;
215 double rad2asec = (180/
pi) * 3600;
220 float pprang = 2 *
pi * (ppr_off - rta_nadir[bd_id]) / max_enc_cts;
221 if (pprang >
pi) pprang -= 2*
pi;
224 double *toff =
new double[pdim];
225 for (
size_t i=0;
i<pdim;
i++) toff[
i] = delt[
i] + ev_toff;
227 for (
size_t i=0;
i<pdim;
i++)
228 theta[
i] = pprang + 2 *
pi * revpsec * toff[
i];
232 double *thetacor =
new double[pdim];
235 for (
size_t i=0;
i<nmcescan;
i++) {
236 if ( mspin[
i] ==
spin) {
245 cout <<
"No MCE encoder data for spin: " <<
spin << endl;
254 for (
size_t j=0;
j<enc_count[isp];
j++) {
255 double tenc =
j*dtenc;
256 if ( tenc <= toff[ip] && (tenc+dtenc) > toff[ip]) {
266 for (
size_t i=0;
i<pdim;
i++) {
267 if ( toff[
i] >= tenc_ke && toff[
i] < tenc_ke+dtenc) {
268 double ft = (toff[
i] - tenc_ke) / dtenc;
270 (1-ft)*rtaenc[isp][ke] + ft*rtaenc[isp][ke+1] -
271 ((1-ft)*hamenc[isp][ke] + ft*hamenc[isp][ke+1] +
272 ham_ct_angles[hside])*0.236;
278 cout <<
"Encoder interpolation error" << endl;
285 double *ascan =
new double[pdim];
286 double *atrack =
new double[pdim];
287 for (
size_t i=0;
i<pdim;
i++) {
288 theta[
i] = theta[
i] - thetacor[
i] / rad2asec;
290 ascan[
i] = as_planarity[0];
291 atrack[
i] = at_planarity[0];
292 for (
size_t k=1;
k<5;
k++) {
293 ascan[
i] += as_planarity[
k]*pow(theta[
i],
k);
294 atrack[
i] += at_planarity[
k]*pow(theta[
i],
k);
297 pview[
i][0] = -sin(atrack[
i]/rad2asec);
298 pview[
i][1] = sin(theta[
i] - ascan[
i]/rad2asec);
299 pview[
i][2] = cos(theta[
i] - ascan[
i]/rad2asec);
312 int createField( NcGroup &ncGrp,
const char *sname,
const char *lname,
315 void *fill_value,
const char *flag_masks,
316 const char *flag_meanings,
317 double low,
double high,
319 int nt, vector<NcDim>& varVec,
string coordinates) {
325 ncVar = ncGrp.addVar(sname, nt, varVec);
327 catch ( NcException& e) {
328 cout << e.what() << endl;
329 cerr <<
"Failure creating variable: " << sname << endl;
332 int var_id = ncVar.getId();
333 int nc_id = ncVar.getParentGroup().getId();
334 std::string grp_name = ncVar.getParentGroup().getName();
336 for (
size_t idim = 0 ; idim < ncVar.getDims().
size(); idim ++){
337 dimids[idim] = ncVar.getDims()[idim].getId();
340 double fill_value_dbl;
341 memcpy( &fill_value_dbl, fill_value,
sizeof(
double));
351 if ( low != fill_value_dbl) {
352 if ( nt == NC_BYTE) {
354 ncVar.setFill(
true, (
void *) &i8);
355 }
else if ( nt == NC_UBYTE) {
356 ui8 = fill_value_dbl;
357 ncVar.setFill(
true, (
void *) &ui8);
358 }
else if ( nt == NC_SHORT) {
359 i16 = fill_value_dbl;
360 ncVar.setFill(
true, (
void *) &i16);
361 }
else if ( nt == NC_USHORT) {
362 ui16 = fill_value_dbl;
363 ncVar.setFill(
true, (
void *) &ui16);
364 }
else if ( nt == NC_INT) {
365 i32 = fill_value_dbl;
366 ncVar.setFill(
true, (
void *) &i32);
367 }
else if ( nt == NC_UINT) {
368 ui32 = fill_value_dbl;
369 ncVar.setFill(
true, (
void *) &ui32);
370 }
else if ( nt == NC_FLOAT) {
371 f32 = fill_value_dbl;
372 ncVar.setFill(
true, (
void *) &
f32);
374 ncVar.setFill(
true, (
void *) &fill_value_dbl);
379 int deflate_level = 5;
380 std::vector<size_t> chunkVec;
381 bool set_compression = (grp_name ==
"geolocation_data") || (grp_name ==
"observation_data");
382 if (set_compression) {
383 if(varVec.size() == 2)
384 chunkVec = {512, 1272};
385 if(varVec.size() == 3)
386 chunkVec = {40, 16, 1272};
388 chunkVec.data(), deflate_level);
394 ncVar.putAtt(
"long_name", lname);
396 catch ( NcException& e) {
398 cerr <<
"Failure creating 'long_name' attribute: " << lname << endl;
402 if ( strcmp( flag_masks,
"") != 0) {
407 fv.assign( flag_masks);
408 size_t pos = fv.find(
"=", curPos);
409 fv = fv.substr(
pos+1);
411 size_t semicln = fv.find(
";");
416 while(
pos != semicln) {
417 pos = fv.find(
",", curPos);
418 if (
pos == string::npos)
422 istringstream iss(fv.substr(curPos,
pos-curPos));
423 iss >> skipws >> flag_mask;
424 vec[n++] = atoi( flag_mask.c_str());
429 ncVar.putAtt(
"flag_masks", nt, n, vec);
431 catch ( NcException& e) {
433 cerr <<
"Failure creating 'flag_masks' attribute: " << lname << endl;
439 if ( strcmp( flag_meanings,
"") != 0) {
442 ncVar.putAtt(
"flag_meanings", flag_meanings);
444 catch ( NcException& e) {
446 cerr <<
"Failure creating 'flag_meanings' attribute: "
447 << flag_meanings << endl;
458 vr[0] = (uint8_t)low;
459 vr[1] = (uint8_t)high;
462 ncVar.putAtt(
"valid_min", NC_BYTE, 1, &vr[0]);
464 catch ( NcException& e) {
466 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
471 ncVar.putAtt(
"valid_max", NC_BYTE, 1, &vr[1]);
473 catch ( NcException& e) {
475 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
483 vr[0] = (uint8_t)low;
484 vr[1] = (uint8_t)high;
487 ncVar.putAtt(
"valid_min", NC_UBYTE, 1, &vr[0]);
489 catch ( NcException& e) {
491 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
496 ncVar.putAtt(
"valid_max", NC_UBYTE, 1, &vr[1]);
498 catch ( NcException& e) {
500 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
508 vr[0] = (int16_t)low;
509 vr[1] = (int16_t)high;
512 ncVar.putAtt(
"valid_min", NC_SHORT, 1, &vr[0]);
514 catch ( NcException& e) {
516 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
521 ncVar.putAtt(
"valid_max", NC_SHORT, 1, &vr[1]);
523 catch ( NcException& e) {
525 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
533 vr[0] = (uint16_t)low;
534 vr[1] = (uint16_t)high;
537 ncVar.putAtt(
"valid_min", NC_USHORT, 1, &vr[0]);
539 catch ( NcException& e) {
541 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
546 ncVar.putAtt(
"valid_max", NC_USHORT, 1, &vr[1]);
548 catch ( NcException& e) {
550 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
558 vr[0] = (int32_t)low;
559 vr[1] = (int32_t)high;
562 ncVar.putAtt(
"valid_min", NC_INT, 1, &vr[0]);
564 catch ( NcException& e) {
566 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
571 ncVar.putAtt(
"valid_max", NC_INT, 1, &vr[1]);
573 catch ( NcException& e) {
575 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
584 vr[0] = (uint32_t)low;
585 vr[1] = (uint32_t)high;
588 ncVar.putAtt(
"valid_min", NC_UINT, 1, &vr[0]);
590 catch ( NcException& e) {
592 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
597 ncVar.putAtt(
"valid_max", NC_UINT, 1, &vr[1]);
599 catch ( NcException& e) {
601 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
614 ncVar.putAtt(
"valid_min", NC_FLOAT, 1, &vr[0]);
616 catch ( NcException& e) {
618 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
623 ncVar.putAtt(
"valid_max", NC_FLOAT, 1, &vr[1]);
625 catch ( NcException& e) {
627 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
639 ncVar.putAtt(
"valid_min", NC_DOUBLE, 1, &vr[0]);
641 catch ( NcException& e) {
643 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
648 ncVar.putAtt(
"valid_max", NC_DOUBLE, 1, &vr[1]);
650 catch ( NcException& e) {
652 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
658 fprintf(
stderr,
"-E- %s line %d: ",__FILE__,__LINE__);
659 fprintf(
stderr,
"Got unsupported number type (%d) ",nt);
660 fprintf(
stderr,
"while trying to create NCDF variable, \"%s\", ",sname);
668 ncVar.putAtt(
"scale_factor", NC_DOUBLE, 1, &
scale);
670 catch ( NcException& e) {
672 cerr <<
"Failure creating 'scale_factor' attribute: " <<
scale << endl;
677 ncVar.putAtt(
"add_offset", NC_DOUBLE, 1, &
offset);
679 catch ( NcException& e) {
681 cerr <<
"Failure creating 'add_offset' attribute: " <<
offset << endl;
690 ncVar.putAtt(
"units",
units);
692 catch ( NcException& e) {
694 cerr <<
"Failure creating 'units' attribute: " <<
units << endl;
705 catch ( NcException& e) {
707 cerr <<
"Failure creating 'description' attribute: " <<
description << endl;
717 catch ( NcException& e) {
719 cerr <<
"Failure creating 'standard_name' attribute: "
726 if ( !coordinates.empty()) {
729 ncVar.putAtt(
"coordinates", coordinates);
731 catch ( NcException& e) {
733 cerr <<
"Failure creating 'coordinates' attribute: "
734 << coordinates << endl;
742 int get_nib_nbb( uint32_t ntaps,
size_t *ia, uint32_t ntb[16], int16_t jagg[16],
743 uint32_t& nib, uint32_t& nbb) {
748 for (
size_t i=0;
i<ntaps;
i++) {
758 for (
size_t i=0;
i<16;
i++) ntb[
i] = 0;
759 for (
size_t i=0;
i<iia;
i++) ntb[ia[
i]] = 32 / jagg[ia[
i]];
761 for (
size_t i=0;
i<16;
i++) nib += ntb[
i];
765 nbb = (ntb[ia[0]]*3) / 4 + 1;
767 for (
size_t i=1;
i<iia;
i++) {
768 if (jagg[ia[
i]] >= jagg[ia[
i]-1])
771 nbb += (ntb[ia[
i]]*3) / 4 + ntb[ia[
i]-1]/4;
778 uint32_t nib, uint32_t nbb,
float **amat,
float **gmat) {
780 for (
size_t i=0;
i<512;
i++) {
781 gmat[
i] =
new float[nib];
782 for (
size_t j=0;
j<nib;
j++) gmat[
i][
j] = 0.0;
788 for (
size_t i=0;
i<16;
i++) {
789 itt[
i][0] = itt[
i][1] = 0;
791 for (
size_t k=0;
k<ntb[
i];
k++) {
793 size_t kj =
k*jagg[
i];
794 for (
size_t j=0;
j<(size_t) jagg[
i];
j++)
795 gmat[ic+kj+
j][ii+
k] = (1.0/jagg[
i]);
803 for (
size_t i=0;
i<nib;
i++) {
804 amat[
i] =
new float[nbb];
805 for (
size_t j=0;
j<nbb;
j++) amat[
i][
j] = 0;
810 for (
size_t k=0;
k<=(ntb[ia[0]]*3)/4;
k++) {
811 for (
size_t l=0; l<=ntb[ia[0]]/4-1; l++) amat[
k+l][
k] = jagg[ia[0]]/8.0;
813 ib = (ntb[ia[0]]*3)/4 + 1;
817 for (
size_t i=ia[1];
i<16;
i++) {
819 if (ntb[
i] >= ntb[
i-1]) {
824 for (
size_t k=0;
k<nr;
k++) {
825 uint16_t k1 = nr -
k - 1;
826 uint16_t k2 = ((
k+1)*ntb[
i]) / ntb[
i-1] - 1;
827 for (
size_t j=0;
j<=k1;
j++)
828 amat[itt[
i-1][1]-k1+
j][ib+
k] = jagg[
i-1] / 8.0;
829 for (
size_t j=0;
j<=k2;
j++)
830 amat[itt[
i][0]+
j][ib+
k] = jagg[
i] / 8.0;
839 for (
size_t k=0;
k<nr;
k++) {
840 uint16_t k1 = ((nr-
k)*ntb[
i-1]) / ntb[
i] - 1;
842 for (
size_t j=0;
j<=k1;
j++)
843 amat[itt[
i-1][1]-k1+
j][ib+
k] = jagg[
i-1] / 8.0;
844 for (
size_t j=0;
j<=k2;
j++)
845 amat[itt[
i][0]+
j][ib+
k] = jagg[
i] / 8.0;
851 for (
size_t k=0;
k<=(ntb[
i]*3)/4;
k++) {
852 for (
size_t j=0;
j<ntb[
i]/4;
j++)
853 amat[itt[
i][0]+
k+
j][ib+
k] = jagg[
i] / 8.0;
855 ib += (ntb[
i]*3) / 4 + 1;
865 vector<uint32_t> kf, kv;
867 if (sstime[
i] == -999 || sstime[
i] == -32767)
873 size_t nf = kf.size();
874 if ( nf == 0)
return 0;
876 size_t nv = kv.size();
879 for (
size_t i=0;
i<nf;
i++) {
883 sstime[kf[
i]] = sstime[kv[0]] -
884 (sstime[kv[1]]-sstime[kv[0]])*(kv[0]-kf[
i])/(kv[1]-kv[0]);
885 }
else if (kf[
i] > kv[nv-1]) {
886 sstime[kf[
i]] = sstime[kv[nv-1]] +
887 (sstime[kv[nv-1]]-sstime[kv[nv-2]])*(kf[
i]-kv[nv-1])/
891 for (
int j=nv-1;
j>=0;
j--) {
897 sstime[kf[
i]] = sstime[kv[iv]] +
898 (sstime[kv[iv+1]]-sstime[kv[iv]])*(kf[
i]-kv[iv])/(kv[iv+1]-kv[iv]);