@teselagen/ove 0.7.27 → 0.7.28

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.
Files changed (304) hide show
  1. package/AASliver.js +187 -0
  2. package/AddLaddersDialog.js +82 -0
  3. package/AdditionalCutsiteInfoDialog.js +599 -0
  4. package/AlignmentView/Mismatches.d.ts +3 -3
  5. package/AlignmentVisibilityTool.js +105 -0
  6. package/AnnotationContainerHolder.js +20 -0
  7. package/AnnotationPositioner.js +27 -0
  8. package/AutoAnnotate.js +501 -0
  9. package/AutoAnnotateBpMatchingDialog.js +208 -0
  10. package/Axis.js +151 -0
  11. package/AxisNumbers.js +35 -0
  12. package/Browser.js +106 -0
  13. package/Caret.js +63 -0
  14. package/Chromatogram.js +293 -0
  15. package/CircularDnaSequence.js +73 -0
  16. package/CircularView/Labels/index.d.ts +1 -1
  17. package/CircularView/index.d.ts +0 -1
  18. package/CircularZoomMinimap.js +16 -0
  19. package/ColorPicker.js +30 -0
  20. package/CommandHotkeyHandler.js +44 -0
  21. package/CreateAnnotationsPage.d.ts +4 -4
  22. package/CreateAnnotationsPage.js +98 -0
  23. package/Cutsite.js +18 -0
  24. package/CutsiteProperties.js +176 -0
  25. package/CutsiteSelectionLayers.js +47 -0
  26. package/Cutsites.js +271 -0
  27. package/DeletionLayer.js +28 -0
  28. package/DigestTool/Ladder.d.ts +1 -1
  29. package/DropHandler.css +21 -0
  30. package/DropHandler.js +64 -0
  31. package/EditCaretPosition.js +234 -0
  32. package/EditTrackNameDialog.js +30 -0
  33. package/Feature.js +83 -0
  34. package/FeatureProperties.js +6 -0
  35. package/FillWindow.js +47 -0
  36. package/GenbankView.js +74 -0
  37. package/GeneralProperties.js +117 -0
  38. package/GenericAnnotationProperties.js +406 -0
  39. package/GlobalDialog.js +73 -0
  40. package/GlobalDialogUtils.js +110 -0
  41. package/GoToDialog.js +25 -0
  42. package/HorizontalPanelDragHandle.js +35 -0
  43. package/Keyboard.js +85 -0
  44. package/Labels.js +327 -0
  45. package/Ladder.css +20 -0
  46. package/Ladder.js +303 -0
  47. package/MeltingTemp.js +85 -0
  48. package/Menlo.ttf +0 -0
  49. package/Minimap.js +515 -0
  50. package/Mismatches.js +134 -0
  51. package/Monaco.ttf +0 -0
  52. package/MultipleSeqsDetectedOnImportDialog.js +74 -0
  53. package/Orf.js +109 -0
  54. package/OrfProperties.js +117 -0
  55. package/Orfs.js +35 -0
  56. package/PCRTool.js +179 -0
  57. package/PairwiseAlignmentView.js +68 -0
  58. package/Part.js +34 -0
  59. package/PartProperties.js +9 -0
  60. package/PassThrough.js +3 -0
  61. package/PerformantSelectionLayer.js +32 -0
  62. package/PinchHelper.js +24 -0
  63. package/PointedAnnotation.js +347 -0
  64. package/PositionAnnotationOnCircle.js +26 -0
  65. package/Primer.js +41 -0
  66. package/PrimerProperties.js +19 -0
  67. package/Reflex/index.d.ts +0 -1
  68. package/ReflexContainer.js +802 -0
  69. package/ReflexElement.js +160 -0
  70. package/ReflexEvents.js +77 -0
  71. package/ReflexSplitter.js +205 -0
  72. package/RenameSequenceDialog.js +7 -0
  73. package/RotateCircularViewSlider.js +93 -0
  74. package/RowView/index.d.ts +0 -1
  75. package/SelectDialog.js +150 -0
  76. package/SequenceName.js +15 -0
  77. package/SimpleCircularOrLinearView.js +381 -0
  78. package/SimpleOligoPreview.js +39 -0
  79. package/SingleEnzymeCutsiteInfo.js +139 -0
  80. package/ToolBar/ToolbarItem.d.ts +1 -3
  81. package/ToolbarItem.js +192 -0
  82. package/Translation.js +198 -0
  83. package/TranslationProperties.js +149 -0
  84. package/UncontrolledSliderWithPlusMinusBtns.css +5 -0
  85. package/UncontrolledSliderWithPlusMinusBtns.js +134 -0
  86. package/VeTopRightContainer.js +12 -0
  87. package/ZoomCircularViewSlider.js +62 -0
  88. package/ZoomLinearView.js +47 -0
  89. package/addAlignment.js +6 -0
  90. package/addMetaToActionCreators.js +12 -0
  91. package/addWrappedAddons.js +20 -0
  92. package/alignmentTool.js +503 -0
  93. package/alignments.js +379 -0
  94. package/annotationLabelVisibility.js +2 -0
  95. package/annotationSearchSelector.js +24 -0
  96. package/annotationTypes.js +35 -0
  97. package/annotationVisibility.js +196 -0
  98. package/annotationsToSupport.js +104 -0
  99. package/arrayToObjWithIds.js +17 -0
  100. package/arrayUtils.js +19 -0
  101. package/array_move.js +10 -0
  102. package/calculateTickMarkPositionsForGivenRange.js +47 -0
  103. package/caretPosition.js +27 -0
  104. package/cdsFeaturesSelector.js +9 -0
  105. package/charWidth.js +22 -0
  106. package/circular.js +19 -0
  107. package/circularSelector.js +4 -0
  108. package/clickAndDragUtils.js +576 -0
  109. package/coerceInitialValue.js +7 -0
  110. package/combineReducersDontIgnoreKeys.js +12 -0
  111. package/commandUtils.js +20 -0
  112. package/constants.js +2 -0
  113. package/copyOptions.js +34 -0
  114. package/createFragmentLines.js +120 -0
  115. package/createMergedDefaultStateReducer.js +30 -0
  116. package/createMetaAction.js +12 -0
  117. package/createSequenceInputPopup.js +290 -0
  118. package/createSequenceInputPopupStyle.css +87 -0
  119. package/createSimpleDialog.js +89 -0
  120. package/createYourOwnEnzyme.js +39 -0
  121. package/cutsiteLabelColorSelector.js +6 -0
  122. package/cutsiteTool.js +88 -0
  123. package/cutsitesByRangeSelector.js +5 -0
  124. package/cutsitesSelector.js +61 -0
  125. package/darkmode.css +98 -0
  126. package/defaultConfig.js +150 -0
  127. package/deletionLayers.js +36 -0
  128. package/description.js +21 -0
  129. package/digestTool.js +34 -0
  130. package/dnaToColor.js +17 -0
  131. package/downloadTool.js +39 -0
  132. package/draggableClassnames.js +5 -0
  133. package/drawAnnotations.js +440 -0
  134. package/drawDirectedPiePiece.js +142 -0
  135. package/editTool.js +49 -0
  136. package/editorSelector.js +2 -0
  137. package/editorUtils.js +205 -0
  138. package/estimateRowHeight.js +184 -0
  139. package/featureLengthsToHide.js +27 -0
  140. package/featureTool.js +34 -0
  141. package/features.js +19 -0
  142. package/featuresSelector.js +8 -0
  143. package/filteredCutsitesSelector.js +136 -0
  144. package/filteredFeaturesSelector.js +32 -0
  145. package/filteredPartsSelector.js +57 -0
  146. package/filteredPrimersSelector.js +27 -0
  147. package/filteredRestrictionEnzymesSelector.js +1 -0
  148. package/find.png +0 -0
  149. package/findTool.js +79 -0
  150. package/findToolConstants.js +1 -0
  151. package/frameTranslations.js +52 -0
  152. package/fullscreen.png +0 -0
  153. package/getAdditionalEnzymesSelector.js +46 -0
  154. package/getAngleForPositionMidpoint.js +3 -0
  155. package/getAnnotationClassnames.js +12 -0
  156. package/getAnnotationNameAndStartStopString.js +61 -0
  157. package/getBpsPerRow.js +19 -0
  158. package/getCutsiteLabelHeights.js +56 -0
  159. package/getGapMap.js +12 -0
  160. package/getGaps.js +27 -0
  161. package/getInternalLabel.js +40 -0
  162. package/getOveHotkeyDefs.js +12 -0
  163. package/getPairwiseOverviewLinearViewOptions.js +38 -0
  164. package/getRangeAnglesSpecial.js +12 -0
  165. package/getStructuredBases.js +97 -0
  166. package/getTrackFromEvent.js +25 -0
  167. package/getVisibleStartEnd.js +7 -0
  168. package/getXStartAndWidthFromNonCircularRange.js +12 -0
  169. package/getXStartAndWidthOfRangeWrtRow.js +27 -0
  170. package/getXStartAndWidthOfRowAnnotation.js +19 -0
  171. package/getYOffset.js +15 -0
  172. package/hoveredAnnotation.js +24 -0
  173. package/{html2canvas.esm--JN4fLQL.js → html2canvas.esm-DiGWN1gP.js} +187 -229
  174. package/{html2canvas.esm-B7d7VJmQ.cjs → html2canvas.esm-J1esNpMJ.cjs} +187 -229
  175. package/importTool.js +27 -0
  176. package/index.cjs.js +48165 -47142
  177. package/index.es.js +47699 -46676
  178. package/index.js +71 -0
  179. package/inlineFindTool.js +38 -0
  180. package/isElementInViewport.js +29 -0
  181. package/isEnzymeFilterAndSelector.js +1 -0
  182. package/isTargetWithinEl.js +6 -0
  183. package/labelLineIntensity.js +25 -0
  184. package/labelSize.js +23 -0
  185. package/ladderDefaults.js +25 -0
  186. package/lastSavedId.js +20 -0
  187. package/lineageLines.js +11 -0
  188. package/linear.png +0 -0
  189. package/makeStore.js +34 -0
  190. package/massageTickSpacing.js +19 -0
  191. package/materiallyAvailable.js +19 -0
  192. package/middleware.js +112 -0
  193. package/minimumOrfSize.js +24 -0
  194. package/minimumOrfSizeSelector.js +2 -0
  195. package/modalActions.js +3 -0
  196. package/moveCaret.js +58 -0
  197. package/name.js +19 -0
  198. package/normalizeAngle.js +3 -0
  199. package/normalizeAngleRange.js +9 -0
  200. package/oligoTool.js +30 -0
  201. package/onlyUpdateForKeysDeep.js +31 -0
  202. package/orfFrameToColorMap.js +10 -0
  203. package/orfTool.js +136 -0
  204. package/orfsSelector.js +15 -0
  205. package/ove.css +12107 -0
  206. package/package.json +6 -5
  207. package/panelsShown.js +294 -0
  208. package/partLengthsToHide.js +23 -0
  209. package/partOverhangs.js +6 -0
  210. package/partTagSearch.js +69 -0
  211. package/partTool.js +45 -0
  212. package/parts.js +19 -0
  213. package/partsSelector.js +8 -0
  214. package/pie.png +0 -0
  215. package/polarToSpecialCartesian.js +7 -0
  216. package/positionCutsites.js +6 -0
  217. package/prepareRowData.js +64 -0
  218. package/primerBases.js +221 -0
  219. package/primerLengthsToHide.js +27 -0
  220. package/primers.js +19 -0
  221. package/primersSelector.js +8 -0
  222. package/print.png +0 -0
  223. package/printTool.js +31 -0
  224. package/propertiesTool.js +40 -0
  225. package/proteinUtils.js +3 -0
  226. package/pureNoFunc.js +18 -0
  227. package/readOnly.js +25 -0
  228. package/redoTool.js +30 -0
  229. package/reflex-styles.css +128 -0
  230. package/reflex-styles.css.map +9 -0
  231. package/relaxLabelAngles.js +157 -0
  232. package/relaxLabels_DEPRECATED.js +105 -0
  233. package/replacementLayers.js +36 -0
  234. package/restrictionEnzymes.js +52 -0
  235. package/restrictionEnzymesSelector.js +34 -0
  236. package/rowviewContants.js +3 -0
  237. package/ruler.css +89 -0
  238. package/save.png +0 -0
  239. package/saveTool.js +44 -0
  240. package/searchLayersSelector.js +71 -0
  241. package/selectedAnnotations.js +89 -0
  242. package/selectedAnnotationsSelector.js +1 -0
  243. package/selectedCutsitesSelector.js +21 -0
  244. package/selectedPartTags.js +21 -0
  245. package/selectionLayer.js +25 -0
  246. package/selectors/annotationSearchSelector.d.ts +1 -1
  247. package/sequence.js +12 -0
  248. package/sequenceDataHistory.js +43 -0
  249. package/sequenceDataSelector.js +2 -0
  250. package/sequenceLengthSelector.js +5 -0
  251. package/sequenceSelector.js +4 -0
  252. package/sharedActionCreators.js +0 -0
  253. package/shouldFlipText.js +4 -0
  254. package/shouldRerender.js +27 -0
  255. package/showFileDialog.js +25 -0
  256. package/showGCContent.js +23 -0
  257. package/show_cut_sites.png +0 -0
  258. package/show_features.png +0 -0
  259. package/show_orfs.png +0 -0
  260. package/show_primers.png +0 -0
  261. package/simpleDialog.css +13 -0
  262. package/specialCutsiteFilterOptions.js +22 -0
  263. package/src/Editor/DropHandler.js +2 -1
  264. package/src/Editor/index.js +0 -2
  265. package/src/RowItem/StackedAnnotations/getStructuredBases.js +20 -6
  266. package/src/ToolBar/cutsiteTool.js +1 -1
  267. package/src/helperComponents/PropertiesDialog/TranslationProperties.js +2 -1
  268. package/style.css +3 -12100
  269. package/tagsToBoldSelector.js +2 -0
  270. package/toggle_views.svg +1 -0
  271. package/toolBar.js +23 -0
  272. package/translationSearchMatchesSelector.js +14 -0
  273. package/translations.js +20 -0
  274. package/translationsRawSelector.js +8 -0
  275. package/translationsSelector.js +137 -0
  276. package/typeField.js +24 -0
  277. package/undoTool.js +30 -0
  278. package/updateEditor.d.ts +1 -3
  279. package/updateEditor.js +200 -0
  280. package/updateLabelsForInViewFeatures.js +55 -0
  281. package/updateLabelsForInViewFeaturesCircView.js +41 -0
  282. package/updateTrackHelper.js +58 -0
  283. package/uppercaseSequenceMapFont.js +25 -0
  284. package/upsertDeleteActionGenerator.js +31 -0
  285. package/useAAColorType.js +8 -0
  286. package/useAdditionalOrfStartCodons.js +24 -0
  287. package/useAnnotationLimits.js +42 -0
  288. package/useChromatogramPrefs.js +31 -0
  289. package/useFormValue.js +7 -0
  290. package/useLadders.js +6 -0
  291. package/useMeltingTemp.js +7 -0
  292. package/useTmType.js +10 -0
  293. package/userDefinedHandlersAndOpts.js +61 -0
  294. package/utils/getAnnotationNameAndStartStopString.d.ts +1 -5
  295. package/utils/selectionLayer.d.ts +2 -2
  296. package/utils.js +37 -0
  297. package/versionHistory.js +26 -0
  298. package/versionHistoryTool.js +21 -0
  299. package/viewSubmenu.js +479 -0
  300. package/visibilityTool.js +39 -0
  301. package/withEditorInteractions/getBpsPerRow.d.ts +1 -3
  302. package/withHover.js +113 -0
  303. package/withRestrictionEnzymes.js +15 -0
  304. package/index.umd.js +0 -188322
@@ -0,0 +1,503 @@
1
+ import React from "react";
2
+ import { Icon, Button, Intent, Classes, Callout } from "@blueprintjs/core";
3
+ import {
4
+ FileUploadField,
5
+ TextareaField,
6
+ EditableTextField,
7
+ CheckboxField,
8
+ wrapDialog
9
+ } from "@teselagen/ui";
10
+ import { reduxForm, FieldArray } from "redux-form";
11
+ import { anyToJson } from "@teselagen/bio-parsers";
12
+ import { flatMap } from "lodash-es";
13
+ import uniqid from "shortid";
14
+ import { cloneDeep } from "lodash-es";
15
+ import classNames from "classnames";
16
+
17
+ import ToolbarItem from "./ToolbarItem";
18
+ import { connectToEditor } from "../withEditorProps";
19
+ import withEditorProps from "../withEditorProps";
20
+ import { showDialog } from "../GlobalDialogUtils";
21
+ import { compose } from "recompose";
22
+ import { array_move } from "./array_move";
23
+
24
+ export default connectToEditor(({ readOnly, toolBar = {} }) => {
25
+ return {
26
+ readOnly: readOnly,
27
+ isOpen: toolBar.openItem === "alignmentTool"
28
+ };
29
+ })(({ toolbarItemProps, isOpen }) => {
30
+ return (
31
+ <ToolbarItem
32
+ {...{
33
+ Icon: <Icon data-test="alignmentTool" icon="align-left" />,
34
+ // toggled: alignmentTool.isOpen,
35
+ renderIconAbove: isOpen,
36
+ // onIconClick: toggleFindTool,
37
+ Dropdown: ConnectedAlignmentToolDropdown,
38
+ onIconClick: "toggleDropdown",
39
+ noDropdownIcon: true,
40
+ tooltip: isOpen ? "Hide Alignment Tool" : "Align to This Sequence",
41
+ ...toolbarItemProps
42
+ }}
43
+ />
44
+ );
45
+ });
46
+
47
+ class AlignmentToolDropdown extends React.Component {
48
+ render() {
49
+ const {
50
+ savedAlignments = [],
51
+ hasSavedAlignments,
52
+ toggleDropdown,
53
+ sequenceData
54
+ } = this.props;
55
+ return (
56
+ <div>
57
+ <Button
58
+ intent={Intent.PRIMARY}
59
+ onClick={() => {
60
+ toggleDropdown();
61
+ showDialog({
62
+ dialogType: "AlignmentToolDialog",
63
+ props: {
64
+ createNewAlignment: this.props.createNewAlignment,
65
+ upsertAlignmentRun: this.props.upsertAlignmentRun,
66
+ initialValues: {
67
+ addedSequences: [{ ...sequenceData, isTemplate: true }]
68
+ }
69
+ }
70
+ });
71
+ }}
72
+ >
73
+ Create New Alignment
74
+ </Button>
75
+ <br></br>
76
+ <br></br>
77
+ <Callout intent="warning">
78
+ Note: This tool requires an alignment server to be hooked up for it to
79
+ work properly. It will NOT work in the OVE demo page.
80
+ </Callout>
81
+ <div className="vespacer" />
82
+ {hasSavedAlignments && (
83
+ <div>
84
+ <h6>Saved Alignments:</h6>
85
+ {!savedAlignments.length && (
86
+ <div style={{ fontStyle: "italic" }}> No Alignments</div>
87
+ )}
88
+ {savedAlignments.map((savedAlignment, i) => {
89
+ return <div key={i}>Saved Alignment {i}</div>;
90
+ })}
91
+ </div>
92
+ )}
93
+ </div>
94
+ );
95
+ }
96
+ }
97
+ const ConnectedAlignmentToolDropdown = withEditorProps(AlignmentToolDropdown);
98
+
99
+ class AlignmentTool extends React.Component {
100
+ state = {
101
+ templateSeqIndex: 0
102
+ };
103
+ sendSelectedDataToBackendForAlignment = async values => {
104
+ const {
105
+ addedSequences,
106
+ isPairwiseAlignment,
107
+ isAlignToRefSeq,
108
+ isAutotrimmedSeq
109
+ } = values;
110
+ const {
111
+ hideModal,
112
+ /* onAlignmentSuccess, */ createNewAlignment,
113
+ // createNewMismatchesList,
114
+ upsertAlignmentRun
115
+ } = this.props;
116
+ const { templateSeqIndex } = this.state;
117
+ const addedSequencesToUse = array_move(addedSequences, templateSeqIndex, 0);
118
+
119
+ let addedSequencesToUseTrimmed;
120
+ if (isAutotrimmedSeq) {
121
+ addedSequencesToUseTrimmed = cloneDeep(addedSequencesToUse);
122
+ // trimming any sequences with chromatogram data
123
+ for (let i = 0; i < addedSequencesToUseTrimmed.length; i++) {
124
+ if ("chromatogramData" in addedSequencesToUseTrimmed[i]) {
125
+ // if (addedSequencesToUseTrimmed[i].chromatogramData.qualNums) {
126
+ if ("qualNums" in addedSequencesToUseTrimmed[i].chromatogramData) {
127
+ // returning bp pos for { suggestedTrimStart, suggestedTrimEnd }
128
+ const { suggestedTrimStart, suggestedTrimEnd } = mottTrim(
129
+ addedSequencesToUseTrimmed[i].chromatogramData.qualNums
130
+ );
131
+ addedSequencesToUseTrimmed[i].sequence = addedSequencesToUseTrimmed[
132
+ i
133
+ ].sequence.slice(suggestedTrimStart, suggestedTrimEnd + 1);
134
+ const elementsToTrim = ["baseCalls", "basePos", "qualNums"];
135
+ // eslint-disable-next-line no-unused-vars
136
+ for (const element in addedSequencesToUseTrimmed[i]
137
+ .chromatogramData) {
138
+ if (elementsToTrim.indexOf(element) !== -1) {
139
+ addedSequencesToUseTrimmed[i].chromatogramData[element] =
140
+ addedSequencesToUseTrimmed[i].chromatogramData[element].slice(
141
+ suggestedTrimStart,
142
+ suggestedTrimEnd + 1
143
+ );
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ let seqsToAlign;
151
+ if (addedSequencesToUseTrimmed) {
152
+ seqsToAlign = addedSequencesToUseTrimmed;
153
+ } else {
154
+ seqsToAlign = addedSequencesToUse;
155
+ }
156
+
157
+ hideModal();
158
+ const alignmentId = uniqid();
159
+ // const alignmentIdMismatches = uniqid();
160
+ createNewAlignment({
161
+ id: alignmentId,
162
+ name: seqsToAlign[0].name + " Alignment"
163
+ });
164
+ //set the alignment to loading
165
+ upsertAlignmentRun({
166
+ id: alignmentId,
167
+ loading: true
168
+ });
169
+ // createNewMismatchesList({
170
+ // id: alignmentIdMismatches,
171
+ // name: addedSequencesToUse[0].name + " Mismatches",
172
+ // alignmentId: alignmentId
173
+ // });
174
+
175
+ // const j5server = process.env.REMOTE_J5 || "http://j5server.teselagen.com"
176
+
177
+ window.toastr.success("Alignment submitted.");
178
+ const replaceProtocol = url => {
179
+ return url.replace("http://", window.location.protocol + "//");
180
+ };
181
+
182
+ const seqInfoToSend = seqsToAlign.map(({ sequence, name, id }) => {
183
+ return {
184
+ sequence,
185
+ name,
186
+ id
187
+ };
188
+ });
189
+
190
+ const {
191
+ alignedSequences: _alignedSequences,
192
+ pairwiseAlignments,
193
+ alignmentsToRefSeq
194
+ } = await (
195
+ await fetch({
196
+ url: replaceProtocol("http://j5server.teselagen.com/alignment/run"),
197
+ method: "post",
198
+ body: JSON.stringify({
199
+ //only send over the bear necessities :)
200
+ sequencesToAlign: seqInfoToSend,
201
+ isPairwiseAlignment,
202
+ isAlignToRefSeq
203
+ })
204
+ })
205
+ ).json();
206
+
207
+ // alignmentsToRefSeq set to alignedSequences for now
208
+ let alignedSequences = _alignedSequences;
209
+ if (alignmentsToRefSeq) {
210
+ alignedSequences = alignmentsToRefSeq;
211
+ }
212
+ if (!alignedSequences && !pairwiseAlignments)
213
+ window.toastr.error("Error running sequence alignment!");
214
+ //set the alignment to loading
215
+ upsertAlignmentRun({
216
+ id: alignmentId,
217
+ pairwiseAlignments:
218
+ pairwiseAlignments &&
219
+ pairwiseAlignments.map((alignedSequences, topIndex) => {
220
+ return alignedSequences.map((alignmentData, innerIndex) => {
221
+ return {
222
+ sequenceData: seqsToAlign[innerIndex > 0 ? topIndex + 1 : 0],
223
+ alignmentData,
224
+ chromatogramData: seqsToAlign[innerIndex].chromatogramData
225
+ };
226
+ });
227
+ }),
228
+ alignmentTracks:
229
+ alignedSequences &&
230
+ alignedSequences.map(alignmentData => {
231
+ return {
232
+ sequenceData:
233
+ seqsToAlign[
234
+ alignmentData.name.slice(0, alignmentData.name.indexOf("_"))
235
+ ],
236
+ alignmentData,
237
+ chromatogramData:
238
+ seqsToAlign[
239
+ alignmentData.name.slice(0, alignmentData.name.indexOf("_"))
240
+ ].chromatogramData
241
+ };
242
+ })
243
+ // alignmentTracks:
244
+ // alignedSequences &&
245
+ // alignedSequences.map((alignmentData, i) => {
246
+ // return {
247
+ // sequenceData: addedSequencesToUse[i],
248
+ // alignmentData,
249
+ // chromatogramData: addedSequencesToUse[i].chromatogramData
250
+ // };
251
+ // })
252
+ });
253
+ };
254
+
255
+ handleFileUpload = (files, onChange) => {
256
+ const { array } = this.props;
257
+ flatMap(files, async file => {
258
+ const results = await anyToJson(file.originalFileObj, {
259
+ fileName: file.name,
260
+ acceptParts: true
261
+ });
262
+ return results.forEach(result => {
263
+ if (result.success) {
264
+ array.push("addedSequences", result.parsedSequence);
265
+ } else {
266
+ return window.toastr.warning("Error parsing file: ", file.name);
267
+ }
268
+ });
269
+ });
270
+ onChange([]);
271
+ };
272
+ renderAddSequence = ({ fields, templateSeqIndex }) => {
273
+ const { handleSubmit } = this.props;
274
+
275
+ const sequencesToAlign = fields.getAll() || [];
276
+ return (
277
+ <div>
278
+ <h6>Or enter sequences in plain text format</h6>
279
+ <div>
280
+ <AddYourOwnSeqForm
281
+ addSeq={newSeq => {
282
+ fields.push(newSeq);
283
+ }}
284
+ />
285
+ <h6 style={{ marginTop: 15 }}>Sequences To Align: </h6>
286
+ {!fields.getAll() && <div>No sequences added yet.</div>}
287
+ <div
288
+ style={{ maxHeight: 180, overflowY: "auto" }}
289
+ className="veAlignmentToolSelectedSequenceList"
290
+ >
291
+ {sequencesToAlign.map((addedSeq, index) => {
292
+ return (
293
+ <div
294
+ onClick={() => {
295
+ this.setState({
296
+ templateSeqIndex: index
297
+ });
298
+ }}
299
+ style={{
300
+ borderBottom: "1px solid lightgrey",
301
+ paddingBottom: 4,
302
+ marginBottom: 4,
303
+ width: "100%",
304
+ justifyContent: "space-between",
305
+ alignItems: "center",
306
+ display: "flex"
307
+ }}
308
+ key={index}
309
+ >
310
+ <div>
311
+ {addedSeq.name}{" "}
312
+ <span style={{ fontSize: 10 }}>
313
+ {" "}
314
+ ({addedSeq.sequence.length} bps)
315
+ </span>
316
+ </div>
317
+ {index === templateSeqIndex && (
318
+ <div
319
+ className={classNames(
320
+ Classes.TAG,
321
+ Classes.ROUND,
322
+ Classes.INTENT_PRIMARY
323
+ )}
324
+ >
325
+ template
326
+ </div>
327
+ )}
328
+
329
+ <Button
330
+ onClick={e => {
331
+ e.stopPropagation();
332
+ e.preventDefault();
333
+ fields.remove(index);
334
+ if (index === templateSeqIndex) {
335
+ this.setState({ templateSeqIndex: 0 });
336
+ }
337
+ }}
338
+ >
339
+ Remove
340
+ </Button>
341
+ </div>
342
+ );
343
+ })}
344
+ </div>
345
+ <br />
346
+ <CheckboxField
347
+ name="isPairwiseAlignment"
348
+ style={{ display: "flex", alignItems: "center" }}
349
+ label={
350
+ <div>
351
+ Create Pairwise Alignment{" "}
352
+ <span style={{ fontSize: 11 }}>
353
+ Individually align each uploaded file against the template
354
+ sequence (instead of creating a single Multiple Sequence
355
+ Alignment)
356
+ </span>
357
+ </div>
358
+ }
359
+ />
360
+ <CheckboxField
361
+ name="isAlignToRefSeq"
362
+ style={{ display: "flex", alignItems: "center" }}
363
+ label={
364
+ <div>
365
+ Align Sequencing Reads to Reference Sequence{" "}
366
+ <span style={{ fontSize: 11 }}>
367
+ Align short sequencing reads to a long reference sequence
368
+ </span>
369
+ </div>
370
+ }
371
+ />
372
+ <CheckboxField
373
+ name="isAutotrimmedSeq"
374
+ style={{ display: "flex", alignItems: "center" }}
375
+ label={
376
+ <div>
377
+ Auto-Trim Sequences{" "}
378
+ <span style={{ fontSize: 11 }}>
379
+ Automatically trim low-quality ends of sequences based on
380
+ quality scores
381
+ </span>
382
+ </div>
383
+ }
384
+ />
385
+
386
+ <Button
387
+ style={{ marginTop: 15, float: "right" }}
388
+ intent={Intent.PRIMARY}
389
+ disabled={sequencesToAlign.length < 2}
390
+ onClick={handleSubmit(this.sendSelectedDataToBackendForAlignment)}
391
+ >
392
+ Create alignment
393
+ </Button>
394
+ </div>
395
+ </div>
396
+ );
397
+ };
398
+
399
+ render() {
400
+ const { selectFromSequenceLibraryHook } = this.props;
401
+ const { templateSeqIndex } = this.state;
402
+ return (
403
+ <div style={{ padding: 20 }} className="veAlignmentTool">
404
+ <h6>Upload files you'd like to align (.ab1, .fasta, .gb) </h6>
405
+ <FileUploadField
406
+ name="alignmentToolSequenceUpload"
407
+ style={{ maxWidth: 400 }}
408
+ beforeUpload={this.handleFileUpload}
409
+ />
410
+ {selectFromSequenceLibraryHook && (
411
+ <h6>Or Select from your sequence library </h6>
412
+ )}
413
+
414
+ <FieldArray
415
+ name="addedSequences"
416
+ templateSeqIndex={templateSeqIndex}
417
+ component={this.renderAddSequence}
418
+ />
419
+ </div>
420
+ );
421
+ }
422
+ }
423
+
424
+ export const AlignmentToolDialog = compose(
425
+ wrapDialog({ title: "Create New Alignment" }),
426
+ reduxForm({
427
+ form: "veAlignmentTool"
428
+ })
429
+ )(AlignmentTool);
430
+
431
+ const AddYourOwnSeqForm = reduxForm({
432
+ form: "AddYourOwnSeqForm",
433
+ validate: ({ name, sequence }) => {
434
+ const errors = {};
435
+ if (!name) {
436
+ errors.name = "Required";
437
+ }
438
+ if (!sequence) {
439
+ errors.sequence = "Required";
440
+ }
441
+ return errors;
442
+ }
443
+ })(({ pristine, error, handleSubmit, reset, addSeq }) => {
444
+ return (
445
+ <form
446
+ onSubmit={handleSubmit(vals => {
447
+ reset();
448
+ addSeq(vals);
449
+ })}
450
+ >
451
+ <EditableTextField
452
+ style={{ maxWidth: 200 }}
453
+ placeholder="Untitled Sequence"
454
+ name="name"
455
+ />
456
+ <TextareaField
457
+ style={{ maxWidth: 400 }}
458
+ placeholder="AGTTGAGC"
459
+ name="sequence"
460
+ />
461
+ <Button disabled={pristine || error} type="submit">
462
+ Add
463
+ </Button>
464
+ </form>
465
+ );
466
+ });
467
+
468
+ function mottTrim(qualNums) {
469
+ if (!qualNums) return;
470
+ let startPos = 0;
471
+ let endPos = 0;
472
+ const totalScoreInfo = [];
473
+ let score = 0;
474
+ let totalScore = 0;
475
+ const cutoff = 0.05;
476
+ for (let i = 0; i < qualNums.length; i++) {
477
+ // low-quality bases have high error probabilities, so may have a negative base score
478
+ score = cutoff - Math.pow(10, qualNums[i] / -10);
479
+ totalScore += score;
480
+ totalScoreInfo.push(totalScore);
481
+ // score = score + cutoff - Math.pow(10, qualNums[i] / -10);
482
+ // if (totalScore < 0) {
483
+ // tempStart = i;
484
+ // }
485
+ // if (i - tempStart > endPos - startPos) {
486
+ // startPos = tempStart;
487
+ // endPos = i;
488
+ // }
489
+ if (totalScore < 0) {
490
+ totalScore = 0;
491
+ }
492
+ }
493
+ const firstPositiveValue = totalScoreInfo.find(e => {
494
+ return e > 0;
495
+ });
496
+ startPos = totalScoreInfo.indexOf(firstPositiveValue);
497
+ const highestValue = Math.max(...totalScoreInfo);
498
+ endPos = totalScoreInfo.lastIndexOf(highestValue);
499
+ return {
500
+ suggestedTrimStart: startPos,
501
+ suggestedTrimEnd: endPos
502
+ };
503
+ }