Skip to content

Instantly share code, notes, and snippets.

@mhvk
Created January 3, 2020 18:07
Show Gist options
  • Save mhvk/9f452330f414de6d9c455c1162527398 to your computer and use it in GitHub Desktop.
Save mhvk/9f452330f414de6d9c455c1162527398 to your computer and use it in GitHub Desktop.
C code to convert RadioAstron RDF to Mark 5B
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#define _FILE_OFFSET_BITS 64
//much of this taken from from Ari Mujunen vsib code
static unsigned char bytetable[256];
unsigned char crcdata[6];
unsigned int crcc () ;
int main(int argc, char *argv[])
{
char filenamein[256],filenameout[256];
unsigned char hh[256],ddin[10000]; //space for rdf header and data blocks
char data_type[5],data_date[18],terminal[3];
char source [11],format_set[11],format_name[7];
FILE *file1, *file2;
int iret,iw,iyear,idoy,ihh,imm,iss,iy,ic,im,ix1,ix2,ix3,mjd,short_mjd;
int secday_start,secmjd,fracsec, frame_per_sec, framepersec;
unsigned char j1, j2, j3, s1, s2, s3, s4, s5,y1;
unsigned short nframe, crc;
u_int32_t mk5bheader[4];
// Mark5b Sync word is constant. Blank user bits
mk5bheader[0] = 0xABADDEED; mk5bheader[1] = 0xF00F0000;
mk5bheader[2] = 0x0; mk5bheader[3] = 0x0;
filenamein[0]=filenameout[0]=0;
if(argc < 2) { printf("NEED readastr filein fileout \n"); return 0; }
if (argc > 1) sscanf(argv[1], "%255s", filenamein);
if (argc > 2) sscanf(argv[2], "%255s", filenameout);
if ((file1 = fopen(filenamein, "r")) == NULL) return 0;
if ((file2 = fopen(filenameout, "w")) == NULL) return 0;
iret=fread(hh, sizeof(hh), 1, file1); //========Read RDF header
strncpy(data_type,&hh[0],5);
strncpy(data_date,&hh[6],18);
strncpy(terminal,&hh[24],3);
strncpy(source,&hh[35],11);
strncpy(format_set,&hh[46],11);
hh[63]='\0'; strncpy(format_name,&hh[57],7);
printf("%s:%s:%s:%s:%s:%s\n",data_type,data_date,terminal,source,format_set,format_name);
data_date[8]=' '; data_date[11]=' '; data_date[14]=' ';
sscanf(data_date,"%4d %3d %2d %2d %2d",&iyear,&idoy,&ihh,&imm,&iss);
y1=iyear-2000; //years since 2000
im = 10; iy = iyear-1; //MJD make
ic = iy/100; iy = iy-ic*100;
ix1 = 146097*ic/4; ix2 = 1461*iy/4; ix3 = (153*im+2)/5;
mjd=ix1+ix2+ix3+idoy-678882;
ic=mjd/1000; short_mjd=mjd-ic*1000;
secday_start=ihh*3600+imm*60+iss;
j1 = (short_mjd%1000/100); j2 = ((short_mjd%100)/10); j3 = (short_mjd%10); //digits of mjd
if(strcmp(format_name,"32IDAS") == 0){ frame_per_sec=3200; } else {frame_per_sec=1600;}
printf("framepersec=%d \n",frame_per_sec);
nframe=0; secmjd=secday_start;
while(iret !=0){ //====================loop reading 10kbyte blocks until data finished
iret=fread(ddin, sizeof(ddin), 1, file1);
s1 = (secmjd/10000)&0xF; s2 = ((secmjd%10000)/1000)&0xF; s3 = ((secmjd%1000)/100)&0xF;
s4 = ((secmjd%100)/10)&0xF; s5 = (secmjd%10)&0xF;
mk5bheader[1]= y1<<28 | 0x0ead <<16 | nframe; //year put according to mk5 memo 58
mk5bheader[2] = j1<<28 | j2<<24 | j3<<20 |
s1<<16 | s2<<12 | s3<<8 | s4<<4 | s5;
crcdata[0] = j1<<4|j2; crcdata[1] = j3<<4|s1;
crcdata[2] = s2<<4|s3; crcdata[3] = s4<<4|s5;
fracsec = (nframe/(double)frame_per_sec)*10000; //MJD sec fraction
s1 = fracsec/1000; s2 = (fracsec%1000)/100;
s3 = (fracsec%100)/10; s4 = fracsec%10;
mk5bheader[3] = s1<<28 | s2<<24 | s3<<20 | s4<<16;
/// CRC according to mk5 memo 58, CRC and frac seconds only needed for Mk5A+ compatibility
crcdata[4] = s1<<4|s2; crcdata[5] = s3<<4|s4;
crc = crcc(crcdata, 48, 040003, 16);
crc = ((crc >> 1) & 0x55555555) | ((crc & 0x55555555) << 1); //reverse bit order
crc = ((crc >> 2) & 0x33333333) | ((crc & 0x33333333) << 2);
crc = ((crc >> 4) & 0x0F0F0F0F) | ((crc & 0x0F0F0F0F) << 4);
crc = ((crc >> 8) & 0x00FF00FF) | ((crc & 0x00FF00FF) << 8);
mk5bheader[3]=mk5bheader[3] | crc;
iw=fwrite(mk5bheader,sizeof(mk5bheader),1,file2); //========write header
iw=fwrite(ddin,sizeof(ddin),1,file2); //========write data block
nframe++;
if(nframe >=frame_per_sec){
nframe=0; secmjd++; //assume scan never goes over midnight
}
} //===========================================================
}
// crc subroutine - converts input into a 16 bit CRC code
unsigned int crcc (unsigned char *idata, int len, int mask, int cycl) {
unsigned int istate = 0;
int idbit;
int q, ich, icb;
for (idbit = 1; idbit <= len; idbit++) {
q = istate & 1;
ich = (idbit - 1) / 8;
icb = 7 - (idbit - 1) % 8;
if ((((idata[ich] >> icb) & 1) ^ q) == 0)
istate &= -2;
else {
istate ^= mask;
istate |= 1;
}
istate = (istate >> 1) | (istate & 1) << (cycl -1);
}
return (istate);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment