# Survey Import: Qualtrics, SurveyJS, LimeSurvey, XLSForm, REDCap, Beiwe and Network Canvas

Source: https://www.potatoannotator.com/docs/tools/survey-import

*New in v2.12.0*

`potato import` turns a questionnaire built in another tool into Potato survey pages: the questions, the pages, and the show/hide logic, translated into Potato's [conditional questions](/docs/features/surveyflow#conditional-questions) and page rules.

| Source | File | `-f` |
|---|---|---|
| [Qualtrics](https://www.qualtrics.com/) | `.qsf` (Survey → Tools → Import/Export → Export Survey) | `qualtrics` |
| [SurveyJS](https://surveyjs.io/) | The survey JSON that SurveyJS Creator saves | `surveyjs` |
| [LimeSurvey](https://www.limesurvey.org/) | `.lss` (Display/Export → Survey structure) | `limesurvey` |
| XLSForm ([ODK](https://getodk.org/), [KoboToolbox](https://www.kobotoolbox.org/), SurveyCTO, Ona) | `.xlsx` | `xlsform` |
| [REDCap](https://projectredcap.org/) | The data dictionary `.csv` (Designer → Download the current Data Dictionary), or the API metadata export | `redcap` |
| Beiwe | Survey JSON, or a study settings export | `beiwe` |
| [Network Canvas](https://networkcanvas.com/) | A `.netcanvas` protocol file, or its `protocol.json` | `network_canvas` |

The format is detected from the file, and `-f` chooses it explicitly. None of these files holds responses, so the import moves the instrument and not the data collected with it.

## Import into a new project

```bash
potato import -i screener.qsf -o my-study/
python potato/flask_server.py start my-study/config.yaml -p 8000
```

The survey pages go in `my-study/surveys/`, one JSON file per page. `config.yaml` lists them in `phases.order` before an `annotation` phase with a placeholder question and three placeholder items, which you replace with the real task.

## Import into an existing project

```bash
potato import -i exit_survey.lss --into my-study/config.yaml --survey-slot poststudy --prefix exit_
```

The pages go in `surveys/` beside that config, and a merged copy is written as `config.with-exit_survey-exit.yaml`, with the report in `IMPORT_REPORT.exit_survey-exit.md`. The original config is not changed.

`--prefix` renames every imported question and page. Use it when question names would clash with the project's own, since the import stops on a clash. The import also stops rather than replace files an earlier import wrote, so edits made to an imported survey are not overwritten.

The merged copy differs from the original in more than the new pages. If the config does not set `export_include_phase_data`, the copy sets it to `true` so that the survey answers are exported, and a comment at the top of the copy says so. Survey answers can hold personal data, so set it to `false` to leave them out of exports. Comments in the original are not kept, and YAML lists are rewritten in block style.

| Flag | Meaning |
|---|---|
| `-o DIR` | Writes a new project |
| `--into CONFIG` | Adds the pages to an existing project and writes a merged copy |
| `--survey-slot` | `prestudy` (the default, before annotation) or `poststudy` |
| `--prefix` | Prefix for every imported question and page name |
| `--survey-language` | Language to take from a multilingual LimeSurvey, XLSForm or Network Canvas survey |

## What carries over from every format

- question wording (HTML is reduced to text), choices, and required questions;
- pages, in order;
- show/hide logic on questions and pages, translated to `display_logic` and page `show_when`, including nested AND, OR and NOT;
- choice order randomization (`randomize_order`) and question order randomization (`randomize_questions`) where the source has them.

Answers to choice questions are stored as the option text, so the translated logic compares against option text, not the source's codes.

Everything the importer could not translate is listed in `IMPORT_REPORT.md` with where it was and why, and the first ten are printed. A logic rule that contains anything untranslatable is reported whole, and the question is left always visible rather than given part of its rule.

## Qualtrics

Each block is a page, and each page break inside a block starts another. Trash blocks are skipped.

- **Questions:** multiple choice (single, multiple, dropdown, NPS), Matrix Likert (as `multirate`), text entry (single line, multi-line, number validation as `number`, forms as one text question per field), sliders, rank order (`ranking`), constant sum (`constant_sum`) and descriptive text (`pure_display`). "Other" choices with a text box get a free-text field.
- **Logic:** display logic with Qualtrics' precedence (AND before OR within a condition set, and between `If`, `AndIf` and `ElseIf` sets), on selected choices, text-entry values, slider values and selection counts.
- **Survey flow:** branches become page rules, with nested branches combined by AND. A randomizer that shows all of its blocks becomes a counterbalance group. A randomizer that shows one of several embedded-data assignments to one field becomes a between-subjects factor under `conditions`, and logic on that field tests `condition.<field>`. End of Survey inside a branch, and skip logic to the end of the survey, become `exit_when`.
- **Reported, not imported:** Loop & Merge (the block is imported once), piped text, matrix-cell logic, "is displayed" conditions, choice-level display logic, quotas, web services, authenticators, scoring, custom validation, request-response (soft required), JavaScript, and the question types Potato has no equivalent for (heat maps, hot spots, file upload, signature, side-by-side, timing, meta info).

[Coming from Qualtrics](/docs/guides/coming-from-qualtrics) maps the rest of a Qualtrics study to Potato.

## SurveyJS

- **Elements:** text (number inputs as `number`), comment, radiogroup, checkbox, dropdown, tagbox, boolean, rating, ranking, matrix, multipletext (one text question per item), html and slider. Panels are flattened into the page, and a panel's `visibleIf` applies to each question in it.
- **Logic:** `visibleIf` on questions, panels and pages, including `anyof`, `allof`, `contains`, `empty`, `{q.length}` selection counts, and `and`, `or` and `!`. A `complete` trigger becomes an `exit_when` on the page that asks the last question it tests.
- **Reported, not imported:** `enableIf`, `requiredIf`, `choicesVisibleIf`, validators, default values, calculated values and expression questions, `setvalue`, `skip` and `runexpression` triggers, dynamic matrices and panels, file and signature questions, and logic that calls functions.

## LimeSurvey

Both file layouts import: older exports with a language column on each row, and exports from DBVersion 400 on, with the text in `*_l10ns` tables. The survey's base language is used unless `--survey-language` says otherwise. Question groups become pages, in order, and group relevance becomes the page's `show_when`.

- **Questions:** list (radio, dropdown, with comment), 5-point, yes/no, gender, multiple choice, the array types (as `multirate`), short and long text, numerical, multiple numerical and multiple short text (one question per subquestion), ranking and text display.
- **Logic:** ExpressionScript relevance on question codes, subquestion codes and SGQA names, with `is_empty()`, `count()` over a multiple-choice question, and `and`, `or` and `!`, plus the older `conditions` table.
- **Reported, not imported:** date, equation, file upload and dual-scale questions; hidden questions; validation (`preg`, `em_validation`); minimum and maximum answers; array filters; randomization groups; quotas; assessments; piped text; and `if()`, `regexMatch()` and `.shown` in logic.

## XLSForm: ODK, KoboToolbox, SurveyCTO and Ona

ODK shows one question per screen unless a group asks for more, and Potato puts a page's questions together, so the import uses the form's own grouping. Each `begin_group` with `appearance: field-list` or `table-list` is one page, and the questions between such groups share a page. Another group's `relevant` is applied to every question inside it, and its label becomes a heading. For a form with several label columns, such as `label::English` and `label::French`, `--survey-language French` picks one, and otherwise the form's `default_language` is used.

| XLSForm | Potato |
|---|---|
| `select_one` | `radio` (`appearance: minimal` as a dropdown) |
| `select_multiple` | `multiselect` |
| `rank` | `ranking` |
| `integer`, `decimal` | `number` |
| `range` | `slider` (`parameters: start= end= step=`) |
| `text` | `text` (`appearance: multiline` as a text box) |
| `note` | `pure_display` |
| `or_other` | An "Other" option with a text field |
| `required` | `label_requirement: {required: true}` |
| `relevant` | `display_logic`, with `selected()`, `not()`, `count-selected()`, `string-length()`, `regex()` and comparisons |
| `parameters: randomize=true` | `randomize_order` |

Reported, not imported: geopoints and other location types, date and time, photos, audio, video, barcodes and files; `calculate` and `hidden` fields and logic that uses them; repeats (their questions are imported once); `constraint`, `choice_filter`, `default`, `read_only` and conditional `required`; and external choice lists. An `.xls` file needs the `xlrd` package, or save it as `.xlsx`.

## REDCap

Each instrument (form) becomes a page, in the order the dictionary lists them, and section headers become headings on the page.

| REDCap | Potato |
|---|---|
| `text` with integer or number validation | `number` with the validation minimum and maximum |
| `text` with other validation, `notes` | `text`, a text box for notes |
| `radio`, `dropdown`, `checkbox` | `radio`, `select`, `multiselect` |
| `yesno`, `truefalse` | `radio` with Yes/No or True/False |
| `slider` | `slider` |
| `descriptive` | `pure_display` |
| Matrix group | `multirate`, or separate questions when logic tests a row |
| Required field | `label_requirement: {required: true}` |
| Branching logic | `display_logic`, with choice codes mapped to the option text and `and` binding tighter than `or` |
| `@PLACEHOLDER` | The text box placeholder |
| `@HIDDEN`, `@HIDDEN-SURVEY` | Left out, since participants never see them |

Reported, not imported: calculated fields and logic that uses them, file and SQL fields, validation types Potato does not check (dates, emails and phone numbers become plain text with a format hint), other action tags, piped values, and logic that uses functions (`datediff`, `sum`), events (`[event][field]`) or form status. REDCap's longitudinal events and repeating instruments have no Potato equivalent.

Potato is not a clinical data capture system and has no audit trail of the kind REDCap provides for regulated studies. Keep identifiable health data in REDCap, and use Potato for the annotation and the questions around it, such as clinicians labeling notes or images.

## Beiwe

Each survey in the export becomes a page. Info text, slider, radio button, checkbox and free-response (numeric, single line, multi-line) questions import, and `display_if` logic translates, with radio answers tested by position and checkbox answers by membership. Date and time questions, audio surveys, schedules and timings are reported, because Potato has no survey scheduling, and so is partial randomization.

## Network Canvas

An ego form or information stage becomes a survey page, and the network stages for one node type become one [`ego_network`](/docs/annotation-types/ego-network) question on one page, with its name generators, name interpreters, dyad and tie-strength censuses, and sociogram. CSV or JSON roster assets become the name generator's roster. Ego skip logic becomes `show_when`, and a skip to the end of the interview becomes `exit_when` on the page before, with the finish screen's text as the message.

Network stages for one node type share a page, so they cannot be skipped one by one, and a network stage that came after other pages moves ahead of them. The import reports each move. Node and edge filter rules, alter edge forms, narrative and geospatial stages, date and time variables, and media items are reported and not imported. The [Ego Networks](/docs/annotation-types/ego-network#importing-a-network-canvas-protocol) page has the stage-by-stage mapping.

## Further Reading

- [Coming from Qualtrics](/docs/guides/coming-from-qualtrics) - A Qualtrics study's features mapped to Potato
- [Multi-Phase Workflows](/docs/features/surveyflow) - Survey pages, conditional questions and phase order
- [Experiment Flow](/docs/experiments/experiment-flow) - Conditions, page rules, screen-outs and counterbalancing
- [Importing Projects](/docs/tools/importing-projects) - Annotation formats, whole projects and other imports
- [Survey Instruments](/docs/features/survey-instruments) - Published questionnaires by name

For implementation details, see the [source documentation](https://github.com/davidjurgens/potato/blob/master/docs/tools/survey_import.md).
