Example #1
0
    def load(self, fileName):
        #Load all the data in the file, exculding the fileInfos
        try:
            with open(os.path.join(fileName), 'r') as inFile:
                variablesToLoad = json.load(inFile)
                for key in variablesToLoad.keys():
                    if key in type(self).__slots__:
                        setattr(self, key, variablesToLoad[key])
                    else:
                        log.message(
                            DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 1,
                            f'Unexpected data was encountered during the loading of the testbench parameters. Faulty key: {key}'
                        )
                        if DEFINES.RAISE_ERROR_ON_UNEXPECTED_KEY:
                            raise errors.IOError(
                                'Unexpected data was encountered during the loading of the testbench parameters'
                            ) from None

            self.slotsCenters = np.array(self.slotsCenters)
            self.nbSlots = len(self.slotsCenters[:, 0])
            self.maxSlots = copy.deepcopy(self.nbSlots)
            self.originalSlotsCenters = copy.deepcopy(self.slotsCenters)

            self.clear_slots()

        except OSError:
            raise errors.IOError(
                'The testbench parameters file could not be found') from None
Example #2
0
    def load(self, fileName):
        try:
            #Load all the data in the file, exculding the fileInfos
            with open(os.path.join(fileName), 'r') as inFile:
                variablesToLoad = json.load(inFile)
                for key in variablesToLoad.keys():
                    if key in type(self).__slots__:
                        if isinstance(variablesToLoad[key], list):
                            setattr(self, key, np.array(variablesToLoad[key]))
                        else:
                            setattr(self, key, variablesToLoad[key])
                    elif key == 'alphaCommands':
                        alphaCommands = np.array(variablesToLoad[key])
                    elif key == 'betaCommands':
                        betaCommands = np.array(variablesToLoad[key])
                    elif key == 'alphaMeasures':
                        alphaMeasures = np.array(variablesToLoad[key])
                    elif key == 'betaMeasures':
                        betaMeasures = np.array(variablesToLoad[key])
                    else:
                        log.message(
                            DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 1,
                            f'Unexpected data was encountered during the loading of the positioner model. Faulty key: {key}'
                        )
                        if DEFINES.RAISE_ERROR_ON_UNEXPECTED_KEY:
                            raise errors.IOError(
                                'Unexpected data was encountered during the loading of the positioner model'
                            ) from None

            self.getCorrectedAlpha = interpolate.interp1d(
                alphaCommands,
                alphaMeasures,
                kind='linear',
                fill_value='extrapolate')
            self.getCorrectedBeta = interpolate.interp1d(
                betaCommands,
                betaMeasures,
                kind='linear',
                fill_value='extrapolate')

        except OSError:
            raise errors.IOError(
                'The positioner model file could not be found') from None
Example #3
0
    def load(self, fileName):
        #Load all the data in the file, exculding the fileInfos
        try:
            with open(os.path.join(fileName), 'r') as inFile:
                variablesToLoad = json.load(inFile)
                for key in variablesToLoad.keys():
                    if key in type(self).__slots__:
                        setattr(self, key, variablesToLoad[key])
                    else:
                        log.message(
                            DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 1,
                            f'Unexpected data was encountered during the loading of the positioner requirements. Faulty key: {key}'
                        )
                        if DEFINES.RAISE_ERROR_ON_UNEXPECTED_KEY:
                            raise errors.IOError(
                                'Unexpected data was encountered during the loading of the positioner requirements'
                            ) from None

        except OSError:
            raise errors.IOError(
                'The positioner requirements file could not be found'
            ) from None
Example #4
0
    def setDistortionCorrection(self, config):
        if self.connected:

            fileName = os.path.join(
                config.get_camera_path(), 'camera_' + str(self.parameters.ID) +
                config.cameraFileExtension)

            #load the camera distortion parameters
            try:
                cam_distortion = io.loadmat(fileName)
            except genicam.GenericException:
                raise errors.IOError(
                    "Camera distortion file could not be loaded") from None
                return

            try:
                cam_distortion = cam_distortion[
                    DEFINES.PC_FILE_DISTORTION_PARAMETERS_NAME]

                cam_x_corr = cam_distortion[
                    DEFINES.PC_FILE_DISTORTION_XCORR_NAME]
                cam_y_corr = cam_distortion[
                    DEFINES.PC_FILE_DISTORTION_YCORR_NAME]
                cam_scale_factor = cam_distortion[
                    DEFINES.PC_FILE_DISTORTION_SCALE_FACTOR_NAME]

                self.parameters.xCorr = np.nan_to_num(cam_x_corr[0, 0])
                self.parameters.yCorr = np.nan_to_num(cam_y_corr[0, 0])
                self.parameters.scaleFactor = cam_scale_factor[0, 0][0, 0]
            except genicam.GenericException:
                raise errors.IOError(
                    "Camera distortion file data is corrupted") from None

            return

        else:
            log.message(
                DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 0,
                'Trying to load calibration data of an unconnected camera')
Example #5
0
    def load_test_results(self, testResults, positionerIDs, lifetimeLoop=0):
        if len(testResults) is not len(positionerIDs):
            raise errors.Error(
                "Test result container has the wrong length") from None

        filePath = os.path.join( self.generalProjectFolder,\
               self.currentProjectFolder,\
               self.resultFolder)

        i = 0
        for positionerID in positionerIDs:
            if self.resultsLoadingFolder == DEFINES.CONFIG_LOAD_LATEST_RESULT:
                resultPath = self.get_latest_positioner_folder(positionerID)
                if resultPath == '':
                    raise errors.IOError(
                        f'Positioner {positionerID:04d} results folder not found'
                    ) from None
            else:
                resultPath = self.resultsLoadingFolder

            resultPath = os.path.join( filePath,\
                   self.positionerFolderPrefix+'_'+str(positionerID),\
                   resultPath)

            if self.check_folder_is_lifetime(resultPath):
                resultPath = os.path.join( resultPath,\
                       self.lifetimeIterationFolderName+'_'+str(lifetimeLoop+1))

            try:
                testResults[i].load(os.path.join( resultPath,\
                         self.testResultsFile+self.testResultsFileExt))
            except errors.IOError:
                log.message(DEFINES.LOG_MESSAGE_PRIORITY_ERROR, 0, str(e))
                raise errors.IOError(
                    f'Positioner {positionerID:04d} test results loading failed'
                ) from None

            i += 1
Example #6
0
    def save_QC_result(self, calibResults=[], testResults=[]):
        #Open the file
        if os.path.isfile(
                os.path.join(self.generalProjectFolder,
                             self.currentProjectFolder,
                             self.resultsOverviewFile)):
            #The file exists in the project
            if os.path.isfile(
                    os.path.join(self.generalConfigFolder, self.configFolder,
                                 self.resultsOverviewAutosave)):
                #autosave exists from a previous failed save. load from it and delete it
                wb = openpyxl.load_workbook(
                    os.path.join(self.generalConfigFolder, self.configFolder,
                                 self.resultsOverviewAutosave))
                os.remove(
                    os.path.join(self.generalConfigFolder, self.configFolder,
                                 self.resultsOverviewAutosave))
            else:
                wb = openpyxl.load_workbook(
                    os.path.join(self.generalProjectFolder,
                                 self.currentProjectFolder,
                                 self.resultsOverviewFile))

        elif os.path.isfile(
                os.path.join(self.generalConfigFolder, self.configFolder,
                             self.resultsOverviewTemplateFile)):
            #The template exists
            wb = openpyxl.load_workbook(
                os.path.join(self.generalConfigFolder, self.configFolder,
                             self.resultsOverviewTemplateFile))
        else:
            raise errors.IOError(
                'QC file: Neither the file nor the template do exist'
            )  #Neither the file nor the template do exist

        #Write results to the file
        ws1 = wb["Results"]

        if calibResults is not []:
            nbSlots = len(calibResults)
        else:
            nbSlots = len(testResults)

        for slot in range(0, nbSlots):
            QCpassed = False
            repeatabilityChecked = False
            hysteresisChecked = False
            writeLine = None
            if calibResults is not [] and slot < len(calibResults):
                alphaLength = calibResults[slot].mesAlphaLength[-1]
                betaLength = calibResults[slot].mesBetaLength[-1]
                RMSModelFit = calibResults[slot].mesRMSModelFit[-1]
                RMSRepeatability = calibResults[slot].mesRMSRepeatability[-1]
                maxHysteresis = calibResults[slot].mesMaxHysteresis[-1]
                maxNonLinearity = calibResults[slot].mesMaxNL[-1]
                maxNonLinDerivative = calibResults[slot].mesMaxNLDerivative[-1]
                RMSalignmentError = calibResults[slot].mesRMSAlignmentError[-1]
                maxAlignmentError = calibResults[slot].mesMaxAlignmentError[-1]
                roundnessDeviation = calibResults[slot].mesMaxRoundnessError[
                    -1]

                alphaLengthPassed = abs(
                    alphaLength -
                    calibResults[slot].requirements.nominalAlphaLength
                ) <= calibResults[slot].requirements.maxAlphaLengthDeviation
                betaLengthPassed = abs(
                    betaLength -
                    calibResults[slot].requirements.nominalBetaLength
                ) <= calibResults[slot].requirements.maxBetaLengthDeviation
                RMSModelFitPassed = RMSModelFit <= calibResults[
                    slot].requirements.maxPosError
                RMSRepeatabilityPassed = RMSRepeatability <= calibResults[
                    slot].requirements.rmsPosRepeatability
                maxHysteresisPassed = maxHysteresis <= calibResults[
                    slot].requirements.maxHysteresis
                maxNonLinearityPassed = maxNonLinearity <= calibResults[
                    slot].requirements.maxNonLinearity
                maxNonLinDerivativePassed = maxNonLinDerivative <= calibResults[
                    slot].requirements.maxNonLinearityDerivative
                roundnessDeviationPassed = roundnessDeviation <= calibResults[
                    slot].requirements.maxRoundnessDeviation

                QCpassed =  alphaLengthPassed and\
                   betaLengthPassed and\
                   maxNonLinearityPassed and\
                   maxNonLinDerivativePassed and\
                   roundnessDeviationPassed

                if not np.isnan(RMSRepeatability):
                    QCpassed = QCpassed and RMSRepeatabilityPassed
                    repeatabilityChecked = True

                if not np.isnan(maxHysteresis):
                    QCpassed = QCpassed and maxHysteresisPassed
                    hysteresisChecked = True
                else:
                    QCpassed = False

                fontPassed = openpyxl.styles.Font(color="008000")
                fontFailed = openpyxl.styles.Font(color="FF0000")

                #get line to write. Either the first writable line or the line matching the ID
                i = 2
                while ws1.cell(row=i, column=1).value is not None and not (
                        ws1.cell(row=i, column=1).value
                        == calibResults[slot].positionerID):
                    i += 1

                writeLine = i

                ws1.cell(row=writeLine,
                         column=1,
                         value=calibResults[slot].positionerID)  #A: ID
                ws1.cell(row=writeLine,
                         column=3,
                         value=calibResults[slot].config.currentProjectTime
                         )  #C: Calib time
                ws1.cell(row=writeLine,
                         column=5,
                         value=calibResults[slot].testBenchName)  #E: Bench
                ws1.cell(row=writeLine,
                         column=6,
                         value=int(calibResults[slot].slotID))  #F: Slot ID

                currentCell = ws1.cell(row=writeLine,
                                       column=7,
                                       value=alphaLength)  #G: Alpha length
                if alphaLengthPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=8,
                                       value=betaLength)  #H: Beta length
                if betaLengthPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=9,
                                       value=RMSModelFit)  #I: Model fit
                if RMSModelFitPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(
                    row=writeLine, column=10,
                    value=RMSRepeatability)  #J: Repeatability
                if RMSRepeatabilityPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=11,
                                       value=maxHysteresis)  #K: Hysteresis
                if maxHysteresisPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=12,
                                       value=maxNonLinearity)  #L: NL
                if maxNonLinearityPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(
                    row=writeLine, column=13,
                    value=maxNonLinDerivative)  #M: NL derivative
                if maxNonLinDerivativePassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=14,
                                       value=roundnessDeviation)  #N: Roundness
                if roundnessDeviationPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

            if testResults is not [] and slot < len(testResults):
                nbRepetitions, nbTargets, maxNbMoves, nbDims = testResults[
                    slot].targets.shape
                nbPoints = nbTargets * nbRepetitions

                RMSErrorFirstMove = testResults[slot].mesRMSError1stMove[-1]
                RMSRepeatabilityFirstMove = testResults[
                    slot].mesRMSRepeatability1stMove[-1]
                targetConvergeance = testResults[slot].mesTargetConvergeance[
                    -1][-1]
                maxNbMoves = testResults[slot].mesMaxNbMoves[-1]

                RMSErrorFirstMovePassed = RMSErrorFirstMove <= testResults[
                    slot].requirements.maxPosError
                RMSRepeatabilityFirstMovePassed = RMSRepeatabilityFirstMove <= testResults[
                    slot].requirements.rmsPosRepeatability
                targetConvergeancePassed = targetConvergeance >= testResults[
                    slot].requirements.targetConvergeance
                maxNbMovesPassed = maxNbMoves <= testResults[
                    slot].requirements.maxNbMoves

                #get line to write. Either the first writable line or the line matching the ID
                if writeLine is None:
                    i = 2
                    while ws1.cell(row=i, column=1).value is not None and not (
                            ws1.cell(row=i, column=1).value
                            == testResults[slot].positionerID):
                        i += 1

                    writeLine = i

                currentCell = ws1.cell(row=writeLine,
                                       column=4,
                                       value=testResults[slot].config.
                                       currentProjectTime)  #D: Test time

                currentCell = ws1.cell(
                    row=writeLine, column=15,
                    value=RMSErrorFirstMove)  #O: Test RMS error
                if RMSErrorFirstMovePassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=16,
                                       value=RMSRepeatabilityFirstMove
                                       )  #P: Test RMS repeatability
                if RMSRepeatabilityFirstMovePassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(
                    row=writeLine, column=17,
                    value=targetConvergeance)  #Q: Test convergeance
                if targetConvergeancePassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                currentCell = ws1.cell(row=writeLine,
                                       column=18,
                                       value=maxNbMoves)  #R: Test max moves
                if maxNbMovesPassed:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

                if not repeatabilityChecked:
                    if not np.isnan(RMSRepeatabilityFirstMove):
                        QCpassed = QCpassed and RMSRepeatabilityFirstMovePassed
                    else:  #Fail the result if the repeatability was not checked
                        QCpassed = False

            if QCpassed and repeatabilityChecked and hysteresisChecked:
                QCresult = 'PASSED'
            else:
                QCresult = 'FAILED'

            if writeLine is not None:
                currentCell = ws1.cell(row=writeLine, column=2,
                                       value=QCresult)  #B: QA result
                if QCpassed and repeatabilityChecked and hysteresisChecked:
                    currentCell.font = fontPassed
                else:
                    currentCell.font = fontFailed

        #save the file
        try:
            wb.save(
                os.path.join(self.generalProjectFolder,
                             self.currentProjectFolder,
                             self.resultsOverviewFile))
        except PermissionError:  #If the file is already opened, autosave a copy in the template folder
            wb.save(
                os.path.join(self.generalConfigFolder, self.configFolder,
                             self.resultsOverviewAutosave))