📄 maui_cal.c
字号:
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){ A_UINT16 numExtrema, numTotalExtrema ; A_UINT16 *extrema ; A_UINT16 ii, jj; numTotalExtrema = 0; extrema = (A_UINT16 *)malloc(pDataset->numChannels * sizeof(A_UINT16)) ; if (extrema == NULL) { uiPrintf("Could not allocate memory for extrema. Exiting...\n"); exit(0); } for (ii=0; ii<pDataset->pDataPerChannel[0].numPcdacValues; ii++) { pick_local_extrema(pDerivDataset, ii, extrema, &(numExtrema)) ; // numExtrema stores the number of extrema found for (jj=0; jj<numExtrema; jj++) { addUniqueElementToList(TPlist, extrema[jj], &(numTotalExtrema)); } } *totalTPs = numTotalExtrema ; qsort( (void *) TPlist, numTotalExtrema, sizeof(A_UINT16), numerical_compare) ; free(extrema);}void addUniqueElementToList(A_UINT16 *list, A_UINT16 element, A_UINT16 *listSize){ A_UINT16 ii = 0; A_BOOL isUnique = TRUE; A_UINT16 size = *listSize ; while ((ii<size) && (isUnique)) { if (element == list[ii]) { isUnique = FALSE; } ii++; } if (isUnique) { list[size] = element ; (*listSize) = size + 1 ; }}int numerical_compare( const void *arg1, const void *arg2 ){ A_INT16 comparison = 0; A_UINT16 val1 = * ( A_UINT16 * ) arg1; A_UINT16 val2 = * ( A_UINT16 * ) arg2; if (val1 > val2) comparison = 1; if (val1 < val2) comparison = -1; return ( comparison );}void pick_local_extrema(dPCDACS_EEPROM *pDataset, A_UINT16 pcd_idx, A_UINT16 *retList, A_UINT16 *listSize){ A_UINT16 ii; A_INT16 flatRunStartDirection, dirxn, newDirexn, midPoint ; A_UINT16 *flatRun ; A_UINT16 sizeFlatRun =0; A_UINT16 ch0, ch1, chN; double noise; double delta; A_UINT16 numTPs = 0; flatRun = (A_UINT16*)malloc(pDataset->numChannels * sizeof(A_UINT16)) ; if (flatRun == NULL) { uiPrintf("Could not allocate memory for list flatRun. Exiting...\n"); exit(0); } ch0 = pDataset->pChannels[0]; ch1 = pDataset->pChannels[1]; chN = pDataset->pChannels[pDataset->numChannels-1]; // noise calculated to ignore a change in slope causing a 1dB deviation over entire range // an adjustment factor of 10 seems to work better for a 30MHz measurement step noise = fabs(1.0/(10*(ch1-ch0)*(chN-ch0))) ; retList[numTPs] = ch0; numTPs++; flatRunStartDirection = 0; // implicitly indicates out of flatrun delta = (pDataset->pDataPerChannel[1].pPwrValues[pcd_idx] - pDataset->pDataPerChannel[0].pPwrVa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -