Skip to content

Commit

Permalink
Merge branch 'master' into qt6.5
Browse files Browse the repository at this point in the history
  • Loading branch information
martinburchell committed Oct 20, 2023
2 parents a75bcf9 + f649495 commit d079c27
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 61 deletions.
14 changes: 13 additions & 1 deletion docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3805,5 +3805,17 @@ Current C++/SQLite client, Python/SQLAlchemy server
only. Target Android version now 33.


**Client and server v2.4.18, IN PROGRESS**
**Client and server v2.4.18, IN PROGRESS**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Make the "Register me" and "More options" buttons more legible on Android.

- When uploading in single user mode, if the server version has changed store the
new version in the client database and refetch the strings. Previously the user
would see a generic error message and the only way to fix it was to re-register
the patient.
https://github.com/ucam-department-of-psychiatry/camcops/issues/263

- Support for a clinician to configure IDED-3D settings for single user mode on
a per-patient basis.
https://github.com/ucam-department-of-psychiatry/camcops/issues/314
90 changes: 89 additions & 1 deletion docs/source/tasks/ided3d.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,96 @@ Intellectual property rights
Cambridge, 1995-1999).


Settings
~~~~~~~~

When assigning this task to a patient as part of a :ref:`task schedule
<scheduling_tasks>`, the task may be configured with the following JSON
settings. For example:


.. code-block:: json
{
"ided3d": {
"last_stage": 8,
"max_trials_per_stage": 50,
"progress_criterion_x": 6,
"progress_criterion_y": 6,
"min_number": 1,
"max_number": 9,
"pause_after_beep_ms": 500,
"iti_ms": 500,
"counterbalance_dimensions": 4,
"volume": 0.5,
"offer_abort": false
}
}
Here is a description of each setting:

.. glossary::

last_stage
Last stage to use (1 [SD] – 8 [EDR]). Default 8.

The stages are:

1. simple discrimination (SD)
2. reversal of previous SD stage (SDr)
3. compound discrimination (CD)
4. reversal of previous CD stage (CDr)
5. intradimensional shift (ID)
6. reversal of previous ID stage (IDr)
7. extradimensional shift (ED)
8. reversal of previous ED stage (EDr)

max_trials_per_stage
Maximum number of trials per stage (abort if this reached without
success). Default 50.

progress_criterion_x
Criterion to proceed to next stage: X correct out of the last Y trials,
where this is X. Default 6.

progress_criterion_y
Criterion to proceed to next stage: X correct out of the last Y trials,
where this is Y. Default 6.

min_number
Minimum number of stimuli [1–9]. Default 1.

max_number
Maximum number of stimuli [1–9]. Default 9.

pause_after_beep_ms
Time to continue visual feedback after auditory feedback finished (ms).
Default 500.

iti_ms
Intertrial interval (ITI) (ms). Default 500.

counterbalance_dimensions
Dimension counterbalancing [0–5]. See :ref:`Counterbalancing
<ided3d_counterbalancing>`. No default.

volume
Volume [0-1]. Default 0.5

offer_abort
Offer the user an abort button. Default false.


In clinician mode, the user may change these settings before starting the
task. In single-user mode, if all of the settings have valid values (as a
minimum `counterbalance_dimensions` must be set), the user will not be able to
change these settings and the task will start immediately.


.. _ided3d_counterbalancing:

Counterbalancing
~~~~~~~~~~~~~~~~
################

The counterbalancing options are:

Expand Down
2 changes: 1 addition & 1 deletion server/installer/installer_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# dev only
flake8

cryptography==41.0.3
cryptography==41.0.4
python-on-whales==0.50.0
prompt-toolkit==3.0.30
semantic_version==2.10.0
Expand Down
74 changes: 64 additions & 10 deletions tablet_qt/core/networkmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1240,12 +1240,37 @@ void NetworkManager::uploadNext(QNetworkReply* reply)
m_upload_next_stage = NextUploadStage::ValidatePatients;
break;

case NextUploadStage::StoreExtraStrings:
// The server version changed so we fetch any new extra strings
storeExtraStrings();
// now we go back to trying to fetch the server info
m_upload_next_stage = NextUploadStage::FetchServerIdInfo;
uploadNext(nullptr);
break;

case NextUploadStage::ValidatePatients:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FROM: fetch server ID info
// TO: ask server to validate patients
// ... or if the server doesn't support that, move on another step
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (m_app.isSingleUserMode()) {
// In single user mode, if the server has been updated, we overwrite
// the stored server version and refetch all server info without
// warning or prompting the user to refetch.
if (!serverVersionMatchesStored()) {
storeServerIdentificationInfo();

statusMessage(tr("Requesting extra strings"));
Dict dict;
dict[KEY_OPERATION] = OP_GET_EXTRA_STRINGS;

m_upload_next_stage = NextUploadStage::StoreExtraStrings;
serverPost(dict, &NetworkManager::uploadNext);
return;
}
}

if (!isServerVersionOK() || !arePoliciesOK() || !areDescriptionsOK()) {
fail();
return;
Expand Down Expand Up @@ -2079,25 +2104,54 @@ bool NetworkManager::catalogueTablesForUpload()
bool NetworkManager::isServerVersionOK() const
{
statusMessage(tr("Checking server CamCOPS version"));
const QString server_version_str = m_reply_dict[KEY_SERVER_CAMCOPS_VERSION];
const Version server_version(server_version_str);
const Version stored_server_version = m_app.serverVersion();

if (server_version < camcopsversion::MINIMUM_SERVER_VERSION) {
if (!serverVersionNewEnough()) {
return false;
}
if (!serverVersionMatchesStored()) {
return false;
}
statusMessage(tr("... OK"));
return true;
}


bool NetworkManager::serverVersionNewEnough() const
{
const Version server_version = serverVersionFromReply();
bool new_enough = server_version >= camcopsversion::MINIMUM_SERVER_VERSION;

if (!new_enough) {
statusMessage(tr("Server CamCOPS version (%1) is too old; must be >= %2")
.arg(server_version_str,
.arg(server_version.toString(),
camcopsversion::MINIMUM_SERVER_VERSION.toString()));
return false;
}
if (server_version != stored_server_version) {

return new_enough;
}


bool NetworkManager::serverVersionMatchesStored() const
{
const Version server_version = serverVersionFromReply();
const Version stored_server_version = m_app.serverVersion();

bool matches = server_version == stored_server_version;

if (!matches) {
statusMessage(tr("Server version (%1) doesn't match stored version (%2).")
.arg(server_version.toString(),
stored_server_version.toString()) +
txtPleaseRefetchServerInfo());
return false;
}
statusMessage(tr("... OK"));
return true;

return matches;
}


Version NetworkManager::serverVersionFromReply() const
{
return Version(m_reply_dict[KEY_SERVER_CAMCOPS_VERSION]);
}


Expand Down
11 changes: 11 additions & 0 deletions tablet_qt/core/networkmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
class CamcopsApp;
class LogBox;
class QNetworkAccessManager;
class Version;


// Controls network operations, optionally providing a progress display.
Expand Down Expand Up @@ -319,6 +320,15 @@ public slots:
// new enough for us to upload at all.
bool isServerVersionOK() const;

// Server version matches what we had stored.
bool serverVersionMatchesStored() const;

// Server version is new enough for us to upload at all.
bool serverVersionNewEnough() const;

// Version returned by the server.
Version serverVersionFromReply() const;

// Do our ID policies match those of the server?
bool arePoliciesOK() const;

Expand Down Expand Up @@ -468,6 +478,7 @@ public slots:
Invalid,
CheckUser,
FetchServerIdInfo,
StoreExtraStrings,
ValidatePatients, // v2.3.0
FetchAllowedTables,
CheckPoliciesThenStartUpload,
Expand Down
5 changes: 5 additions & 0 deletions tablet_qt/tasklib/taskscheduleitemeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ void TaskScheduleItemEditor::editTask()

const int patient_id = m_app.selectedPatientId();
task->setupForEditingAndSave(patient_id);

// Only apply settings on task creation. The task should save any
// settings along with the responses. So if a task is re-edited we
// shouldn't need to apply them here. This will prevent the settings
// from changing, should they change on the server.
const QJsonObject settings = m_p_task_schedule_item->settings();
task->applySettings(settings);
m_p_task_schedule_item->setTask(task->pkvalueInt());
Expand Down

0 comments on commit d079c27

Please sign in to comment.