Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/local/bin/python 

2# encoding: utf-8 

3""" 

4*The context tab for the PESSTO Object tickets* 

5 

6:Author: 

7 David Young 

8""" 

9import sys 

10import os 

11import datetime 

12import re 

13import khufu 

14from marshall_webapp.templates.commonelements.tickets.single_ticket import ticket_building_blocks 

15from marshall_webapp.templates.commonelements import commonutils as cu 

16 

17 

18def context_tab( 

19 log, 

20 request, 

21 discoveryDataDictionary, 

22 objectAkas, 

23 atelData, 

24 lightcurveData, 

25 transientCrossmatches): 

26 """context tab 

27 

28 **Key Arguments** 

29 

30 - ``log`` -- logger 

31 - ``request`` -- the pyramid request 

32 - ``discoveryDataDictionary`` -- the unique discoveryData dictionary of the object in the pessto marshall database (from view_object_contextual_data) 

33 - ``objectAkas`` -- object akas 

34 - ``lightcurveData`` -- the lightcurve data for the objects displayed on the webpage 

35 - ``atelData`` -- the atel matches for the objects displayed on the webpage 

36 - ``transientCrossmatches`` -- catalogue crossmatches (from sherlock) 

37 

38 

39 **Return** 

40 

41 - ``context_tab`` -- the lightcurve/context tab for a single ticket on the transient listings page 

42 

43 """ 

44 from marshall_webapp.templates.commonelements.tickets import single_ticket 

45 

46 log.debug('starting the ``context_tab`` function') 

47 

48 crossmatches = _crossmatch_info_block( 

49 log=log, 

50 request=request, 

51 discoveryDataDictionary=discoveryDataDictionary, 

52 transientCrossmatches=transientCrossmatches 

53 ) 

54 

55 crossmatches = khufu.grid_row( 

56 responsive=True, 

57 columns=crossmatches, 

58 htmlId=False, 

59 htmlClass=False 

60 ) 

61 

62 aladin = _aladin_block( 

63 log=log, 

64 request=request, 

65 discoveryDataDictionary=discoveryDataDictionary, 

66 transientCrossmatches=transientCrossmatches 

67 ) 

68 

69 aladin = khufu.grid_row( 

70 responsive=True, 

71 columns=aladin, 

72 htmlId=False, 

73 htmlClass=False 

74 ) 

75 

76 sherlockForm = _sherlock_development_form( 

77 log=log, 

78 request=request, 

79 discoveryDataDictionary=discoveryDataDictionary, 

80 transientCrossmatches=transientCrossmatches 

81 ) 

82 

83 context_block = """%(aladin)s %(crossmatches)s %(sherlockForm)s """ % locals( 

84 ) 

85 # context_block = """%(host_stamp)s%(crossmatches)s""" % locals( 

86 # ) 

87 

88 footer = context_footer_bar( 

89 log, 

90 request=request 

91 ) 

92 

93 context_tab = single_ticket._ticket_tab_template( 

94 log, 

95 request=request, 

96 tabHeader=False, 

97 blockList=[context_block], 

98 tabFooter=footer, 

99 htmlId="contexttab" 

100 ) 

101 

102 log.debug('completed the ``context_tab`` function') 

103 return "%(context_tab)s" % locals() 

104 

105 

106def context_footer_bar( 

107 log, 

108 request): 

109 """get ticket footer bar 

110 

111 **Key Arguments** 

112 

113 - ``log`` -- logger 

114 - ``discoveryData`` -- the discoveryData for the object 

115 - ``lightcurveData`` -- the lightcurve data for the object 

116 

117 

118 **Return** 

119 

120 - ``context_footer_bar`` -- the ticket footer bar for the pesssto object 

121 

122 """ 

123 lsqExists = False 

124 log.debug('starting the ``context_footer_bar`` function') 

125 ## VARIABLES ## 

126 

127 footerColumn = khufu.grid_column( 

128 span=2, # 1-12 

129 offset=0, # 1-12 

130 content="<BR>" % locals( 

131 ) 

132 ) 

133 

134 context_footer_bar = khufu.grid_row( 

135 responsive=True, 

136 columns=footerColumn, 

137 htmlId=False, 

138 htmlClass="ticketFooter" 

139 ) 

140 

141 return context_footer_bar 

142 

143 

144def _host_info_block( 

145 log, 

146 request, 

147 discoveryDataDictionary): 

148 """get ticket host info block 

149 

150 **Key Arguments** 

151 

152 - ``log`` -- logger 

153 - ``request`` -- the pyramid request 

154 - ``discoveryDataDictionary`` -- a dictionary of the discovery data for this transient. 

155 

156 

157 **Return** 

158 

159 - ``host_info_block`` -- the ticket identity block for the pesssto object 

160 

161 """ 

162 log.debug('starting the ``host_info_block`` function') 

163 

164 title = cu.block_title( 

165 log, 

166 title="host stamp" 

167 ) 

168 

169 masterName = discoveryDataDictionary["masterName"] 

170 sherlockClassification = discoveryDataDictionary["sherlockClassification"] 

171 

172 nearestObjectUrl = "" 

173 exactLocationUrl = "" 

174 ogleStamp = "" 

175 ra = discoveryDataDictionary["raDeg"] 

176 dec = discoveryDataDictionary["decDeg"] 

177 transientBucketId = discoveryDataDictionary["transientBucketId"] 

178 if discoveryDataDictionary["sdss_coverage"] == 1: 

179 nearestObjectUrl = "http://skyserver.sdss3.org/public/en/tools/explore/obj.aspx?ra=%(ra)s&dec=%(dec)s" % locals( 

180 ) 

181 exactLocationUrl = """http://skyserver.sdss3.org/public/en/tools/chart/image.aspx?ra=%(ra)s&dec=%(dec)s&scale=0.25&opt=GS&width=512&height=512""" % locals( 

182 ) 

183 downloadContextStamp = "caches/transients/%s/sdss_stamp.jpeg" % ( 

184 discoveryDataDictionary["transientBucketId"],) 

185 contextStamp = request.static_url(f'marshall_webapp:{downloadContextStamp}') 

186 stampName = "%(masterName)s_sdss_context_image" % locals() 

187 elif discoveryDataDictionary["ogle_color_context_stamp"] == 1: 

188 downloadContextStamp = "caches/transients/%(transientBucketId)s/ogle_color_context_stamp.png" % locals( 

189 ) 

190 contextStamp = request.static_url(f'marshall_webapp:{downloadContextStamp}') 

191 ogleStamp = "OGLE context stamp" 

192 stampName = "%(masterName)s_ogle_context_image" % locals() 

193 elif discoveryDataDictionary["sdss_coverage"] == 0: 

194 contextStamp = 'holder.js/500x500/auto/industrial/text:not in sdss footprint' 

195 downloadContextStamp = contextStamp 

196 stampName = False 

197 else: 

198 contextStamp = 'holder.js/500x500/auto/industrial/text:sdss stamp not ready yet' 

199 downloadContextStamp = contextStamp 

200 stampName = False 

201 sdssUrl = """http://skyserver.sdss3.org/public/en/tools/chart/image.aspx?ra=%(ra)s&dec=%(dec)s&scale=0.25&opt=GSP&width=512&height=512&query=G""" % locals( 

202 ) 

203 

204 sdssLinkRow = "" 

205 if len(nearestObjectUrl): 

206 nearestObjectUrl = khufu.a( 

207 content='sdss nearest object', 

208 href=nearestObjectUrl, 

209 openInNewTab=True 

210 ) 

211 nearestObjectUrl = khufu.coloredText( 

212 text=nearestObjectUrl, 

213 color="cyan", 

214 size=False, # 1-10 

215 pull=False, # "left" | "right" 

216 ) 

217 exactLocationUrl = khufu.a( 

218 content='exact sdss location', 

219 href=exactLocationUrl, 

220 openInNewTab=True 

221 ) 

222 exactLocationUrl = khufu.coloredText( 

223 text=exactLocationUrl, 

224 color="blue", 

225 size=False, # 1-10 

226 pull=False, # "left" | "right" 

227 ) 

228 sdssLinkRow = khufu.grid_row( 

229 responsive=True, 

230 columns="&nbsp&nbsp&nbsp&nbsp%(ogleStamp)s%(exactLocationUrl)s<br>&nbsp&nbsp&nbsp&nbsp%(nearestObjectUrl)s" % locals( 

231 ), 

232 htmlId=False, 

233 htmlClass=False, 

234 onPhone=True, 

235 onTablet=True, 

236 onDesktop=True 

237 ) 

238 

239 if len(ogleStamp): 

240 ogleStamp = khufu.coloredText( 

241 text="&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp%(ogleStamp)s" % locals(), 

242 color="blue" 

243 ) 

244 

245 sdssLink = khufu.a( 

246 content='sdss dr12 location', 

247 href=sdssUrl, 

248 ) 

249 

250 if stampName: 

251 href = request.route_path( 

252 'download', _query={'url': downloadContextStamp, "webapp": "marshall_webapp", "filename": stampName}) 

253 else: 

254 href = False 

255 

256 imageModal = khufu.imagingModal( 

257 log=log, 

258 imagePath=contextStamp, 

259 display="rounded", # [ rounded | circle | polaroid | False ] 

260 modalHeaderContent="Context Stamp for %(masterName)s" % locals(), 

261 modalFooterContent=sdssLink, 

262 stampWidth=400, 

263 modalImageWidth=400, 

264 downloadLink=href) 

265 imageModal = imageModal.get() 

266 

267 return "%(title)s %(imageModal)s %(sdssLinkRow)s" % locals() 

268 

269 

270def _crossmatch_info_block( 

271 log, 

272 request, 

273 discoveryDataDictionary, 

274 transientCrossmatches): 

275 """get ticket host info block 

276 

277 **Key Arguments** 

278 

279 - ``log`` -- logger 

280 - ``request`` -- the pyramid request 

281 - ``discoveryDataDictionary`` -- a dictionary of the discovery data for this transient. 

282 

283 

284 **Return** 

285 

286 - ``_crossmatch_info_block`` -- the crossmatch info from sherlock for the pesssto object 

287 

288 """ 

289 log.debug('starting the ``_crossmatch_info_block`` function') 

290 

291 title = cu.block_title( 

292 log, 

293 title="crossmatched sources" 

294 ) 

295 

296 # FIND THIS TRANSIENT'S CROSSMATCHES 

297 transientBucketId = discoveryDataDictionary["transientBucketId"] 

298 cms = [] 

299 for row in transientCrossmatches: 

300 if row["transientBucketId"] == transientBucketId: 

301 cms.append(row) 

302 

303 masterName = discoveryDataDictionary["masterName"] 

304 sherlockClassification = discoveryDataDictionary["sherlockClassification"] 

305 

306 sourceIcons = { 

307 "galaxy": "spinner5", 

308 "agn": "target3", 

309 "qso": "target3", 

310 "star": "star3", 

311 "cv": "sun6", 

312 "cb": "sun6", 

313 "other": "help2", 

314 "unclear": "help2" 

315 } 

316 transColors = { 

317 "sn": "blue", 

318 "nt": "magenta", 

319 "cv": "green", 

320 "agn": "yellow", 

321 "variablestar": "orange", 

322 "vs": "orange", 

323 "bs": "brown", 

324 "?": "violet", 

325 "unclear": "violet", 

326 "kepler": "#dc322f" 

327 } 

328 

329 table = "" 

330 if len(cms) > 0: 

331 

332 hs = ["Rank", "Catalogue", "Catalogue ID", "Catalogue Type (& Subtype)", "Classification", 

333 "Angular Separation from Transient", "Physical Separation from Transient", "Transient Peak M", "Source Distance", "Source Redshift", "Source Mag"] 

334 tableHead = "" 

335 for h in hs: 

336 th = khufu.th( 

337 content=h, 

338 color=False 

339 ) 

340 tableHead = """%(tableHead)s%(th)s""" % locals() 

341 # xkhufu-th 

342 tableHead = khufu.thead( 

343 trContent=tableHead 

344 ) 

345 

346 tableBody = [] 

347 

348 rs = ["rank", "catalogue_table_name", "catalogue_object_id", "catalogue_object_type", "sherlockClassification", 

349 "separationArcsec", "physical_separation_kpc", "transientAbsMag", "distance", "z", "best_mag"] 

350 for c in cms: 

351 

352 # generate object links 

353 if c["object_link"]: 

354 c["catalogue_object_id"] = khufu.a( 

355 content=c["catalogue_object_id"], 

356 href=c["object_link"], 

357 openInNewTab=True 

358 ) 

359 

360 if c["catalogue_table_name"]: 

361 

362 popover = khufu.popover( 

363 tooltip=True, 

364 placement="top", # [ top | bottom | left | right ] 

365 # [ False | click | hover | focus | manual ] 

366 trigger="hover", 

367 title=c["search_name"], 

368 content=False, 

369 delay=200 

370 ) 

371 

372 # add text color 

373 c["catalogue_table_name"] = khufu.a( 

374 content=c["catalogue_table_name"], 

375 href="#", 

376 popover=popover 

377 ) 

378 

379 # SOURCE MAGNITUDE 

380 if c["best_mag"]: 

381 m = c["best_mag"] 

382 e = c["best_mag_error"] 

383 f = c["best_mag_filter"] 

384 if e: 

385 e = " &plusmn; %(e)0.2f" % locals() 

386 else: 

387 e = "" 

388 if isinstance(m, float): 

389 c["best_mag"] = "%(f)s = %(m)0.2f%(e)s" % locals() 

390 else: 

391 c["best_mag"] = m 

392 

393 # CLASSIFICATION 

394 if c["classificationReliability"] == 1: 

395 cText = "transient is <em>synonymous</em> with this source" 

396 cLevel = "success" 

397 elif c["classificationReliability"] == 2: 

398 cText = "transient may be <em>associated</em> with this source" 

399 cLevel = "warning" 

400 else: 

401 cText = "<em>annotation</em> - not to be relied on for predicting transient classification" 

402 cLevel = "important" 

403 

404 b = khufu.badge( 

405 text=c["classificationReliability"], 

406 level=cLevel 

407 ) 

408 popover = khufu.popover( 

409 tooltip=False, 

410 placement="right", 

411 trigger="hover", 

412 title="<b>Classification Reliability</b>", 

413 content=cText, 

414 delay=200 

415 ) 

416 b = khufu.a( 

417 content=b, 

418 href=False, 

419 popover=popover 

420 ) 

421 

422 # DISTANCE CURATION 

423 if c["z"]: 

424 c["distance_method"] = "spec-z distance" 

425 col = "success" 

426 zbadge = "s" 

427 elif c["photoZ"]: 

428 c["distance_method"] = "photo-z distance" 

429 col = "important" 

430 zbadge = "p" 

431 if c["direct_distance"]: 

432 col = "warning" 

433 c["distance"] = c["direct_distance"] 

434 c["distance_method"] = "redshift-independent distance" 

435 zbadge = "r" 

436 

437 # REDSHIFT CURATION 

438 if not c["z"]: 

439 if c["photoZ"]: 

440 pz = c["photoZ"] 

441 if c["photoZErr"]: 

442 pze = c["photoZErr"] 

443 pz = "%(pz)0.3f &plusmn; %(pze)0.3f" % locals() 

444 b = khufu.badge( 

445 text='p', 

446 level='important' 

447 ) 

448 popover = khufu.popover( 

449 tooltip=True, 

450 placement="right", 

451 trigger="hover", 

452 title="photo-z", 

453 content=False, 

454 delay=200 

455 ) 

456 b = khufu.a( 

457 content=b, 

458 href=False, 

459 popover=popover 

460 ) 

461 c["z"] = pz + b 

462 

463 else: 

464 b = khufu.badge( 

465 text='s', 

466 level='success' 

467 ) 

468 popover = khufu.popover( 

469 tooltip=True, 

470 placement="right", 

471 trigger="hover", 

472 title="spec-z", 

473 content=False, 

474 delay=200 

475 ) 

476 b = khufu.a( 

477 content=b, 

478 href=False, 

479 popover=popover 

480 ) 

481 cz = c["z"] 

482 if isinstance(cz, float): 

483 c["z"] = "%(cz)0.3f %(b)s" % locals() 

484 

485 tableRow = [] 

486 

487 for r in rs: 

488 if c[r] == None: 

489 c[r] = "-" 

490 if r == "catalogue_object_type": 

491 try: 

492 icon = sourceIcons[c[r]] 

493 except: 

494 icon = "help2" 

495 if c["catalogue_object_type"].lower() == "other": 

496 c["catalogue_object_type"] = c[ 

497 "catalogue_object_subtype"] 

498 thisType = c[r] 

499 

500 if c["catalogue_object_subtype"]: 

501 thisType += " (" + c["catalogue_object_subtype"] + ")" 

502 

503 # add text color 

504 c[r] = """<i class="icon-%(icon)s" color="#268bd2"></i> %(thisType)s""" % locals() 

505 

506 if isinstance(c[r], float): 

507 this = c[r] 

508 c[r] = """%(this)0.2f""" % locals() 

509 

510 # ADD UNITS 

511 if c[r] != "-": 

512 if r in ["original_search_radius_arcsec", "major_axis_arcsec"] and c[r] != "-": 

513 c[r] = c[r] + '"' 

514 if r in ["distance"]: 

515 

516 b = khufu.badge( 

517 text=zbadge, 

518 level=col 

519 ) 

520 popover = khufu.popover( 

521 tooltip=True, 

522 # [ top | bottom | left | right ] 

523 placement="right", 

524 # [ False | click | hover | focus | manual ] 

525 trigger="hover", 

526 title=c["distance_method"], 

527 content=False, 

528 delay=200 

529 ) 

530 b = khufu.a( 

531 content=b, 

532 href=False, 

533 popover=popover 

534 ) 

535 

536 c[r] = c[r] + ' Mpc ' + b 

537 

538 if r in ["physical_separation_kpc"]: 

539 c[r] = c[r] + ' Kpc' 

540 if r in ["separationArcsec"]: 

541 n = c["northSeparationArcsec"] 

542 e = c["eastSeparationArcsec"] 

543 c[r] = c[r] + '" (%(n)0.2fN, %(e)0.2fE)' % locals() 

544 

545 content = khufu.coloredText( 

546 text=c[r], 

547 color=transColors[c["association_type"].lower()], 

548 size=False, # 1-10 

549 pull=False, # "left" | "right", 

550 addBackgroundColor=False 

551 ) 

552 td = khufu.td( 

553 content=content, 

554 color=False 

555 ) 

556 tableRow.append(td) 

557 # xkhufu-table-cell 

558 tr = khufu.tr( 

559 cellContent=tableRow, 

560 color=transColors[c["association_type"].lower()] 

561 ) 

562 tableBody.append(tr) 

563 

564 tableBody = khufu.tbody( 

565 trContent=tableBody 

566 ) 

567 table = khufu.table( 

568 caption=False, 

569 thead=tableHead, 

570 tbody=tableBody, 

571 striped=False, 

572 bordered=False, 

573 hover=True, 

574 condensed=True 

575 ) 

576 

577 return "%(table)s" % locals() 

578 

579 

580def _aladin_block( 

581 log, 

582 request, 

583 discoveryDataDictionary, 

584 transientCrossmatches): 

585 """get aladin lite instance for transient 

586 

587 **Key Arguments** 

588 

589 - ``log`` -- logger 

590 - ``request`` -- the pyramid request 

591 - ``discoveryDataDictionary`` -- a dictionary of the discovery data for this transient. 

592 

593 

594 **Return** 

595 

596 - ``_aladin_block`` -- the crossmatch info from sherlock for the pesssto object 

597 

598 """ 

599 log.debug('starting the ``_aladin_block`` function') 

600 

601 title = cu.block_title( 

602 log, 

603 title="crossmatch map" 

604 ) 

605 

606 # ADD TEXT COLOR 

607 masterName = discoveryDataDictionary["masterName"] 

608 text = khufu.coloredText( 

609 text="Contextual classification for <em>%(masterName)s</em>" % locals( 

610 ), 

611 color="grey", 

612 size=3, # 1-10 

613 pull="right", # "left" | "right", 

614 addBackgroundColor=False 

615 ) 

616 

617 masterClassification = discoveryDataDictionary["classification"] 

618 

619 # ADD TEXT COLOR 

620 masterClassification = khufu.coloredText( 

621 text=masterClassification, 

622 color="violet", 

623 size=6, # 1-10 

624 pull="right", # "left" | "right", 

625 addBackgroundColor=False 

626 ) 

627 masterClassification = masterClassification + "</br>" + text + "</br>" 

628 

629 text = khufu.p( 

630 content='', 

631 lead=False, 

632 textAlign=False, # [ left | center | right ] 

633 color=False, # [ muted | warning | info | error | success ] 

634 navBar=False, 

635 onPhone=True, 

636 onTablet=True, 

637 onDesktop=True 

638 ) 

639 

640 coords = "%s %s" % ( 

641 discoveryDataDictionary["raDeg"], discoveryDataDictionary["decDeg"],) 

642 

643 name = discoveryDataDictionary["masterName"] 

644 

645 # FIND THIS TRANSIENT'S CROSSMATCHES 

646 transientBucketId = discoveryDataDictionary["transientBucketId"] 

647 cms = [] 

648 for row in transientCrossmatches: 

649 if row["transient_object_id"] == transientBucketId: 

650 cms.append(row) 

651 

652 masterName = discoveryDataDictionary["masterName"] 

653 sherlockClassification = discoveryDataDictionary["sherlockClassification"] 

654 if discoveryDataDictionary["ps1_map"] == 1: 

655 survey = "P/PanSTARRS/DR1/color/z/zg/g" 

656 elif discoveryDataDictionary["sdss_coverage"] == 1: 

657 survey = "P/SDSS9/color" 

658 else: 

659 survey = "P/DSS2/color" 

660 

661 aladin = '<div class="aladin-hide" coords="%(coords)s" survey="%(survey)s" data="/marshall/transients/%(transientBucketId)s/context" transient="%(name)s" style="font-family:dryx_icon_font"></div>' % locals( 

662 ) 

663 

664 return "%(masterClassification)s %(aladin)s" % locals() 

665 

666 

667def _sherlock_development_form( 

668 log, 

669 request, 

670 discoveryDataDictionary, 

671 transientCrossmatches): 

672 """*a form for adding comments and confirming/reporting incorrect matches from sherlock trasient classifier* 

673 

674 **Key Arguments** 

675 

676 - ``log`` -- logger 

677 - ``request`` -- the pyramid request 

678 - ``discoveryDataDictionary`` -- a dictionary of the discovery data for this transient.): 

679 

680 """ 

681 

682 transientBucketId = discoveryDataDictionary["transientBucketId"] 

683 

684 if discoveryDataDictionary["mismatchComment"]: 

685 # add text color 

686 commentDate = discoveryDataDictionary["commentDate"] 

687 if commentDate: 

688 commentDate = commentDate.strftime("%Y-%m-%d") 

689 else: 

690 commentDate = "no comment date" 

691 if not discoveryDataDictionary["user"]: 

692 discoveryDataDictionary["user"] = "anon" 

693 text = khufu.coloredText( 

694 text="Mismatch reported by " + discoveryDataDictionary["user"].replace(".", " ").title( 

695 ) + ", " + commentDate + ": ", 

696 color="red", 

697 size=4, # 1-10 

698 pull=False, # "left" | "right", 

699 addBackgroundColor=False 

700 ) 

701 

702 currentComment = khufu.coloredText( 

703 text=text + discoveryDataDictionary["mismatchComment"], 

704 color="grey", 

705 size=3, # 1-10 

706 pull=False, # "left" | "right", 

707 addBackgroundColor=False 

708 ) 

709 else: 

710 currentComment = "" 

711 

712 if len(currentComment) == 0: 

713 

714 button = khufu.button( 

715 buttonText='mismatch', 

716 # [ default | primary | info | success | warning | danger | inverse | link ] 

717 buttonStyle='success', 

718 buttonSize='default', # [ large | default | small | mini ] 

719 htmlId=False, 

720 href=False, 

721 pull=False, # right, left, center 

722 submit=True, 

723 block=False, 

724 disable=False, 

725 postInBackground=False, 

726 dataToggle=False, # [ modal ] 

727 popover=False 

728 ) 

729 

730 correctMatchInput = khufu.formInput( 

731 # [ text | password | datetime | datetime-local | date | month | time | week | number | float | email | url | search | tel | color ] 

732 ttype='text', 

733 placeholder='comment ...', 

734 span=10, 

735 htmlId="sherlockMatchComment", 

736 searchBar=False, 

737 pull=False, 

738 prepend=False, 

739 append=False, 

740 prependDropdown=False, 

741 appendDropdown=False, 

742 inlineHelpText=False, 

743 blockHelpText=False, 

744 focusedInputText=False, 

745 required=True, 

746 disabled=False 

747 ) 

748 correctMatchInput = khufu.controlRow( 

749 inputList=[correctMatchInput, button] 

750 ) 

751 correctMatchLabel = khufu.horizontalFormControlLabel( 

752 labelText='If you think the first ranked transient-host match is obviously incorrect please report the mismatch to help improve the contextual classifier', 

753 forId="sherlockMatchComment" 

754 ) 

755 

756 correctMatchCG = khufu.horizontalFormControlGroup( 

757 content=correctMatchLabel + correctMatchInput, 

758 validationLevel=False 

759 ) 

760 # xkhufu-tmpx-form-control-groue 

761 

762 sherlockForm = khufu.form( 

763 content=correctMatchCG, # list of control groups 

764 # [ "inline" | "horizontal" | "search" | "navbar-form" | "navbar-search" ] 

765 formType='inline', 

766 navBarPull=False, # [ false | right | left ], 

767 postToScript="/marshall/transients/%(transientBucketId)s/context" % locals(), 

768 htmlId="sherlockDevelopment", 

769 postInBackground=False, 

770 htmlClass=False, 

771 redirectUrl="/marshall/transients/%(transientBucketId)s" % locals(), 

772 span=10, 

773 offset=1 

774 ) 

775 

776 currentComment = khufu.grid_column( 

777 span=6, # 1-12 

778 offset=1, # 1-12 

779 content=currentComment, 

780 pull=False, # ["right", "left", "center"] 

781 htmlId=False, 

782 htmlClass=False, 

783 onPhone=True, 

784 onTablet=True, 

785 onDesktop=True 

786 ) 

787 else: 

788 sherlockForm = "" 

789 

790 currentComment = khufu.grid_column( 

791 span=6, # 1-12 

792 offset=0, # 1-12 

793 content=currentComment, 

794 pull=False, # ["right", "left", "center"] 

795 htmlId=False, 

796 htmlClass=False, 

797 onPhone=True, 

798 onTablet=True, 

799 onDesktop=True 

800 ) 

801 

802 return currentComment + sherlockForm 

803 

804 # xt-class-method