rxome-generator 1.0.3 → 1.0.4-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.html ADDED
@@ -0,0 +1,834 @@
1
+ <h1>TODO:</h1>
2
+
3
+ <ul>
4
+ <li>how to connect to docker container (shell)</li>
5
+ </ul>
6
+
7
+ <p><code>docker run -it -rm node /bin/bash
8
+ cd root/
9
+ npm install rxome-generator
10
+ node_modules/.bin/rxcode id key</code></p>
11
+
12
+ <h1>FindMe2care (RxOME) QR-code generator</h1>
13
+
14
+ <p>Generates QR codes containing medical information for use with the FindMe2care platform
15
+ (formerly called RxOME).</p>
16
+
17
+ <h2>LICENSE</h2>
18
+
19
+ <p>Copyright (c) 2023 RxOME GmbH</p>
20
+
21
+ <p>All rights reserved, unauthorized use prohibited.</p>
22
+
23
+ <h2>Purpose</h2>
24
+
25
+ <p>The <em>rxome</em> packages generate QR codes from medical data for use with the FindMe2care platform.</p>
26
+
27
+ <p>The package <em>rxome-generator</em> offers a JavaScript library as well as
28
+ a command line tool as front end to this library. Additonally, the packages <em>rxome-server</em> and <em>rxome-server-win</em>
29
+ provide a web service based on the rxome library.</p>
30
+
31
+ <p>The packages expect the medical data in JSON format
32
+ according to a subset of the PhenoPacket standard (with some additions), see below.
33
+ The medical data will be encrypted before generating the QR code. This encrypted data can be decrypted
34
+ by the database backend only. The meta data is transmitted unencrypted.</p>
35
+
36
+ <p>Every QR code is tagged with a unique pseudonym that is downloaded from the RxOME server. Thus, the tools
37
+ require an active internet connection. Furthermore, the user or the facility applying the QR generator has to sign up to the RxOME server. The communication to the server API is secured with a protocol that uses an
38
+ asymmetric pair of keys, a private key (the API access key) is used to sign the API enquiry,
39
+ a public key is uploaded to the server and used to verify the signature,
40
+ see generating user credentials.</p>
41
+
42
+ <p>When generating a QR code and, thus, downloading a pseudonym, the user needs to specify the
43
+ corresponding credentials (keyID and key) for accessing the FindMe2care server.
44
+ The command line tool offers command line options for the API access credentials. Further, they
45
+ can be specified in the input JSON file (see 'MetaData and credentials' below),
46
+ where the command line options precede the data in the JSON file.</p>
47
+
48
+ <p>In case the patient already has a pseudonym that will be used for the QR code,
49
+ the known pseudonym can be specified in the MetaData section of the input JSON data.
50
+ Additionally, the command line tool
51
+ offers a command line argument, <code>-p</code>, for specifying a known pseudonym.
52
+ Note that this pseudonym must be a valid FindMe2care pseudonym, that is, it has to be generated by
53
+ FindMe2care for a previous medical statement. Using an arbitrary pseudonym will render the
54
+ generated QR-Code useless, as it cannot be processed by FindMe2care.</p>
55
+
56
+ <p>By default, the keywords in the JSON file are expected to be noted in camelCase. However, the tool
57
+ can convert snake_case to camelCase (command line: -s, library function: convertToCamelCase).</p>
58
+
59
+ <h2>1. Library and Command-Line Tool</h2>
60
+
61
+ <h3>1.1 Installation</h3>
62
+
63
+ <blockquote>
64
+ <p><code>npm install rxome-generator</code></p>
65
+ </blockquote>
66
+
67
+ <h3>1.2 Basic Usage</h3>
68
+
69
+ <h4>Command Line Tool</h4>
70
+
71
+ <p>Generate a QR code <em>inputfile</em>.png from a JSON file <em>inputfile</em>.json containing all medical data in PhenoPacket format, meta data and credentials (using camelCase for keywords):</p>
72
+
73
+ <blockquote>
74
+ <p><code>rxcode g</code> <em>inputfile</em>.json</p>
75
+ </blockquote>
76
+
77
+ <p>For detailed descriptions see</p>
78
+
79
+ <blockquote>
80
+ <p><code>rxcode g --help</code></p>
81
+ </blockquote>
82
+
83
+ <h4>Library Functions</h4>
84
+
85
+ <p>Import the library with</p>
86
+
87
+ <blockquote>
88
+ <p><code>const Coder = require( 'rxome-generator' );</code></p>
89
+ </blockquote>
90
+
91
+ <p>The following two async library functions generate QR codes:</p>
92
+
93
+ <blockquote>
94
+ <p><code>Coder.writeQR( filename, data, api = RXAPI )</code></p>
95
+ </blockquote>
96
+
97
+ <blockquote>
98
+ <p><em>filename</em>: name for PNG file with the QR code<br/>
99
+ <em>data</em>: object containing medical data, meta data, and credentials (format: see below)<br/>
100
+ <em>api</em>: omit in production mode, set to <code>Coder.TESTAPI</code> in test mode.</p>
101
+ </blockquote>
102
+
103
+ <p>This function creates the QR code from the given data and writes it as PNG file specified by <em>filename</em>.
104
+ The credentials for accessing the RxOME API (i.e., fetching a pseudonym and the encryption key) have to be
105
+ part of the data object (see below). Returns the pseudonym used to generate the QR code and the unencrypted
106
+ content of the QR code.</p>
107
+
108
+ <blockquote>
109
+ <p><code>Coder.makeQR( data, api = RXAPI, apiEntry = APIENTRY )</code></p>
110
+ </blockquote>
111
+
112
+ <p>Generates a QR code object as Data URL that can be placed on a web page. As above, the credentials are specified as part of the data object. Returns an object:</p>
113
+
114
+ <p><code>{
115
+ qr_code: (QR code),
116
+ pseudonym: (pseudonym used to generate the QR code),
117
+ qr_data: content of the QR code (with encrypted medical data; i.e., a 1:1 image of the QR code content),
118
+ qr_content: content of the QR code but with unencrypted medical data for documentation purposes
119
+ }</code></p>
120
+
121
+ <p>Both <code>writeQR</code> and <code>makeQR</code> take care
122
+ of the preprocessing steps (sanitizing, compessing, encoding). However, converting the keys in the data object to camelCase is <em>not</em> part of the preprocessing.
123
+ Use the following function to convert keys from snake_case to camelCase:</p>
124
+
125
+ <blockquote>
126
+ <p><code>Coder.convertToCamelCase( data )</code></p>
127
+ </blockquote>
128
+
129
+ <p>Additionally, the data can be verified with</p>
130
+
131
+ <blockquote>
132
+ <p><code>Coder.verify( data )</code></p>
133
+ </blockquote>
134
+
135
+ <p>Note that the credential information perhaps stored in the data package is <em>not</em> part of the PhenoPacket standard.</p>
136
+
137
+ <h3>1.3 Command-Line Tool</h3>
138
+
139
+ <h4>Overview</h4>
140
+
141
+ <p>```
142
+ FindMe2care QR Code generation tool</p>
143
+
144
+ <p>Usage: rxcode [options] [command]</p>
145
+
146
+ <p>Basic usage: rxcode g &lt;input json file&gt;: generates QR Code with the basefilename of the inputfile.
147
+ Before first use, please generate an API access key (rxcode -k) and deposit the public key on the
148
+ FindMe2care server.</p>
149
+
150
+ <p>Options:
151
+ -V, --version output the version number
152
+ -h, --help display help for command</p>
153
+
154
+ <p>Commands:
155
+ generate|g [options] [input file] generate QR Code from PhenoPacket JSON
156
+ upload|U [input file] [key ID] [key] For debug purposes: Upload and decode QR Code PNG to server (only
157
+ for test server)
158
+ convert|c [options] [input file] convert case style of keys in JSON files from snake_case to
159
+ camelCase (and vice versa)
160
+ preprocess|p [options] [input file] perform preprocessing steps
161
+ verify|v [input file] verify input file against phenopacket schema
162
+ apikeys|k [options] [file prefix] generate key pair for API access
163
+ ping|P [options] <id> <key> Ping API/check API credentials
164
+ encrypt|e [options] [input file] encrypt message (just for testing)
165
+ decrypt|d [options] [input file] decrypt coded message or medical data
166
+ data-keys|K [options] [file prefix] generate data encryption key pair (see -e, -d; just for testing)
167
+ pheno2proto|E [options] [input file] encode PhenoPacket to protobuf (just for testing)
168
+ proto2pheno|D [options] [input file] decode protobuf to PhenoPacket (just for testing)
169
+ settings|S [options] Print current settings
170
+ statistics|s [input file] print memory consuption for several stages and alternatives
171
+ help [command] display help for command</p>
172
+
173
+ <p>Author: Tom Kamphans, GeneTalk GmbH, 2022, (c) 2023 RxOME GmbH
174
+ ```</p>
175
+
176
+ <h4>Generating QR codes</h4>
177
+
178
+ <p>Use the 'g' command for actually generating a QR code:</p>
179
+
180
+ <p>```
181
+ FindMe2care QR Code generation tool</p>
182
+
183
+ <p>Usage: rxcode generate|g [options] [input file]</p>
184
+
185
+ <p>Generate QR Code from PhenoPacket JSON. The credential information keyId and either key or keyFile
186
+ are mandatory and can be specified either in the input JSON file or by command line arguments.
187
+ The command line arguments precede the data from the JSON input file.
188
+ Output: prints the given or new pseudonym.</p>
189
+
190
+ <p>Arguments:
191
+ input file Input JSON file (default: STDIN)</p>
192
+
193
+ <p>Options:
194
+ -o, --output <filename> Filename for the QR code (default: <inputfile>.png)
195
+ -p, --pseudonym <pseudonym> For re-evaluations: pseudonym for patient. Otherwise a new is generated
196
+ (default: &quot;&quot;)
197
+ -i, --keyId <id> API access ID (default: input file, credentials.keyId or metaData.createdBy)
198
+ -k, --keyFile <filename> Filename with API access key (default: use -s)
199
+ -s, --key &lt;key string&gt; API access key (default: input file, credentials.key)
200
+ -u, --user &lt;user string&gt; API access user (default: credentials.user or metaData.submittedBy or
201
+ info@rxome.net)
202
+ -c, --created <date> Date (default: input file, metaData.created)
203
+ -l, --lab <lab> Laboratory name (default: input file, metaData.createdBy or lab name stored
204
+ in the user account)
205
+ -e, --email <email> Laboratory email (default: input file, metaData.submittedBy)
206
+ -S, --snake Read payload formatted in snake_case (default: camelCase)
207
+ -t, --test Use test API instead of production API
208
+ -L, --localhost Connect to localhost API
209
+ -D, --debug Some output for debugging
210
+ -h, --help display help for command</p>
211
+
212
+ <p>Author: Tom Kamphans, GeneTalk GmbH, 2022, (c) 2023 RxOME GmbH
213
+ ```</p>
214
+
215
+ <p>Writes the pseudonym used to generate the QR code to STDOUT. With -D given, this further writes the
216
+ (unencrypted) content of the QR code to STDOUT.</p>
217
+
218
+ <h4>Generating API Access Keys</h4>
219
+
220
+ <p>To communicate with the server API you need access credentials, that is, an id for your lab (the keyId) and a pair of corresponding keys. First, generate a pair of keys with</p>
221
+
222
+ <p><code>rxcode k myLabId</code></p>
223
+
224
+ <p>This yields two files: <code>myLabId.private.apikey</code> and <code>myLabId.public.apikey</code>. Store the
225
+ private key safely.
226
+ Create a lab account on <code>app.findme2care.de/generate</code> and upload the public key to your profile.
227
+ Afterwards, you should be able to access the API (see 'debugging' below).</p>
228
+
229
+ <h4>Demo</h4>
230
+
231
+ <p><code>rxcode g -t -o qrcode.png demos/demo_data_full.json</code></p>
232
+
233
+ <img src="qrcode.png" width="400">
234
+
235
+ <h4>Testing your installation</h4>
236
+
237
+ <p>To check the connection to the API on RxOME server API use</p>
238
+
239
+ <blockquote>
240
+ <p><code>rxcode P -d</code> <em>your_id</em> <em>your_key</em></p>
241
+ </blockquote>
242
+
243
+ <p>If you want to make sure that all data from your input is transmitted correctly, you can
244
+ use the <code>pheno2proto</code> and the corresponding <code>proto2pheno</code> commands to encode and decode your
245
+ file. Compare the output of <code>proto2pheno</code> with your original file:</p>
246
+
247
+ <p><code>rxcode E -b my_file.json &gt; my_file.pbuf
248
+ rxcode D -bp my_file.pbuf &gt; my_new_file.json
249
+ diff my_new_file.json my_file.json</code></p>
250
+
251
+ <p>Further, you can check a QR Code that was generated on the test server (using the <code>-t</code> option in <code>rxcode g</code>) by uploading and decoding it to the test server with the <code>upload</code> command:</p>
252
+
253
+ <p><code>rxcode U my_qr_code.png my_key_id my_private_key</code></p>
254
+
255
+ <h2>2. QR-code generator service</h2>
256
+
257
+ <p>The packages <em>rxome-server</em> generates QR codes containing medical information for use with the FindMe2Care database
258
+ (formerly called RxOME). The command line tool <code>rxsrv</code> starts the QR generator as local service listening on localhost:<em>port</em> (default: port 1607).
259
+ A client can send POST requests to this port and retrieves the generated QR code by HTTP protocol.</p>
260
+
261
+ <p>A second package, <em>rxome-server-win</em>, build up on rxome-server installs the server as windows service.</p>
262
+
263
+ <h3>2.1 Prerequisites</h3>
264
+
265
+ <p>Running the QR-Code server requires either <code>node.js</code> or <code>docker</code>.</p>
266
+
267
+ <h3>2.2 Using Node.js</h3>
268
+
269
+ <h4>Installation</h4>
270
+
271
+ <p>Either install the QR-Code Server or the Windows service installer using</p>
272
+
273
+ <p><code>npm install -q rxome-server</code></p>
274
+
275
+ <p>or</p>
276
+
277
+ <p><code>npm install -q rxome-server-win</code></p>
278
+
279
+ <h4>Starting the QR-Code Server</h4>
280
+
281
+ <p>For detailed descriptions see
282
+ <code>rxsrv --help</code></p>
283
+
284
+ <h4>Generating API access keys</h4>
285
+
286
+ <p>You can generate new API access keys using the command line:
287
+ <code>rxsrv --newkey</code></p>
288
+
289
+ <p>or in the Windows version:
290
+ <code>rxsrv_win.cmd command</code></p>
291
+
292
+ <p>or start the server with dummy FindMe2Care credentials and access the '/key' entrypoint of the server.</p>
293
+
294
+ <h4>Configuring using Environment Variables</h4>
295
+
296
+ <p>The following command starts the server and reads the configuration from environment variables.
297
+ Note that the env variables can be set in the
298
+ environment's config file, e.g. when using Docker or NGINX. Setting the port is optional.</p>
299
+
300
+ <p>```
301
+ export RXID=rxome
302
+ export RXKEY=private_key_for_rxome
303
+ export RXPORT=4242</p>
304
+
305
+ <p>rxsrv -e
306
+ ```</p>
307
+
308
+ <p>Where <code>RXID</code> is the API username (not to be confused with the login name)
309
+ of the laboratory on the FindMe2Care platform, <code>RXKEY</code> is the
310
+ private API access key matching the public key stored on the lab's profile on the
311
+ FindMe2Care platform. See the README of the rxome-qrcode-generator for generating the
312
+ API keys.</p>
313
+
314
+ <p>Note that storing secret information in environment variables may pose a security risk; therefore, this option is not recommended and should only be used if the software runs in an isolated environment.</p>
315
+
316
+ <h4>Configuring using Config File</h4>
317
+
318
+ <p>Example config file (setting the port is optional.)</p>
319
+
320
+ <p><code>cat demo.cfg
321
+ {
322
+ &quot;id&quot;: &quot;rxome&quot;,
323
+ &quot;key&quot;: &quot;private_key_for_rxome&quot;,
324
+ &quot;port&quot;: &quot;4242&quot;
325
+ }</code></p>
326
+
327
+ <p>Start the server and read settings from config file:</p>
328
+
329
+ <p><code>rxsrv -c demo.cfg</code></p>
330
+
331
+ <h4>Registering and Unregistering the Windows Service</h4>
332
+
333
+ <p>The npm package <code>rxome-server-win</code> provides a Windows executable that you can start with:</p>
334
+
335
+ <p><code>rxsrv_win.cmd command</code></p>
336
+
337
+ <p>where command is one of</p>
338
+
339
+ <ul>
340
+ <li>install</li>
341
+ <li>uninstall</li>
342
+ <li>ping</li>
343
+ <li>newkey</li>
344
+ <li>help</li>
345
+ </ul>
346
+
347
+ <p>Note that the Windows service is configured with a config file given by <code>%RXCFG%</code> or, if none specified,
348
+ the default file <code>%APPDATA\npm\node_modules\rxome-server-win\demo.cfg</code> is used.</p>
349
+
350
+ <h3>2.3 Using Docker</h3>
351
+
352
+ <p>Instead of installing node.js and starting the server manually, you can use a docker image to run the service, e.g., with</p>
353
+
354
+ <p><code>docker run -d -p 1607:1607 tomkamphans/rxsrv:current -i &quot;your_key_id&quot; -s &quot;your_private_key&quot;</code></p>
355
+
356
+ <p>Also, you can specify key ID and key using environment variables, which may be useful in a docker compose or kubernetes setting:</p>
357
+
358
+ <p><code>docker run -d -p 1607:1607 -e RXID=&quot; your_key_id&quot; -e RXKEY=&quot;your_private_key&quot; tomkamphans/rxsrv:current</code></p>
359
+
360
+ <p>Where <code>your_key_id</code> is the lab's API user name and your_key is the private API key as described above.</p>
361
+
362
+ <p>When starting the first time (or when a new key pair should be used), you can start the service with</p>
363
+
364
+ <p><code>docker run -d -p 1607:1607 tomkamphans/rxsrv:current -i &quot;your_key_id&quot; -K</code></p>
365
+
366
+ <p>to generate a new key pair. Before starting the service, the script outputs the new keys. You should copy the public key into your FM2C profile, the private key
367
+ is immediately used to run the service.</p>
368
+
369
+ <p>Note that the first port number in <code>-p 1607:1607</code> denotes the port on <em>localhost</em> to which the docker internal port (denoted the second port number, in this case 1607 also) is mapped. So if you need to run the service on another port, say 8081, use
370
+ <code>docker run -p 8081:1607 ...</code>.</p>
371
+
372
+ <p>Hint for Docker on Windows: set the start type of <em>Docker Desktop Service</em> to <em>automatic</em> using the Windows Services App (services.msc).</p>
373
+
374
+ <h3>2.4 API Endpoints</h3>
375
+
376
+ <p>The server provides the following endpoints, see descriptions below:</p>
377
+
378
+ <ul>
379
+ <li><code>GET /</code></li>
380
+ <li><code>GET /demo</code></li>
381
+ <li><code>POST /</code></li>
382
+ <li><code>POST /img</code></li>
383
+ <li><code>GET /key</code></li>
384
+ </ul>
385
+
386
+ <h4>Testing connection</h4>
387
+
388
+ <p>Querying the url <code>localhost:&lt;port&gt;/</code> should yield a line such as</p>
389
+
390
+ <p><code>This is the RxOME QRcode generator API Version 0.0.1 for lab id rxome running on port 1607 with PID 26584</code></p>
391
+
392
+ <h4>Getting Demo Data</h4>
393
+
394
+ <p>For convenient testing, the server provides a demo JSON file by sending a GET request to <code>/data</code>.</p>
395
+
396
+ <h4>Getting a QR-Code in PNG</h4>
397
+
398
+ <p>Send a JSON file with the data for the RxOME code generator by POST request to <code>/img</code>, e.g.</p>
399
+
400
+ <p><code>curl -X POST -H &quot;Content-Type: application/json&quot; -d @demo_data_full.json --output qrcode.png localhost:1607/img</code></p>
401
+
402
+ <h4>Getting QR-Code and Pseudonym in JSON Format</h4>
403
+
404
+ <p>In addition to the QR-Code itself, the code generator yields the pseudonym given to this patient
405
+ and the full unencrypted content of the QR code. The laboratory may
406
+ use this pseudonym if the patient is re-evaluated and gets a new QR-Code. Thus, the former medical data can be
407
+ overwritten in the FindMe2Care Database. To get the QR-code and the pseudonyme in JSON format, send the input JSON file to <code>/</code>:</p>
408
+
409
+ <p><code>curl -X POST -H &quot;Content-Type: application/json&quot; -d @demo_data_full.json --output qrcode.json localhost:1607/</code></p>
410
+
411
+ <p>This yields a JSON response containing</p>
412
+
413
+ <p><code>{
414
+ qr_code: (QR code),
415
+ pseudonym: (pseudonym used to generate the QR code),
416
+ qr_content: content of the QR code but with unencrypted medical data for documentation purposes
417
+ }</code></p>
418
+
419
+ <h3>2.5 Server Command-Line Tool</h3>
420
+
421
+ <p>```
422
+ FindMe2care QR-Code generation server</p>
423
+
424
+ <p>Usage: rxsrv -e | -c &lt;cfg_file&gt; | -i <id> (-k &lt;key_file&gt; | -s <key> | -K) [-p <port>]</p>
425
+
426
+ <p>Starts the QR-code tool as service listening on localhost:<port>.
427
+ Before first use, please use the -K option to generate an API access key and deposit the public key
428
+ on the FindMe2care server.</p>
429
+
430
+ <p>Given multiple key options, -K has highest priority.</p>
431
+
432
+ <p>The command-line parameters -k, -s, -p precede the environment variables (if -e specified), which,
433
+ in turn, precede the config file (if -c is also specified).
434
+ A key string (-s) has precedence over a key from a key file (-k).</p>
435
+
436
+ <p>If no parameter is given, -e is assumed.</p>
437
+
438
+ <p>Options:
439
+ -V, --version output the version number
440
+ -c, --config <filename> JSON file with config, entries id, key, [port]; -c-- to read from stdin
441
+ -e, --environment use environment variables RXID, RXKEY, RXPORT to configure rxsrv (useful
442
+ for working with docker)
443
+ -i, --keyId <id> API access ID
444
+ -k, --keyFile <filename> Filename with API access key (default: use -s)
445
+ -s, --key &lt;key string&gt; API access key
446
+ -p, --port <port> Set port for server, default: 1607
447
+ -K, --newkey Generate new key pair, print both keys and start the server with the keys
448
+ -h, --help display help for command</p>
449
+
450
+ <p>Author: Tom Kamphans, GeneTalk GmbH, 2023
451
+ ```</p>
452
+
453
+ <h2>3. Data Format</h2>
454
+
455
+ <h3>3.1 Modifications to the PhenoPacket Standard</h3>
456
+
457
+ <h4>Meta Data and Credentials</h4>
458
+
459
+ <p>For convenience, all data needed to generate a QR code can be specified in one JSON file
460
+ (or, when using the library functions, one JavaScript object).
461
+ In addition to the medical data, the JSON files or objects accepted by rxcode and the
462
+ rxcode library may contain the credentials to access the RxOME API and - if existing -
463
+ the patients pseudonym from earlier issued QR codes.
464
+ Note that the information given in the credential section is mandatory
465
+ when using the library functions.
466
+ When using the command line, these data can be part of the input JSON
467
+ or specified using command line arguments.
468
+ Pleace specify <em>either</em> a file containing the API access key (keyFile, -k)
469
+ <em>or</em> the key itself (key, -s).</p>
470
+
471
+ <p>When a pseudonym is given (either in the meta data or with command line option <code>-P</code>),
472
+ the QR code will be generated using this pseudonym (this must be a valid/known RxOME
473
+ pseudonym, see introduction). Otherwise, a new one will be
474
+ fetched from the server. In both cases, the
475
+ pseudonym used will be part of the output for futher processing or storing.</p>
476
+
477
+ <p>```
478
+ {
479
+ ...
480
+ metaData: {
481
+ ...
482
+ pseudonym: '19T5K7042'
483
+ }
484
+ credentials: {
485
+ keyId: &lt;lab-id/key-id, corresponding to private key&gt;
486
+ key: &lt;private key&gt;
487
+ keyFile: &lt;name of file containing private key&gt; // please specify key OR keyFile
488
+ user: e.g., hans.motkamp@genetalk.de
489
+ }</p>
490
+
491
+ <p>}
492
+ ```</p>
493
+
494
+ <h4>Phenotypic Features</h4>
495
+
496
+ <p>The rxome library extends the PhenoPacket schema for storing phenotypicFeatures (HPO terms). In addition the notation suggested by PhenoPackets:</p>
497
+
498
+ <p>```
499
+ &quot;phenotypicFeatures&quot;: [
500
+ {
501
+ &quot;type&quot;: {
502
+ &quot;id&quot;: &quot;HP:0003155&quot;
503
+ }
504
+ },
505
+ {
506
+ &quot;type&quot;: {
507
+ &quot;id&quot;: &quot;HP:0001249&quot;
508
+ }
509
+ },
510
+ {
511
+ &quot;type&quot;: {
512
+ &quot;id&quot;: &quot;HP:0001250&quot;
513
+ }
514
+ }, {
515
+ &quot;type&quot;: {
516
+ &quot;id&quot;: &quot;HP: 0031360&quot;
517
+ },
518
+ &quot;excluded&quot;: true
519
+ }
520
+ ]</p>
521
+
522
+ <p>```</p>
523
+
524
+ <p>the terms can be stored in a shorter and more convenient form:</p>
525
+
526
+ <p><code>&quot;compressedFeatures&quot;: {
527
+ &quot;included&quot;: [
528
+ &quot;HP:0003155&quot;,
529
+ &quot;HP:0001249&quot;,
530
+ &quot;HP:0001250&quot;
531
+ ],
532
+ &quot;excluded&quot;: [
533
+ &quot;HP:0031360&quot;
534
+ ]
535
+ }</code></p>
536
+
537
+ <h4>Additional Data</h4>
538
+
539
+ <p>The RxOME data format allows to store informations that are not provided by the phenopacket format by using
540
+ the phenopacket extension fields in the form</p>
541
+
542
+ <p>```
543
+ &quot;extensions&quot;: [
544
+ {
545
+ &quot;name&quot;: &quot;...&quot;,
546
+ &quot;value&quot;: &quot;...&quot;
547
+ },
548
+ {
549
+ &quot;name&quot;: &quot;...&quot;,
550
+ &quot;value&quot;: &quot;...&quot;
551
+ }
552
+ ]</p>
553
+
554
+ <p>```</p>
555
+
556
+ <ul>
557
+ <li><p>The type of genetic test performed to obtain a variant (extension field name <em>test-type</em>)</p></li>
558
+ <li><p>CNV information (field name <em>cnv</em>). Possible values:</p>
559
+
560
+ <ul>
561
+ <li>0 = Not provided (default)</li>
562
+ <li>1 = Deletion</li>
563
+ <li>2 = Duplication</li>
564
+ </ul></li>
565
+ <li><p>Methylation (field name <em>meth</em>). Possible values:</p>
566
+
567
+ <ul>
568
+ <li>0 = Not provided</li>
569
+ <li>1 = Hypermethylation</li>
570
+ <li>2 = Hypomethylation</li>
571
+ <li>3 = Intermediate</li>
572
+ </ul></li>
573
+ <li><p>Allele Frequency (field name <em>af</em>)</p></li>
574
+ <li><p>Repeat length (field name <em>rl</em>)</p></li>
575
+ <li><p>Chromosomal Region (field name <em>chr</em>)</p></li>
576
+ <li><p>Methylation site (field name <em>site</em>)</p></li>
577
+ </ul>
578
+
579
+ <h6>Example: test type</h6>
580
+
581
+ <p>The type of genetic test performed to obtain a variant can be specified in an extension field to the genomic interpretation in the <em>variationDescriptor</em> section:</p>
582
+
583
+ <p><code>&quot;genomicInterpretations&quot;: [
584
+ [
585
+ {
586
+ &quot;variantInterpretation&quot;: {
587
+ &quot;acmgPathogenicityClassification&quot;: &quot;Pathogenic&quot;,
588
+ &quot;variationDescriptor&quot;: {
589
+ &quot;geneContext&quot;: {
590
+ &quot;expressions&quot;: [
591
+ {
592
+ &quot;syntax&quot;: &quot;hgvs.c&quot;,
593
+ &quot;value&quot;: &quot;NM_017837.4(PIGV):c.1022C&gt;A (p.Ala341Glu)&quot;
594
+ }
595
+ ],
596
+ &quot;allelicState&quot;: {
597
+ &quot;id&quot;: &quot;GENO_0000136&quot;
598
+ },
599
+ &quot;extensions&quot;: [
600
+ {
601
+ &quot;name&quot;: &quot;test-type&quot;,
602
+ &quot;value&quot;: &quot;Single gene sequencing&quot;
603
+ }
604
+ ]
605
+ }
606
+ }
607
+ }
608
+ }
609
+ ]
610
+ ]</code></p>
611
+
612
+ <h4>Additional Remarks</h4>
613
+
614
+ <p>Additional remarks can be specified in a <em>comment</em> field on the top level:</p>
615
+
616
+ <p><code>{
617
+ &quot;id&quot;: &quot;QR-Code ID&quot;,
618
+ &quot;comment&quot;: &quot;useful remarks&quot;,
619
+ &quot;subject&quot;: {
620
+ ...</code></p>
621
+
622
+ <h4>Whitelist Filter</h4>
623
+
624
+ <p>Before packing the data, needless sections (that is, sections that are not evaluted by RxOME)
625
+ are removed. On top level, the following section will be passed over to the QR code:</p>
626
+
627
+ <ul>
628
+ <li>id</li>
629
+ <li>comment</li>
630
+ <li>subject</li>
631
+ <li>phenotypicFeatures</li>
632
+ <li>interpretations</li>
633
+ <li>diagnosis</li>
634
+ <li>metaData</li>
635
+ <li>credentials (not passed to QR code, but also not removed by whitelist filtering)</li>
636
+ </ul>
637
+
638
+ <h3>3.2 Special phenopacket entries</h3>
639
+
640
+ <p>In this section, we give some additional explanations to some of the fields in the phenopacket schema.</p>
641
+
642
+ <h4>Diagnosis/Disease</h4>
643
+
644
+ <p>The diagnosis can be specified in the <em>disease</em> field.
645
+ IMPORTANT: Note that the</p>
646
+
647
+ <h4>Zygosity</h4>
648
+
649
+ <p>The zygosity is specified in the field <em>allelicState</em> in the <em>variationDescriptor</em> section. According to the
650
+ phenopacket standard, possible values are</p>
651
+
652
+ <ul>
653
+ <li>GENO_0000137 for 'unspecified_zygosity'</li>
654
+ <li>GENO_0000136 for 'homozygous'</li>
655
+ <li>GENO_0000135 for 'heterozygous'</li>
656
+ <li>GENO_0000402 for 'compound_heterozygous'</li>
657
+ <li>GENO_0000134 for 'hemizygous'</li>
658
+ <li>GENO_0000604 for 'hemizygous_X_linked'</li>
659
+ <li>GENO_0000605 for 'hemizygous_Y_linked'</li>
660
+ <li>GENO_0000606 for 'hemizygous_insertion_linked'</li>
661
+ <li>GENO_0000392 for 'aneusomic_zygosity'</li>
662
+ <li>GENO_0000393 for 'trisomic_homozygous'</li>
663
+ <li>GENO_0000394 for 'trisomic_heterozygous'</li>
664
+ <li>GENO_0000602 for 'homoplasmic'</li>
665
+ <li>GENO_0000603 for 'heteroplasmic'</li>
666
+ <li>GENO_0000964 for 'mosaic'</li>
667
+ </ul>
668
+
669
+ <h3>3.3 Payload Example File</h3>
670
+
671
+ <p><code>{
672
+ &quot;id&quot;: &quot;232DTCEZZCQX&quot;,
673
+ &quot;subject&quot;: {
674
+ &quot;dateOfBirth&quot;: &quot;2021-07-16&quot;,
675
+ &quot;sex&quot;: 1
676
+ },
677
+ &quot;comment&quot;: &quot;Demo record&quot;,
678
+ &quot;compressedFeatures&quot;: {
679
+ &quot;includes&quot;: [
680
+ &quot;HP:0003155&quot;,
681
+ &quot;HP:0001250&quot;,
682
+ &quot;HP:0001249&quot;
683
+ ],
684
+ &quot;excludes&quot;: [
685
+ &quot;HP:0031360&quot;
686
+ ]
687
+ },
688
+ &quot;interpretations&quot;: [
689
+ {
690
+ &quot;id&quot;: &quot;first&quot;,
691
+ &quot;progressStatus&quot;: 3,
692
+ &quot;diagnosis&quot;: {
693
+ &quot;disease&quot;: {
694
+ &quot;id&quot;: &quot;OMIM:614207&quot;
695
+ },
696
+ &quot;genomicInterpretations&quot;: [
697
+ {
698
+ &quot;subjectOrBiosampleId&quot;: &quot;0vlqzsw094u.0&quot;,
699
+ &quot;interpretationStatus&quot;: &quot;3&quot;,
700
+ &quot;variantInterpretation&quot;: {
701
+ &quot;acmgPathogenicityClassification&quot;: &quot;5&quot;,
702
+ &quot;variationDescriptor&quot;: {
703
+ &quot;geneContext&quot;: {
704
+ &quot;valueId&quot;: &quot;26031&quot;,
705
+ &quot;symbol&quot;: &quot;PIGV&quot;,
706
+ &quot;alternateIds&quot;: [
707
+ &quot;55650&quot;
708
+ ]
709
+ },
710
+ &quot;expressions&quot;: [
711
+ {
712
+ &quot;syntax&quot;: &quot;hgvs.c&quot;,
713
+ &quot;value&quot;: &quot;NM_017837.4(PIGV):c.1022C&gt;A (p.Ala341Glu)&quot;
714
+ }
715
+ ],
716
+ &quot;extensions&quot;: [
717
+ {
718
+ &quot;name&quot;: &quot;test-type&quot;,
719
+ &quot;value&quot;: &quot;Single gene sequencing&quot;
720
+ }
721
+ ],
722
+ &quot;allelicState&quot;: {
723
+ &quot;id&quot;: &quot;GENO_0000136&quot;
724
+ }
725
+ }
726
+ }
727
+ },
728
+ {
729
+ &quot;subjectOrBiosampleId&quot;: &quot;qpsczs5l7y.907m2ybforb&quot;,
730
+ &quot;variantInterpretation&quot;: {
731
+ &quot;acmgPathogenicityClassification&quot;: &quot;1&quot;,
732
+ &quot;variationDescriptor&quot;: {
733
+ &quot;geneContext&quot;: {
734
+ &quot;valueId&quot;: &quot;31369&quot;,
735
+ &quot;symbol&quot;: &quot;TOMM5&quot;,
736
+ &quot;alternateIds&quot;: [
737
+ &quot;401505&quot;
738
+ ]
739
+ },
740
+ &quot;expressions&quot;: [
741
+ {
742
+ &quot;syntax&quot;: &quot;hgvs.c&quot;,
743
+ &quot;value&quot;: &quot;... hgvs code ...&quot;
744
+ },
745
+ {
746
+ &quot;syntax&quot;: &quot;iscn&quot;,
747
+ &quot;value&quot;: &quot;... iscn data ...&quot;
748
+ }
749
+ ],
750
+ &quot;extensions&quot;: [
751
+ {
752
+ &quot;name&quot;: &quot;test-type&quot;,
753
+ &quot;value&quot;: &quot;Multigene panel&quot;
754
+ },
755
+ {
756
+ &quot;name&quot;: &quot;cnv&quot;,
757
+ &quot;value&quot;: &quot;1&quot;
758
+ },
759
+ {
760
+ &quot;name&quot;: &quot;meth&quot;,
761
+ &quot;value&quot;: &quot;1&quot;
762
+ },
763
+ {
764
+ &quot;name&quot;: &quot;af&quot;,
765
+ &quot;value&quot;: &quot;...allele frequency...&quot;
766
+ },
767
+ {
768
+ &quot;name&quot;: &quot;rl&quot;,
769
+ &quot;value&quot;: &quot;... repeat length ...&quot;
770
+ },
771
+ {
772
+ &quot;name&quot;: &quot;chr&quot;,
773
+ &quot;value&quot;: &quot;... chromosomal region ...&quot;
774
+ },
775
+ {
776
+ &quot;name&quot;: &quot;site&quot;,
777
+ &quot;value&quot;: &quot; ... methylation site ...&quot;
778
+ }
779
+ ],
780
+ &quot;allelicState&quot;: {
781
+ &quot;id&quot;: &quot;GENO_0000136&quot;
782
+ }
783
+ }
784
+ }
785
+ },
786
+ {
787
+ &quot;subjectOrBiosampleId&quot;: &quot;qpsczs5l7y.k0z7yqgy8gi&quot;,
788
+ &quot;variantInterpretation&quot;: {
789
+ &quot;acmgPathogenicityClassification&quot;: &quot;Unknown&quot;,
790
+ &quot;variationDescriptor&quot;: {
791
+ &quot;geneContext&quot;: {
792
+ &quot;valueId&quot;: &quot;34528&quot;,
793
+ &quot;symbol&quot;: &quot;TOMM6&quot;,
794
+ &quot;alternateIds&quot;: [
795
+ &quot;100188893&quot;
796
+ ]
797
+ },
798
+ &quot;expressions&quot;: [
799
+ {
800
+ &quot;syntax&quot;: &quot;hgvs.c&quot;,
801
+ &quot;value&quot;: &quot;HGVS2&quot;
802
+ }
803
+ ],
804
+ &quot;extensions&quot;: [
805
+ {
806
+ &quot;name&quot;: &quot;test-type&quot;,
807
+ &quot;value&quot;: &quot;Multigene panel&quot;
808
+ }
809
+ ],
810
+ &quot;allelicState&quot;: {
811
+ &quot;id&quot;: &quot;None&quot;
812
+ }
813
+ }
814
+ }
815
+ }
816
+ ]
817
+ }
818
+ }
819
+ ],
820
+ &quot;metaData&quot;: {
821
+ &quot;created&quot;: &quot;2024-08-13&quot;,
822
+ &quot;createdBy&quot;: &quot;ACME Genetics&quot;,
823
+ &quot;submittedBy&quot;: &quot;genetics@acme.org&quot;,
824
+ &quot;pseudonym&quot;: &quot;232DTCEZZCQX&quot;
825
+ }
826
+ }</code></p>
827
+
828
+ <!--
829
+ ## Acknowledgments
830
+ openpgp https://openpgpjs.org/
831
+ node-qrcode https://github.com/soldair/node-qrcode
832
+ noble-ed25519
833
+ -->
834
+