📄 maui_cal.c
字号:
fprintf(fStream, " \t");
for (i = 0; i < pEepromData->numChannels; i++) {
fprintf(fStream,"%d\t", pEepromData->pChannels[i]);
}
fprintf(fStream,"\n");
//print the pcdac values for each frequency
for(j = 0; j < pEepromData->pDataPerChannel[0].numPcdacValues ; j++) {
fprintf(fStream,"%d\t", pEepromData->pDataPerChannel[0].pPcdacValues[j]);
for(i = 0; i < pEepromData->numChannels; i++) {
pChannelData = &(pEepromData->pDataPerChannel[i]);
//fprintf(fStream,"%2.2f\t", pChannelData->pPwrValues[j]);
fprintf(fStream,"%f\t", pChannelData->pPwrValues[j]);
}
fprintf(fStream,"\n");
}
fclose(fStream);
}
void dump_nonrectangular_grid_to_file( dPCDACS_EEPROM *pEepromData, char *filename )
{
A_UINT16 i, j;
FILE *fStream;
if (CalSetup.customerDebug)
uiPrintf("\nWriting to file %s\n", filename);
if( (fStream = fopen( filename, "w")) == NULL ) {
uiPrintf("Failed to open %s - using Defaults\n", filename);
return;
}
//print the frequency values
fprintf(fStream, " \t");
for (i = 0; i < pEepromData->numChannels; i++) {
fprintf(fStream,"%d: pcdacMin=%d, pcdacMax=%d\n", pEepromData->pChannels[i],
pEepromData->pDataPerChannel[i].pcdacMin,
pEepromData->pDataPerChannel[i].pcdacMax);
//print the pcdac values for each frequency
for(j = 0; j < pEepromData->pDataPerChannel[0].numPcdacValues ; j++) {
fprintf(fStream,"%d: %2.1f\n", pEepromData->pDataPerChannel[i].pPcdacValues[j],
pEepromData->pDataPerChannel[i].pPwrValues[j]);
}
fprintf(fStream, "\n\n");
}
fclose(fStream);
}
void make_cal_dataset_from_raw_dataset()
{
A_UINT16 numPiers ;
A_UINT16 i ;
A_UINT16 channelValue;
A_UINT16 numAllChannels, numAllPcdacs;
A_UINT16 stepAllChannels = 5;
A_UINT16 *AllPcdacs ;
A_UINT16 numPcdacs;
A_UINT16 *turning_points ;
A_UINT16 filter_size = 2;
A_UINT16 data_ceiling = 30 ; // max dB in raw measured data
A_UINT16 debug = CalSetup.customerDebug;
dPCDACS_EEPROM SnapshotDataset;
dPCDACS_EEPROM *pSnapshotDataset = &SnapshotDataset;
numPcdacs = sizeOfRawPcdacs;
if ( eepromType == EEPROM_SIZE_16K )
{
numPiers = NUM_PIERS ;
}
if(!d_allocateEepromStruct( pCalDataset, numPiers, goldenParams.numIntercepts )) {
uiPrintf("unable to allocate eeprom struct pCalDataset. Exiting...\n");
exit(0);
}
pCalDataset->hadIdenticalPcdacs = FALSE ;
numAllChannels = (goldenParams.channelStop - goldenParams.channelStart)/stepAllChannels + 1;
numAllPcdacs = (goldenParams.pcdacStop - goldenParams.pcdacStart)/goldenParams.pcdacStep + 1;
if(!d_allocateEepromStruct( pFullDataset, numAllChannels, numAllPcdacs )) {
uiPrintf("unable to allocate eeprom struct pFullDataset. Exiting...\n");
exit(0);
}
pFullDataset->hadIdenticalPcdacs = TRUE ;
AllPcdacs = (A_UINT16 *) malloc(numAllPcdacs*sizeof(A_UINT16)) ;
for (i = 0; i < numAllPcdacs; i++) {
AllPcdacs[i] = goldenParams.pcdacStart + i*goldenParams.pcdacStep ;
}
for (i = 0; i < numAllChannels; i++) {
channelValue = goldenParams.channelStart + i*stepAllChannels;
pFullDataset->pChannels[i] = channelValue;
pFullDataset->pDataPerChannel[i].channelValue = channelValue;
pFullDataset->pDataPerChannel[i].numPcdacValues = numAllPcdacs ;
memcpy(pFullDataset->pDataPerChannel[i].pPcdacValues, AllPcdacs, numAllPcdacs*sizeof(A_UINT16));
pFullDataset->pDataPerChannel[i].pcdacMin = pFullDataset->pDataPerChannel[i].pPcdacValues[0];
pFullDataset->pDataPerChannel[i].pcdacMax = pFullDataset->pDataPerChannel[i].pPcdacValues[numPcdacs - 1];
}
turning_points = (A_UINT16 *) malloc(numRAWChannels * sizeof(A_UINT16) ) ;
if (NULL == turning_points)
{
uiPrintf("Could not allocate space for turning points\n");
exit(0);
}
if(CalSetup.forcePiers && !CalSetup.readFromFile)
{
if(CalSetup.numForcedPiers > numPiers)
{
uiPrintf("ERROR: %d piers specified in FORCE_PIERS_LIST in calsetup.txt\n", CalSetup.numForcedPiers);
uiPrintf("A maximum of %d are allowed.\n", numPiers);
exit(0);
}
for (i=0; i<CalSetup.numForcedPiers; i++)
{
turning_points[i] = (A_UINT16) CalSetup.piersList[i];
}
while (i < numPiers)
{
turning_points[i++] = (A_UINT16) CalSetup.piersList[CalSetup.numForcedPiers-1];
}
truncate_hash_subzero(pRawDataset) ;
} else
{
find_optimal_pier_locations(turning_points, numPiers, filter_size, data_ceiling, debug);
}
if(!d_allocateEepromStruct( &SnapshotDataset, numPiers, numPcdacs )) {
uiPrintf("unable to allocate eeprom struct pSnapshotDataset. Exiting...\n");
exit(0);
}
pSnapshotDataset->hadIdenticalPcdacs = TRUE ;
for (i = 0; i < numPiers; i++) {
channelValue = turning_points[i];
pSnapshotDataset->pChannels[i] = channelValue;
pSnapshotDataset->pDataPerChannel[i].channelValue = channelValue;
memcpy(pSnapshotDataset->pDataPerChannel[i].pPcdacValues, RAW_PCDACS, sizeOfRawPcdacs );
pSnapshotDataset->pDataPerChannel[i].pcdacMin = pSnapshotDataset->pDataPerChannel[i].pPcdacValues[0];
pSnapshotDataset->pDataPerChannel[i].pcdacMax = pSnapshotDataset->pDataPerChannel[i].pPcdacValues[numAllPcdacs - 1];
}
dMapGrid(pRawDataset, pSnapshotDataset);
if (CalSetup.customerDebug)
dump_rectangular_grid_to_file(pSnapshotDataset, "junkcal.log");
build_cal_dataset_skeleton(pRawDataset, pCalDataset, goldenParams.pInterceptPercentages,
goldenParams.numIntercepts, turning_points, numPiers);
dMapGrid(pRawDataset, pCalDataset);
quantize_hash(pCalDataset);
if(CalSetup.customerDebug) {
dump_nonrectangular_grid_to_file(pCalDataset, "junkToee.log");
}
d_freeEepromStruct(pSnapshotDataset);
free(AllPcdacs);
free(turning_points);
}
void find_optimal_pier_locations(A_UINT16 *turning_points, A_UINT16 numTPsToPick, double filter_size, A_UINT16 data_ceiling, A_UINT16 debug)
{
A_UINT32 filter_iterations = 1;
dPCDACS_EEPROM deriv1Struct;
dPCDACS_EEPROM deriv2Struct ;
dPCDACS_EEPROM *deriv1 = &deriv1Struct;
dPCDACS_EEPROM *deriv2 = &deriv2Struct;
A_UINT16 *allTPs;
A_UINT16 numAllTPs ;
A_UINT16 i;
TP_VAL tp_totempole_Struct;
TP_VAL *tp_totempole = &tp_totempole_Struct;
for (i=0; i<filter_iterations; i++)
{
filter_hash(pRawDataset, filter_size, data_ceiling);
}
truncate_hash_subzero(pRawDataset) ;
if (CalSetup.customerDebug)
dump_rectangular_grid_to_file(pRawDataset, "junkg.log");
if (!d_allocateEepromStruct(deriv1, pRawDataset->numChannels, pRawDataset->pDataPerChannel[0].numPcdacValues))
{
uiPrintf("Could not allocate deriv1 data structure. Exiting...\n");
exit(0);
}
differentiate_hash(pRawDataset, deriv1);
if (CalSetup.customerDebug)
dump_rectangular_grid_to_file(deriv1, "junks.log");
if (!d_allocateEepromStruct(deriv2, pRawDataset->numChannels, pRawDataset->pDataPerChannel[0].numPcdacValues))
{
uiPrintf("Could not allocate deriv2 data structure. Exiting...\n");
exit(0);
}
differentiate_hash(deriv1, deriv2);
if (CalSetup.customerDebug)
dump_rectangular_grid_to_file(deriv2, "junkss.log");
allTPs = (A_UINT16 *) malloc(numRAWChannels * sizeof(A_UINT16) ) ;
if (NULL == allTPs)
{
uiPrintf("Could not allocate space for allTPs \n");
exit(0);
}
build_turning_points(pRawDataset, deriv2, allTPs, &(numAllTPs), debug);
consolidate_turning_points(&(allTPs), &(numAllTPs), debug);
// allTPs now points to the consolidated TPs and the numAllTPs has also been adjusted.
if (debug)
{
uiPrintf("Consolidated turning points are: ");
for (i=0; i<numAllTPs; i++)
{
uiPrintf("%d, ", allTPs[i]);
}
uiPrintf("\n");
}
build_turningpoint_totempole(pRawDataset, &(tp_totempole), numAllTPs, allTPs, debug);
qsort( (void *) tp_totempole, numAllTPs, sizeof(TP_VAL), totempole_compare) ;
for (i=0; i<numTPsToPick; i++)
{
if (i < numAllTPs) {
turning_points[i] = pRawDataset->pChannels[tp_totempole[i].channel_idx] ;
} else {
turning_points[i] = pRawDataset->pChannels[tp_totempole[0].channel_idx] ;
}
}
qsort((void *)turning_points, numTPsToPick, sizeof(A_UINT16), numerical_compare);
d_freeEepromStruct(deriv1);
d_freeEepromStruct(deriv2);
free(allTPs);
free(tp_totempole);
}
// ALGORITHM : the purpose of this routine is to filter SINGLE POINT SPIKES only.
// 1. if you've filtered the previous point - ignore the current one.
// 2. if currval > upperbound then filter currval
// 3. if currval deviates from neighbors mean by more than the filterSize BUT the neighbors themselves
// are within the filterSize, then filter currval.
//
// NOTE: this algorithm is NOT designed to handle extended set of deviant points.
//
void filter_hash(dPCDACS_EEPROM *pDataset, double filter_size, double data_ceiling)
{
A_UINT16 pcd, ii, jj, freq ;
double avgii, diffii;
A_UINT16 filteredOne = 0;
dDATA_PER_CHANNEL *prevChannel ;
dDATA_PER_CHANNEL *currChannel ;
dDATA_PER_CHANNEL *nextChannel ;
for (jj=0; jj<pDataset->pDataPerChannel[0].numPcdacValues; jj++)
{
currChannel = &(pDataset->pDataPerChannel[0]);
nextChannel = &(pDataset->pDataPerChannel[1]);
pcd = currChannel->pPcdacValues[jj];
filteredOne = 0;
// filter the 1st point
if ( (currChannel->pPwrValues[jj] > data_ceiling) ||
( fabs(currChannel->pPwrValues[jj] - nextChannel->pPwrValues[jj]) > data_ceiling) )
{
currChannel->pPwrValues[jj] = nextChannel->pPwrValues[jj] ;
filteredOne = 1;
}
// filter elements 1..N-1
for ( ii=1; ii<(pDataset->numChannels - 1); ii++)
{
freq = pDataset->pChannels[ii];
prevChannel = &(pDataset->pDataPerChannel[ii-1]);
currChannel = &(pDataset->pDataPerChannel[ii]);
nextChannel = &(pDataset->pDataPerChannel[ii+1]);
if (filteredOne > 0)
{
filteredOne = 0;
continue ;
} else
{
avgii = (prevChannel->pPwrValues[jj] + nextChannel->pPwrValues[jj]) / 2.0;
diffii = fabs(prevChannel->pPwrValues[jj] - nextChannel->pPwrValues[jj]);
if ( (currChannel->pPwrValues[jj] > data_ceiling) ||
((fabs(currChannel->pPwrValues[jj] - avgii) > data_ceiling) && (diffii <= data_ceiling)) )
{
if (WARNINGS_ON)
uiPrintf("Filtering %d, %d datapoint from %2.1f to %2.1f\n", freq, pcd, currChannel->pPwrValues[jj], avgii);
currChannel->pPwrValues[jj] = avgii ;
filteredOne = 1;
}
}
}
// filter the Nth point
ii = pDataset->numChannels - 1;
prevChannel = &(pDataset->pDataPerChannel[ii-1]);
currChannel = &(pDataset->pDataPerChannel[ii]);
if ( ( (currChannel->pPwrValues[jj] > data_ceiling) ||
(fabs(currChannel->pPwrValues[jj] - prevChannel->pPwrValues[jj]) > data_ceiling) ) &&
(filteredOne < 1) )
{
currChannel->pPwrValues[jj] = prevChannel->pPwrValues[jj] ;
filteredOne = 1;
}
}
}
void truncate_hash_subzero(dPCDACS_EEPROM *pDataset)
{
A_UINT16 ii, jj;
dDATA_PER_CHANNEL *currChannel ;
for (ii=0; ii<pDataset->numChannels; ii++)
{
currChannel = &(pDataset->pDataPerChannel[ii]);
for (jj=0; jj<currChannel->numPcdacValues; jj++)
{
if (currChannel->pPwrValues[jj] < 0.0)
currChannel->pPwrValues[jj] = 0.0;
}
}
}
void differentiate_hash(dPCDACS_EEPROM *srcStruct, dPCDACS_EEPROM *destStruct)
{
A_UINT16 ii, jj ;
double diffii;
dDATA_PER_CHANNEL *currChannel ;
diffii = (double) 2.0*(srcStruct->pChannels[1] - srcStruct->pChannels[0]) ;
destStruct->hadIdenticalPcdacs = TRUE;
memcpy(destStruct->pChannels, srcStruct->pChannels, srcStruct->numChannels * sizeof(A_UINT16));
for (ii=0; ii<destStruct->numChannels; ii++)
{
currChannel = &(destStruct->pDataPerChannel[ii]);
currChannel->pcdacMax = srcStruct->pDataPerChannel[ii].pcdacMax ;
currChannel->pcdacMin = srcStruct->pDataPerChannel[ii].pcdacMin ;
memcpy(currChannel->pPcdacValues, srcStruct->pDataPerChannel[ii].pPcdacValues, currChannel->numPcdacValues*sizeof(A_UINT16));
}
for (jj=0; jj<destStruct->pDataPerChannel[0].numPcdacValues; jj++)
{
destStruct->pDataPerChannel[0].pPwrValues[jj] = (double)2.0*( srcStruct->pDataPerChannel[1].pPwrValues[jj] -
srcStruct->pDataPerChannel[0].pPwrValues[jj] )/diffii ;
for (ii=1; ii<(destStruct->numChannels-1); ii++)
{
destStruct->pDataPerChannel[ii].pPwrValues[jj] = (double)( srcStruct->pDataPerChannel[ii+1].pPwrValues[jj] -
srcStruct->pDataPerChannel[ii-1].pPwrValues[jj] )/diffii ;
}
ii = destStruct->numChannels-1 ;
destStruct->pDataPerChannel[ii].pPwrValues[jj] = (double)2.0*( srcStruct->pDataPerChannel[ii-1].pPwrValues[jj] -
srcStruct->pDataPerChannel[ii].pPwrValues[jj] )/diffii ;
}
}
void build_turning_points(dPCDACS_EEPROM *pDataset, dPCDACS_EEPROM *pDerivDataset, A_UINT16 *TPlist, A_UINT16 *totalTPs, A_UINT16 debug)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -