#include "fadtoraw.h" #define NUM_OF_CHANNELS_PER_CHIP 9 #define NUM_OF_DRS_PER_FAD 4 #define CPC NUM_OF_CHANNELS_PER_CHIP #define DPF NUM_OF_DRS_PER_FAD #define MAX_NUM_OF_FADS 50 // converts FAD -> .RAW int fadtoraw(char *inputfilename, timeval starttime, timeval endtime, int runnum){ FILE *faddatafile; FILE* RAWfile; char rawfilename[PATH_MAX]; EventHeader RawEventHeader; RunHeader RawRunHeader; RawRunHeader.NChips = DPF; RawRunHeader.NBoards = 1; //fix BoardStructure rawBoard[RawRunHeader.NBoards]; EVNT FadEvent; unsigned short board_ids[MAX_NUM_OF_FADS]; short convert; // buffer to convert adc data float temperature=0; // open input data file which is fad-formatted if ((faddatafile = fopen (inputfilename, "r")) == NULL) { printf ("Error: Inputfile %s not found\n", inputfilename); return -1; } // Open outputfile, which will be RAW formatted char dummy[PATH_MAX]; strncpy(dummy,inputfilename,strlen(inputfilename)-4); sprintf(rawfilename, "%s.raw", dummy); if ((RAWfile = fopen (rawfilename, "w")) == NULL) { printf ("Error: Could not open outputfile %s\n", rawfilename); return -1; } //RAW file starts with a Runheader, but not all information is known at this // point, so an empty header is written, and filled after the inputfile was processed. write_RAWheader (rawBoard, RawRunHeader, RAWfile); // reading FAD input file. counting number of events in file. // Write FAD-Data to FAD-struct int Number_of_Events_in_File =0; for (int evnt_cnt = 0;; evnt_cnt++) { // reading package header // try to read START PACKAGE FLAG = 0xFB01 ... if reading fails, EOF found. if (fread (&FadEvent.evnt_header.start_package_flag, sizeof (FadEvent.evnt_header.start_package_flag), 1, faddatafile) != 1) { // end of file reached Number_of_Events_in_File = evnt_cnt; std::cout << evnt_cnt << " events counted.\n"; break; } if(ntohs (FadEvent.evnt_header.start_package_flag) != 0xFB01){ printf ("Error: Wrong start package flag in event %d\n", evnt_cnt); exit (1); } fread (&FadEvent.evnt_header.package_length, sizeof (FadEvent.evnt_header.package_length), 1, faddatafile); fread (&FadEvent.evnt_header.version_no, sizeof (FadEvent.evnt_header.version_no), 1, faddatafile); fread (&FadEvent.evnt_header.trigger_id, sizeof (FadEvent.evnt_header.trigger_id), 1, faddatafile); fread (&FadEvent.evnt_header.trigger_type, sizeof (FadEvent.evnt_header.trigger_type), 1, faddatafile); fread (&FadEvent.evnt_header.trigger_crc, sizeof (FadEvent.evnt_header.trigger_crc), 1, faddatafile); fread (&FadEvent.evnt_header.local_trigger_id, sizeof (FadEvent.evnt_header.local_trigger_id), 1, faddatafile); fread (&FadEvent.evnt_header.local_trigger_type, sizeof (FadEvent.evnt_header.local_trigger_type), 1, faddatafile); fread (&FadEvent.evnt_header.local_trigger_crc, sizeof (FadEvent.evnt_header.local_trigger_crc), 1, faddatafile); fread (&FadEvent.evnt_header.board_id, sizeof (FadEvent.evnt_header.board_id), 1, faddatafile); RawEventHeader.EventNumber = ntohl(FadEvent.evnt_header.local_trigger_id); RawEventHeader.TriggerType = ntohs(FadEvent.evnt_header.local_trigger_type); RawEventHeader.Second = starttime.tv_sec; // Event time stamp (result of gettimeofday()) RawEventHeader.Microsecond = starttime.tv_usec; RawEventHeader.TriggerType = FadEvent.evnt_header.local_trigger_type; // read out temperatures and sum them up // i need some dummy variables here long SumOfRois =0; int ThisRoi=0; int start_cell_dummy =0; for (int i = 0; i < DPF; i++) { fread (&FadEvent.evnt_header.drs_temperature[i], sizeof (FadEvent.evnt_header.drs_temperature[i]), 1, faddatafile); // if MSB = sign bit is set. if ((ntohs (FadEvent.evnt_header.drs_temperature[i]) & 0x8000) == 0) // temp is positive { temperature += float(ntohs (FadEvent.evnt_header.drs_temperature[i]) >> 3)/16; } else // temp is negative { temperature += float(0xE000 | (ntohs (FadEvent.evnt_header.drs_temperature[i])) >> 3)/16; } } // DAC Values, only if version > 0x0101 if (ntohs (FadEvent.evnt_header.version_no) > 0x0101) { for (int i = 0; i < 8; i++) { fread (&FadEvent.evnt_header.dac[i], sizeof (FadEvent.evnt_header.dac[i]), 1, faddatafile); } } SumOfRois = 0; ThisRoi = 0; for (int i = 0; i < (DPF * CPC); i++) // for loop over DPFxCPC channels .. i.e. 36 channels in our case. { // read channel header // ID fread (&FadEvent.channel[i].channel_id, sizeof (FadEvent.channel[i].channel_id), 1, faddatafile); // start cell fread (&FadEvent.channel[i].channel_start_cell, sizeof (FadEvent.channel[i].channel_start_cell), 1, faddatafile); // region of interest fread (&FadEvent.channel[i].channel_roi, sizeof (FadEvent.channel[i].channel_roi), 1, faddatafile); ThisRoi = ntohs(FadEvent.channel[i].channel_roi); SumOfRois += ThisRoi; // allocate memory and read channel data FadEvent.channel[i].channel_adc_data = (unsigned short*) calloc (ThisRoi, sizeof (unsigned short)); fread (FadEvent.channel[i].channel_adc_data, sizeof (unsigned short), ThisRoi, faddatafile); } // now I know everything about this Event and can write the run header. // write RAW Event Header RawEventHeader.EventSize = SumOfRois * sizeof(short) + DPF * sizeof(int) * RawRunHeader.NBoards; // THE TRIGGER CELLS ARE PART OF THE EVENT SIZE (+16)!!!!!!! fwrite(&RawEventHeader.EventNumber, (size_t) sizeof(RawEventHeader.EventNumber), 1, RAWfile); fwrite(&RawEventHeader.Second, (size_t) sizeof(RawEventHeader.Second), 1, RAWfile); fwrite(&RawEventHeader.Microsecond, (size_t) sizeof(RawEventHeader.Microsecond), 1, RAWfile); fwrite(&RawEventHeader.TriggerType, (size_t) sizeof(RawEventHeader.TriggerType), 1, RAWfile); fwrite(&RawEventHeader.EventSize, (size_t) sizeof(RawEventHeader.EventSize), 1, RAWfile); // write trigger cells // these triger cells are the so called channel_start cells ...I read out of the fad // input data file. // I read out the channels in this order: 00 10 20 30 01 11 21 31 .. 28 38. // so the four trigger cell I need are stored in the first // four channels of each event. for(unsigned int l=0; l < RawRunHeader.NBoards*RawRunHeader.NChips; l++){ start_cell_dummy = int(ntohs(FadEvent.channel[l].channel_start_cell)); fwrite(&start_cell_dummy, sizeof(int), 1, RAWfile); } // okay now i can write the 36 channels into the data file. // but they were stored in a different manner ... so we have // to do this carefully // // oh and in addition. the data is not yet in a nice PC readable format. // its still in 12bit signed twis complement + out-of-range-bit with leading zeroes. // we have to transform it into nice signed shorts. // for loop over DPFxCPC channels .. i.e. 36 channels in our case. for (int chip =0 ; chip < DPF ; ++chip) { for (int ch = 0; ch < CPC; ++ch) { // we want to walk like this: 0 4 8 12 .. 32 1 5 9 .. 33 2 6 10 ... 34 3 7 11 ... 35 for (int b =0 ; b < ntohs(FadEvent.channel[chip+DPF*ch].channel_roi) ; b++) { convert = ntohs(FadEvent.channel[chip+DPF*ch].channel_adc_data[b]); //if(convert == 0x1FFF) convert = 0x7FFF; //set value for overflow //else if(convert == 0x1000)convert = 0x8000; //set value for underflow (convert <<= 4) >>= 4; //delete the sign-bit by shifting left and shift back fwrite (&convert , sizeof(unsigned short) , 1 , RAWfile); } } } for (int i = 0; i < (DPF * CPC); i++) // for loop over DPFxCPC channels .. i.e. 36 channels in our case. { // free memory of channel data free (FadEvent.channel[i].channel_adc_data); } // CRC, only if version > 0x0100 if (ntohs (FadEvent.evnt_header.version_no) > 0x0100) { fread (&FadEvent.package_crc, sizeof (FadEvent.package_crc), 1, faddatafile); } // end package flag fread (&FadEvent.end_package_flag, sizeof (FadEvent.end_package_flag), 1, faddatafile); if(ntohs (FadEvent.end_package_flag) != 0x04FE){ printf ("Error: Wrong end package flag (%#x) in event %d\n", ntohs (FadEvent.end_package_flag), evnt_cnt); return -1; } } //FAD Data to RAW-struct //RunHeader RawRunHeader.MagicNum = 0xe0e0; RawRunHeader.DataFormat = 1; RawRunHeader.RunHeaderSize = sizeof(RawRunHeader); RawRunHeader.EventHeaderSize = sizeof(RawEventHeader); RawRunHeader.BoardStructureSize = sizeof(BoardStructure); RawRunHeader.SoftwareRevision = 0xFFFF; RawRunHeader.Identification = 0xFFFF; RawRunHeader.Type = 0; // Run type: 0=data, 1=pedestal, 3=test RawRunHeader.Events = Number_of_Events_in_File; RawRunHeader.RunNumber = runnum; RawRunHeader.FileNumber = 0; memset (RawRunHeader.Description, 0x00, sizeof (RawRunHeader.Description)); sprintf(RawRunHeader.Description,"FAD BOARD TEST"); RawRunHeader.NChips = DPF; // Number of DRS chips per board RawRunHeader.NChannels = CPC; // Number of channels per chip RawRunHeader.Samples = 1024; // Number of samples _only for test_ RawRunHeader.Offset= 0; // ??? Offset from trigger RawRunHeader.NBytes = 2; // Bytes per sample RawRunHeader.StartSecond = starttime.tv_sec; // Opening and closing time of the file RawRunHeader.StartMicrosecond = starttime.tv_usec; RawRunHeader.EndSecond = endtime.tv_sec; RawRunHeader.EndMicrosecond = endtime.tv_usec; for (unsigned int i=0; i < RawRunHeader.NBoards; i++) { rawBoard[i].SerialNo = board_ids[i]; // Board serial number rawBoard[i].NomFreq = 2; // Nominal sampling frequency [GHz] rawBoard[i].BoardTemp = temperature/(4*RawRunHeader.Events); // Board temperature [deg C] rawBoard[i].ScaleFactor = 1/2.048; // Factor for conversion to mV } // now all necessary information // to write RAW file header is known. // jump back to the beginning and rewind(RAWfile); // write the Raw header write_RAWheader (rawBoard, RawRunHeader, RAWfile); if(RawRunHeader.Events > 0){ printf("Could not find any events."); return -1; } fclose(RAWfile); fclose(faddatafile); return 0; } int write_RAWheader (BoardStructure *rawBoard, RunHeader& RawRunHeader, FILE *RAWfile) { // write header of rawfile fwrite (&RawRunHeader.MagicNum, (size_t) sizeof(RawRunHeader.MagicNum), 1, RAWfile); fwrite (&RawRunHeader.DataFormat, (size_t) sizeof(RawRunHeader.DataFormat), 1, RAWfile); fwrite (&RawRunHeader.RunHeaderSize, (size_t) sizeof(RawRunHeader.RunHeaderSize), 1, RAWfile); fwrite (&RawRunHeader.EventHeaderSize, (size_t) sizeof(RawRunHeader.EventHeaderSize), 1, RAWfile); fwrite (&RawRunHeader.BoardStructureSize, (size_t) sizeof(RawRunHeader.BoardStructureSize), 1, RAWfile); fwrite (&RawRunHeader.SoftwareRevision, (size_t) sizeof(RawRunHeader.SoftwareRevision), 1, RAWfile); fwrite (&RawRunHeader.Identification, (size_t) sizeof(RawRunHeader.Identification), 1, RAWfile); fwrite (&RawRunHeader.Type, (size_t) sizeof(RawRunHeader.Type), 1, RAWfile); fwrite (&RawRunHeader.RunNumber, (size_t) sizeof(RawRunHeader.RunNumber), 1, RAWfile); fwrite (&RawRunHeader.FileNumber, (size_t) sizeof(RawRunHeader.FileNumber), 1, RAWfile); fwrite (&RawRunHeader.Description, (size_t) sizeof(RawRunHeader.Description), 1, RAWfile); fwrite (&RawRunHeader.NBoards, (size_t) sizeof(RawRunHeader.NBoards), 1, RAWfile); fwrite (&RawRunHeader.NChips, (size_t) sizeof(RawRunHeader.NChips), 1, RAWfile); fwrite (&RawRunHeader.NChannels, (size_t) sizeof(RawRunHeader.NChannels), 1, RAWfile); fwrite (&RawRunHeader.Samples, (size_t) sizeof(RawRunHeader.Samples), 1, RAWfile); fwrite (&RawRunHeader.Offset, (size_t) sizeof(RawRunHeader.Offset), 1, RAWfile); fwrite (&RawRunHeader.Events, (size_t) sizeof(RawRunHeader.Events), 1, RAWfile); fwrite (&RawRunHeader.NBytes, (size_t) sizeof(RawRunHeader.NBytes), 1, RAWfile); fwrite (&RawRunHeader.StartSecond, (size_t) sizeof(RawRunHeader.StartSecond), 1, RAWfile); fwrite (&RawRunHeader.StartMicrosecond, (size_t) sizeof(RawRunHeader.StartMicrosecond), 1, RAWfile); fwrite (&RawRunHeader.EndSecond, (size_t) sizeof(RawRunHeader.EndSecond), 1, RAWfile); fwrite (&RawRunHeader.EndMicrosecond, (size_t) sizeof(RawRunHeader.EndMicrosecond), 1, RAWfile); // write boardstructure to RAW file for (unsigned int i=0; i < RawRunHeader.NBoards; i++) { fwrite (&rawBoard[i].SerialNo, (size_t) sizeof(rawBoard[i].SerialNo), 1, RAWfile); fwrite (&rawBoard[i].NomFreq, (size_t) sizeof(rawBoard[i].NomFreq), 1, RAWfile); fwrite (&rawBoard[i].BoardTemp, (size_t) sizeof(rawBoard[i].BoardTemp), 1, RAWfile); fwrite (&rawBoard[i].ScaleFactor, (size_t) sizeof(rawBoard[i].ScaleFactor), 1, RAWfile); } return 0; }