Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 233 additions & 16 deletions src/classes/Compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -763,13 +763,220 @@ full_data <- read.csv(text = paste0("${MODEL_DATA}")) %>% dplyr::select(-X)
precan_df <- precan_partners(full_data)
`;

// Collection of test responses
const TEST_RESPONSES = [
{
ID: "TEST_001",
Trial: 1,
ppt1: 8,
par1: 6,
ppt2: 6,
par2: 8,
Ac: 1,
Phase: 1
},
{
ID: "TEST_002",
Trial: 2,
ppt1: 9,
par1: 5,
ppt2: 7,
par2: 7,
Ac: 1,
Phase: 1
},
{
ID: "TEST_003",
Trial: 3,
ppt1: 6,
par1: 8,
ppt2: 8,
par2: 6,
Ac: 2,
Phase: 1
},
{
ID: "TEST_004",
Trial: 4,
ppt1: 7,
par1: 7,
ppt2: 9,
par2: 5,
Ac: 1,
Phase: 1
},
{
ID: "TEST_005",
Trial: 5,
ppt1: 5,
par1: 9,
ppt2: 7,
par2: 7,
Ac: 2,
Phase: 1
},
{
ID: "TEST_006",
Trial: 6,
ppt1: 8,
par1: 6,
ppt2: 6,
par2: 8,
Ac: 1,
Phase: 1
},
{
ID: "TEST_007",
Trial: 7,
ppt1: 9,
par1: 5,
ppt2: 5,
par2: 9,
Ac: 1,
Phase: 1
},
{
ID: "TEST_008",
Trial: 8,
ppt1: 6,
par1: 8,
ppt2: 8,
par2: 6,
Ac: 2,
Phase: 1
},
{
ID: "TEST_009",
Trial: 9,
ppt1: 7,
par1: 7,
ppt2: 9,
par2: 5,
Ac: 2,
Phase: 1
},
{
ID: "TEST_010",
Trial: 10,
ppt1: 5,
par1: 9,
ppt2: 7,
par2: 7,
Ac: 1,
Phase: 1
},
{
ID: "TEST_011",
Trial: 11,
ppt1: 8,
par1: 6,
ppt2: 6,
par2: 8,
Ac: 2,
Phase: 1
},
{
ID: "TEST_012",
Trial: 12,
ppt1: 9,
par1: 5,
ppt2: 5,
par2: 9,
Ac: 1,
Phase: 1
},
{
ID: "TEST_013",
Trial: 13,
ppt1: 6,
par1: 8,
ppt2: 8,
par2: 6,
Ac: 1,
Phase: 1
},
{
ID: "TEST_014",
Trial: 14,
ppt1: 7,
par1: 7,
ppt2: 9,
par2: 5,
Ac: 2,
Phase: 1
},
{
ID: "TEST_015",
Trial: 15,
ppt1: 5,
par1: 9,
ppt2: 7,
par2: 7,
Ac: 1,
Phase: 1
},
{
ID: "TEST_016",
Trial: 16,
ppt1: 8,
par1: 6,
ppt2: 6,
par2: 8,
Ac: 2,
Phase: 1
},
{
ID: "TEST_017",
Trial: 17,
ppt1: 9,
par1: 5,
ppt2: 5,
par2: 9,
Ac: 1,
Phase: 1
},
{
ID: "TEST_018",
Trial: 18,
ppt1: 6,
par1: 8,
ppt2: 8,
par2: 6,
Ac: 2,
Phase: 1
},
{
ID: "TEST_019",
Trial: 19,
ppt1: 7,
par1: 7,
ppt2: 9,
par2: 5,
Ac: 1,
Phase: 1
},
{
ID: "TEST_020",
Trial: 20,
ppt1: 5,
par1: 9,
ppt2: 7,
par2: 7,
Ac: 2,
Phase: 1
}
];

/**
* @summary Compute class used to run a model locally in the browser using WebR.
*/
class Compute {
// WebR instance used to run the model script
private webR: WebR;

// Status of operation
private ready: boolean;

/**
* Default constructor
* @constructor
Expand All @@ -784,6 +991,9 @@ class Compute {
}
: {}
);

// Initialize the status of operation
this.ready = false;
}

/**
Expand All @@ -794,6 +1004,7 @@ class Compute {
// Initialize the WebR instance
await this.webR.init();

// Install required packages
if (Configuration.manipulations.useOfflinePackages) {
consola.start("Using offline packages...");
try {
Expand All @@ -803,7 +1014,6 @@ class Compute {
consola.error(error);
}
} else {
// Install required packages and evaluate the script
consola.start("Using online packages...");
await this.webR.installPackages([
"matlab",
Expand All @@ -812,17 +1022,28 @@ class Compute {
"dplyr",
"logger",
]);
consola.success("Online packages installed successfully");
}

// Evaluate the R script
await this.webR.evalR(FUNCTIONS);
this.ready = true;
}

/**
* Get the status of operation
* @return {boolean}
*/
public isReady(): boolean {
return this.ready;
}

/**
* Utility function to handle a response received from WebR
* @param {any[]} data Data returned by R functions
* @return {any} Data structure containing reformatting model responses
*/
private handleResponse(data: any[]): ModelResponse {
private parseResponse(data: any[]): ModelResponse {
// Get the participant parameters
const participantParameters = data[0].values;

Expand Down Expand Up @@ -854,27 +1075,23 @@ class Compute {
/**
* Run the R script with the current user responses
* @param {any[]} data request parameters
* @param {function(data: any): void} callback
* @param {boolean} useTestResponses whether to use test responses for debugging
*/
public async submit(
data: any[],
callback: (data: any) => void
): Promise<void> {
const startTime = performance.now();
public async submit(data: any[], useTestResponses=false): Promise<ModelResponse> {
if (useTestResponses) {
data = TEST_RESPONSES;
}

// Evaluate the R function and pass in user responses
// Note: Need to format JSON with " rather than '
const startTime = performance.now();
const result = await this.webR.evalR(
`model_wrapper(fromJSON('${JSON.stringify(data)}'))`
`model_wrapper(fromJSON('${JSON.stringify(data)}'))` // Note: Need to format JSON with " rather than '
);
const parsed: WebRDataJsNode = (await result.toJs()) as WebRDataJsNode;
consola.success(`Compute complete after ${Math.round(performance.now() - startTime)}ms`);

// Handle the response from the R script and run the provided callback function
const parameters = this.handleResponse(parsed.values);
callback(parameters);

const endTime = performance.now();
consola.info(`Compute complete after ${Math.round(endTime - startTime)}ms`);
// Parse the response from the R script
return this.parseResponse(parsed.values);
}
}

Expand Down
45 changes: 32 additions & 13 deletions src/classes/Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,28 +178,47 @@ class Handler {

/**
* Handler called after loading request completed (for matching state)
* @param {boolean} storeParameters whether to store the parameters
* @param {number[]} participantParameters generated model
* parameters for participant
* @param {number[]} partnerParameters generated model parameters for partner
* @param {number} setupDuration duration of the setup operation in ms
* @param {number} operationDuration duration of the operation operation in ms
*/
public loading(
storeParameters: boolean,
participantParameters: number[],
partnerParameters: number[]
partnerParameters: number[],
setupDuration: number,
operationDuration: number
): void {
consola.debug(
"Loading responses:",
participantParameters,
partnerParameters
);
// Store participant parameters
this.dataframe.server_alpha_ppt = participantParameters[0];
this.dataframe.server_beta_ppt = participantParameters[1];
if (storeParameters) {
consola.debug(
"Loading responses:",
participantParameters,
partnerParameters
);
// Store participant parameters
this.dataframe.server_alpha_ppt = participantParameters[0];
this.dataframe.server_beta_ppt = participantParameters[1];

// Store partner parameters
this.dataframe.server_alpha_par = partnerParameters[0];
this.dataframe.server_beta_par = partnerParameters[1];
}

// Store partner parameters
this.dataframe.server_alpha_par = partnerParameters[0];
this.dataframe.server_beta_par = partnerParameters[1];
// Store timing data
this.dataframe.setupDuration = 0;
this.dataframe.operationDuration = 0;
if (setupDuration > 0) {
this.dataframe.setupDuration = setupDuration;
}
if (operationDuration > 0) {
this.dataframe.operationDuration = operationDuration;
}

// We don't call the callback on a timer
// Finish trial
this.callback();
}

/**
Expand Down
Loading