void StimulusDisplay::getDisplayBounds(const Datum &display_info, GLdouble &left, GLdouble &right, GLdouble &bottom, GLdouble &top) { if(display_info.getDataType() == M_DICTIONARY && display_info.hasKey(M_DISPLAY_WIDTH_KEY) && display_info.hasKey(M_DISPLAY_HEIGHT_KEY) && display_info.hasKey(M_DISPLAY_DISTANCE_KEY)){ GLdouble width_unknown_units = display_info.getElement(M_DISPLAY_WIDTH_KEY); GLdouble height_unknown_units = display_info.getElement(M_DISPLAY_HEIGHT_KEY); GLdouble distance_unknown_units = display_info.getElement(M_DISPLAY_DISTANCE_KEY); GLdouble half_width_deg = (180. / M_PI) * atan((width_unknown_units/2.)/distance_unknown_units); GLdouble half_height_deg = half_width_deg * height_unknown_units / width_unknown_units; //GLdouble half_height_deg = (180. / M_PI) * atan((height_unknown_units/2.)/distance_unknown_units); left = -half_width_deg; right = half_width_deg; top = half_height_deg; bottom = -half_height_deg; } else { left = M_STIMULUS_DISPLAY_LEFT_EDGE; right = M_STIMULUS_DISPLAY_RIGHT_EDGE; top = M_STIMULUS_DISPLAY_TOP_EDGE; bottom = M_STIMULUS_DISPLAY_BOTTOM_EDGE; } }
// overridable base class method // assumes data have already been checked for proper dictionary, name. CalibratorRequestedAction Calibrator::getRequestedAction(Datum dictionaryData) { // check what action is requested (e.g. update parameters) if (!(dictionaryData.hasKey(R_CALIBRATOR_ACTION))) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Request sent to calibrator %s that did not contain an action field was ignored.", uniqueCalibratorName.c_str()); return(CALIBRATOR_NO_ACTION); } Datum actionData = dictionaryData.getElement(R_CALIBRATOR_ACTION); if (!(actionData.getDataType() == M_STRING)) { // check if name field is a string mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Request sent to calibrator %s that did not contain a string in the action field was ignored.", uniqueCalibratorName.c_str()); return(CALIBRATOR_NO_ACTION); } if (actionData.getString() == R_CALIBRATOR_ACTION_SET_PARAMETERS) { // check is name field matches the name of this calibrator if (VERBOSE_EYE_CALIBRATORS>1) mprintf( "Calibrator %s successfully received request for to update its parameters to contained values.", uniqueCalibratorName.c_str()); return CALIBRATOR_ACTION_SET_PARAMS_TO_CONTAINED; } else if (actionData.getString() == R_CALIBRATOR_ACTION_SET_PARAMETERS_TO_DEFAULTS) { if (VERBOSE_EYE_CALIBRATORS>1) mprintf("Calibrator %s successfully received request for to update its parameters to defaults.", uniqueCalibratorName.c_str()); return CALIBRATOR_ACTION_SET_PARAMS_TO_DEFAULTS; } else { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Calibrator %s received a request, but action was unknown. Request ignored", uniqueCalibratorName.c_str()); return CALIBRATOR_NO_ACTION; } return (CALIBRATOR_NO_ACTION); }
// this routine checks that the request is a dictionary and that it contains a name that matches the calibrator bool Calibrator::checkRequest(Datum dictionaryData) { Datum data; // to hold field data for checking // check if this is a dictionary if (!(dictionaryData.getDataType() == M_DICTIONARY)) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Request sent to calibrator %s that was not expected dictionary type was ignored.", uniqueCalibratorName.c_str()); return(false); } // check if there is a name field and if this calibrator should respond (i.e. if it has the correct name) if (!(dictionaryData.hasKey(R_CALIBRATOR_NAME))) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Request sent to calibrator %s that did not contain name field was ignored.", uniqueCalibratorName.c_str()); return(false); } Datum nameData = dictionaryData.getElement(R_CALIBRATOR_NAME); if (!(nameData.getDataType() == M_STRING)) { // check if name field is a string mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Request sent to calibrator %s that did not contain a string in the name field was ignored.", uniqueCalibratorName.c_str()); return(false); } if (uniqueCalibratorName == nameData.getString()) { // check is name field matches the name of this calibrator if (VERBOSE_EYE_CALIBRATORS) mprintf("Calibrator %s successfully received a properly named request.", uniqueCalibratorName.c_str()); } else { if (VERBOSE_EYE_CALIBRATORS) mprintf("Calibrator %s received a request, but name did not match.", uniqueCalibratorName.c_str()); return(false); // request not meant for this calibrator (can be normal behavior -- no warnings) } return true; }
// this routine handles both "requests" and loading of private data (stored params) // if a request, then priuvate values are probably in need of update // if a load of private, then private values are OK, but I can check this. void EyeCalibrator::tryToUseDataToSetParameters(Datum dictionaryData) { // check if this is a dictionary if (!(dictionaryData.getDataType() == M_DICTIONARY)) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed by calibrator %s that was not expected dictionary type was ignored.", uniqueCalibratorName.c_str()); return; } // try to perform the requested action bool paramsChanged = false; Datum paramData; // if appropriate param fields are present and have expected length, then use the data // to try to update the parameters // H params ================================================ if (!(dictionaryData.hasKey(R_CALIBRATOR_PARAMS_H))) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed to update params of calibrator %s without proper params filed was ignored.", uniqueCalibratorName.c_str()); return; } paramData = dictionaryData.getElement(R_CALIBRATOR_PARAMS_H); // check if vector and correct length if (paramData.getDataType() != M_LIST) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed to update params of calibrator %s that did not contain vector in params field was ignored.", uniqueCalibratorName.c_str()); return; } Datum paramsH = paramData; if (paramsH.getNElements() != (fitableFunctions->getElement(HfunctionIndex))->getNumParameters() ) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed to update params of calibrator %s that did not contain expected number of params was ignored.", uniqueCalibratorName.c_str()); return; } bool noErr = (fitableFunctions->getElement(HfunctionIndex))->setParameters(paramsH); if (noErr) paramsChanged = true; // params have been updated // V params ================================================ if (!(dictionaryData.hasKey(R_CALIBRATOR_PARAMS_V))) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed to update params of calibrator %s without proper params filed was ignored.", uniqueCalibratorName.c_str()); return; } paramData = dictionaryData.getElement(R_CALIBRATOR_PARAMS_V); // check if vector and correct length if (paramData.getDataType() != M_LIST) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed to update params of calibrator %s that did not contain vector in params field was ignored.", uniqueCalibratorName.c_str()); return; } Datum paramsV = paramData; if (paramsV.getNElements() != (fitableFunctions->getElement(VfunctionIndex))->getNumParameters() ) { mwarning(M_SYSTEM_MESSAGE_DOMAIN, "Data processed to update params of calibrator %s that did not contain expected number of params was ignored.", uniqueCalibratorName.c_str()); return; } noErr = (fitableFunctions->getElement(VfunctionIndex))->setParameters(paramsV); if (noErr) paramsChanged = true; // params have been updated // if any params were updated, announce the full set of current parameters // if this change was triggered by an external change to the private variable, then we do not need to update that private variable (and we cannot anyway -- it is locked) if (paramsChanged) reportParameterUpdate(); }