Skip to content

Commit a201425

Browse files
transform helper (#56)
* adding helper function to utils.py The helper function parses the run properties and results data so that the user doesn't need to include any parsing script in their transform script. The helper function only accepts a user-defined function that accepts an array of results data as its input and returns an array of results data matching the assay design it is used with. Also, the helper function requires that users explicitly define the run properties in their transform script, otherwise the labkey transform script parser does not recognize ${runInfo}. * Create example transform script that uses labkey.utils.transform_helper * Delete assay_transform_function_example.py moving filter to /docs folder * documentation for transform_helper function * Update transform_helper.md * Update transform_helper.md * updating transform_helper to be more robust and use snake case switched from camel case to snake case for variable naming. additionally, changed script to get file_path_in from the row beginning with "runDataUploadedFile" in runProperties file. This is to better handle results data with numerical header names, such as when the results data is a grid representing well plates. * Update labkey/utils.py Co-authored-by: Alan Vezina <[email protected]> * Update utils.py using with statements when opening files --------- Co-authored-by: Alan Vezina <[email protected]>
1 parent 89c62ab commit a201425

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

docs/transform_helper.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Transform Helper Function Support
2+
3+
This helper function provides a convenient way for users to write transform scripts for assays without requiring the user to read the results and run data before transforming the data, and it also takes care of writing the transformed data back to labkey.
4+
5+
### Importing and preparing the helper function
6+
7+
First, your script must begin with these two lines to properly use the transform helper function:
8+
9+
```python
10+
from labkey.utils import transform_helper
11+
12+
filepath = '${runInfo}'
13+
```
14+
15+
The substitution token `${runInfo}` is replaced with the runProperties file path when the transform script is run within LabKey Server.
16+
17+
### Write your user-defined transform function
18+
19+
This is an example function that could be used as an argument when using the transform_helper function:
20+
21+
```python
22+
def transform(grid):
23+
isHeaderChecked = False
24+
# iterate through the rows of your results data, checking for the header
25+
for row in grid:
26+
if isHeaderChecked == False:
27+
row.append('averageResult')
28+
isHeaderChecked = True
29+
else:
30+
# In this example, we are taking the average of the 3rd-5th column values by row
31+
# and appending that average value in a 6th column called "averageResult"
32+
newValTemp = sum([float(val) for val in row[2:]])/len(row[2:])
33+
row.append(round(newValTemp, 2))
34+
return grid
35+
```
36+
37+
As you can see in the example function, the transform function must accept only one argument, the tabular data (including headers) that needs to be transformed in an list of lists format. The user-defined transform function must also return tabular data the same list of lists format with a header row that matches the header of the results data as defined by the targeted assay design.
38+
39+
### Using the helper function
40+
41+
The last thing to do is call the transform_helper function, supplying the user-defined transfrom function as the first argument, and the file path (as defined by ${runInfo}) as the second argument.
42+
43+
```python
44+
transform_helper(transform, filepath)
45+
```

labkey/utils.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,42 @@ def default(self, o):
3131
def json_dumps(*args, **kwargs):
3232
kwargs.setdefault("cls", DateTimeEncoder)
3333
return json.dumps(*args, **kwargs)
34+
35+
36+
def transform_helper(user_transform_func, file_path_run_properties):
37+
#file_path_run_properties must be explicitly defined as ${runInfo} within the user's transform script
38+
#parse run properties to for results data in and out filepaths
39+
file_path_in = ''
40+
file_path_out = ''
41+
with open(file_path_run_properties) as file_run_properties:
42+
for l in file_run_properties:
43+
row = l.strip().split('\t')
44+
if row[0] == 'runDataFile':
45+
file_path_out = row[3]
46+
if row[0] == 'runDataUploadedFile':
47+
file_path_in = row[1]
48+
49+
#parse results data into array, confirming supported file type is used
50+
with open(file_path_in) as file_in:
51+
data_grid = []
52+
53+
for l in file_in:
54+
if '\t' in l:
55+
row = l.replace('\n', '').split('\t')
56+
elif ',' in l:
57+
row = l.replace('\n', '').split(',')
58+
else:
59+
raise ValueError('Unsupported file type or delimiter used. Header used: \n' + str(l))
60+
data_grid.append(row)
61+
62+
#run user transform on parsed results data array
63+
transformed_grid = user_transform_func(data_grid)
64+
65+
#write transformed results data array to LabKey assay results data grid
66+
#transformed array must be a python list object, not a numpy array or pandas dataframe
67+
with open(file_path_out, mode='w') as file_out:
68+
for row in transformed_grid:
69+
row = [str(el).strip() for el in row]
70+
row = '\t'.join(row)
71+
file_out.write(row + '\n')
72+

0 commit comments

Comments
 (0)