From 005263e84e778ef6b81fb7a763d8451b0acddc5b Mon Sep 17 00:00:00 2001 From: Kathryn Wynn Date: Fri, 9 Jan 2026 14:10:16 -0800 Subject: [PATCH 1/4] Adding galaxy annotations and ranking for visualization --- src/ajaxrequests.py | 29 ++- src/function.py | 15 +- src/templates/alert_info.html | 408 ++++++++++++++++++++++++++++++---- 3 files changed, 400 insertions(+), 52 deletions(-) diff --git a/src/ajaxrequests.py b/src/ajaxrequests.py index 6d4aa72f..725387f9 100644 --- a/src/ajaxrequests.py +++ b/src/ajaxrequests.py @@ -312,18 +312,29 @@ def ajax_event_galaxies(): for glist in galLists: markers = [] entries = [x for x in galEntries if x.listid == glist.id] + name_list = [] + ra_list = [] + dec_list = [] + rank_list = [] + info_list = [] + for e in entries: ra, dec = function.sanatize_pointing(e.position) - markers.append({ - "name":e.name, - "ra": ra, - "dec": dec, - "info":function.sanatize_gal_info(e, glist) - }) + name_list.append(e.name) + ra_list.append(ra) + dec_list.append(dec) + rank_list.append(int(e.rank)) + info_list.append(function.sanatize_gal_info(e, glist)) + + df = pd.DataFrame({'name': name_list, 'ra':ra_list, 'dec':dec_list, 'rank':rank_list, 'info':info_list}) + df.sort_values(by=['rank'], inplace=True, ignore_index=True) + df.drop(columns = 'rank') + + markers = df.to_dict('records') event_galaxies.append({ - "name":glist.groupname, - "color":"", - "markers":markers + "name": glist.groupname, + "color": "", + "markers": markers }) return(jsonify(event_galaxies)) diff --git a/src/function.py b/src/function.py index bc5674e4..a77c1630 100644 --- a/src/function.py +++ b/src/function.py @@ -151,16 +151,21 @@ def sanatize_XRT_source_info(info): def sanatize_gal_info(entry, glist): ra, dec = sanatize_pointing(entry.position) ret = "

" - ret = " RA DEC: "+str(round(ra,4))+" "+str(round(dec,4))+"
" - ret += "Score: "+str(entry.score)+"
" + ret += " RA: " +f"{ra:.4f}" + "
" + ret += " DEC: " + f"{dec:.4f}" + "
" + ret += "Score: "+ f"{entry.score:.4E}"+"
" ret += "Rank: "+str(entry.rank)+"
" if glist.reference: - ret+= f"Reference
" + ret += f"Reference
" if glist.doi_url: - ret+= f"DOI
" + ret += f"DOI
" + ret += f"NED
" ret+="

Other Information:

" for key in entry.info.keys(): - ret += ""+str(key)+": "+str(entry.info[key]).split('\n')[0]+"
" + if 'Dist' in str(key): + ret += ""+str(key)+": "+ "{:.2f}".format(float(str(entry.info[key]).split('\n')[0])) +"
" + else: + ret += ""+str(key)+": "+ "{:.2E}".format(float(str(entry.info[key]).split('\n')[0])) +"
" ret += "

" return ret diff --git a/src/templates/alert_info.html b/src/templates/alert_info.html index fea981df..de585353 100644 --- a/src/templates/alert_info.html +++ b/src/templates/alert_info.html @@ -5,7 +5,9 @@ .slidecontainer { width: 100%; } - +#max_rank { + width: 9em; +} .slider { width: 100%; height: 25px; @@ -168,14 +170,45 @@

GRB Coverage

Sources

+ +
- + +

Galaxies

+ +
+
+
+
+ + + +
+ +
+
+ +
+
+ +
+
+ + +

Galaxies

@@ -183,7 +182,7 @@

Galaxies

- + Galaxies />
-
-
- -
+
- -
@@ -1204,130 +1198,12 @@

Candidates

}); }); - //getting the alert event galaxies - -// ---------------------------- -// Global galaxy list accessible across files -// ---------------------------- -// window.CURRENT_GALAXY_LIST = null; - -// $(document).ready(function () { -// $('#alert_event_galaxies').click(function (e) { -// e.preventDefault(); // prevent form submission if inside a form - -// const button = document.getElementById('alert_event_galaxies'); -// const alertid = document.getElementById('hidden_alertid').value; -// const maxRankInput = document.querySelector('#max_rank'); - -// // --------------------------- -// // GET GALAXIES -// // --------------------------- -// if (button.innerHTML === 'Get') { -// $('#alert_event_galaxies').prop('disabled', true); - -// $.ajax({ -// url: '/ajax_event_galaxies', -// data: 'alertid=' + alertid -// }) -// .done(function (event_galaxies) { -// try { -// if (!event_galaxies || !event_galaxies.length) { -// $('#alert_gal_div').html('

No Results

'); -// $('#alert_event_galaxies').prop('disabled', false); -// return; -// } - -// const firstGroupMarkers = event_galaxies[0].markers; -// let max_rank = (maxRankInput && parseInt(maxRankInput.value, 10)) || firstGroupMarkers.length; -// if (isNaN(max_rank) || max_rank < 1) max_rank = firstGroupMarkers.length; - -// // --------------------------- -// // Function: limit markers in all groups -// // --------------------------- -// function limitAllGroups(galaxies, limit) { -// return galaxies.map(group => ({ -// ...group, -// markers: group.markers.slice(0, limit) -// })); -// } - -// // Initial limited galaxy list -// const limited_galaxies = limitAllGroups(event_galaxies, max_rank); -// window.CURRENT_GALAXY_LIST = limited_galaxies; // <- global assignment - -// // --------------------------- -// // Max rank input listener -// // --------------------------- -// if (maxRankInput) { -// if (maxRankInput._onMaxRankChange) { -// maxRankInput.removeEventListener('change', maxRankInput._onMaxRankChange); -// } - -// maxRankInput._onMaxRankChange = function () { -// const new_max = parseInt(maxRankInput.value, 10); - -// if (isNaN(new_max) || new_max < 1) return; -// if (new_max > firstGroupMarkers.length) return; - -// const new_limited_galaxies = limitAllGroups(event_galaxies, new_max); -// window.CURRENT_GALAXY_LIST = new_limited_galaxies; - -// // Update Aladin -// const new_markerlist = aladin_setMarkers(aladin, new_limited_galaxies); -// marker_list['alert_gal'] = new_limited_galaxies -// aladin_setMarkerHtml(new_limited_galaxies, 'alert_gal_div'); -// set_aladin_markerlist['alert_gal'] = new_markerlist; -// }; - -// maxRankInput.addEventListener('change', maxRankInput._onMaxRankChange); -// } - -// // --------------------------- -// // Initial render -// // --------------------------- -// const gal_markerlist = aladin_setMarkers(aladin, limited_galaxies); -// marker_list['alert_gal'] = limited_galaxies -// aladin_setMarkerHtml(limited_galaxies, 'alert_gal_div'); -// set_aladin_markerlist['alert_gal'] = gal_markerlist; - -// button.innerHTML = 'Hide'; -// $('#alert_event_galaxies').prop('disabled', false); - -// } catch (err) { -// console.error('Error processing event_galaxies', err); -// $('#alert_gal_div').html('

Error :(

'); -// $('#alert_event_galaxies').prop('disabled', false); -// } -// }) -// .fail(function () { -// $('#alert_event_galaxies').prop('disabled', false); -// $('#alert_gal_div').html('Error fetching galaxies'); -// }); - -// return; -// } - -// // --------------------------- -// // HIDE / SHOW TOGGLE -// // --------------------------- -// if (button.innerHTML === 'Hide') { -// aladin_markerToggleAll(set_aladin_markerlist['alert_gal'], false); -// button.innerHTML = 'Show'; -// $('.gal_coll input:checkbox').prop('checked', false); -// } else if (button.innerHTML === 'Show') { -// aladin_markerToggleAll(set_aladin_markerlist['alert_gal'], true); -// button.innerHTML = 'Hide'; -// $('.gal_coll input:checkbox').prop('checked', true); -// } -// }); -// }); - -// ---------------------------- -// Global galaxy list accessible across files -// ---------------------------- -window.CURRENT_GALAXY_LIST = null; - -$(document).ready(function () { + // ---------------------------- + // Global galaxy list accessible across files + // ---------------------------- + window.CURRENT_GALAXY_LIST = null; + + $(document).ready(function () { $('#alert_event_galaxies').click(function (e) { e.preventDefault(); From e096c4a44459e7cbb96e0964c30991bb903f6280 Mon Sep 17 00:00:00 2001 From: Kathryn Wynn Date: Mon, 12 Jan 2026 15:51:30 -0800 Subject: [PATCH 3/4] fixed form validation for strings and scientific notation --- src/templates/alert_info.html | 339 +++++++++++++++++----------------- 1 file changed, 174 insertions(+), 165 deletions(-) diff --git a/src/templates/alert_info.html b/src/templates/alert_info.html index 43dd0c61..7d555c69 100644 --- a/src/templates/alert_info.html +++ b/src/templates/alert_info.html @@ -1205,219 +1205,228 @@

Candidates

$(document).ready(function () { - $('#alert_event_galaxies').click(function (e) { - e.preventDefault(); - - const button = document.getElementById('alert_event_galaxies'); - const alertid = document.getElementById('hidden_alertid').value; - const maxRankInput = document.querySelector('#max_rank'); - - // --------------------------- - // Helper: limit markers in all groups - // --------------------------- - function limitAllGroups(galaxies, limit) { - return galaxies.map(group => ({ - ...group, - markers: group.markers.slice(0, limit) - })); - } + $('#alert_event_galaxies').click(function (e) { + e.preventDefault(); + + const button = document.getElementById('alert_event_galaxies'); + const alertid = document.getElementById('hidden_alertid').value; + const maxRankInput = document.querySelector('#max_rank'); + + // --------------------------- + // Helper: limit markers in all groups + // --------------------------- + function limitAllGroups(galaxies, limit) { + return galaxies.map(group => ({ + ...group, + markers: group.markers.slice(0, limit) + })); + } - // --------------------------- - // Helper: parse max-rank (blank = all) - // --------------------------- - function getMaxRankOrAll(input, maxAvailable) { - if (!input) return maxAvailable; + // --------------------------- + // Helper: parse max-rank + // --------------------------- - const raw = input.value.trim(); + function getMaxRank(input, maxAvailable) { + if (!input) return null; - // blank → all galaxies - if (raw === '') return maxAvailable; + // distinguish blank vs invalid string + if (input.validity.badInput) return undefined; - const value = parseInt(raw, 10); + const raw = input.value.trim(); - if (!Number.isInteger(value)) return null; - if (value < 1 || value > maxAvailable) return null; + // blank → explicitly blank + if (raw === '') return null; - return value; - } + const value = input.valueAsNumber; - // --------------------------- - // Helper: refresh markers IN PLACE - // --------------------------- - function refreshGalaxyMarkersInCatalog(galaxySets, galaxies) { - if (!galaxySets) return; + if (Number.isNaN(value)) return undefined; + if (!Number.isInteger(value)) return undefined; + if (value < 1 || value > maxAvailable) return undefined; - for (let i = 0; i < galaxySets.length; i++) { - const set = galaxySets[i]; - const markers = galaxies[i].markers; + return value; + } - // clear catalog markers - set.markerlayer.clear(); + // --------------------------- + // Helper: refresh markers in place + // --------------------------- + function refreshGalaxyMarkersInCatalog(galaxySets, galaxies) { + if (!galaxySets) return; - // clear overlay graphics - if (set.has_overlay && set.overlaylayer) { - set.overlaylayer.removeAll(); - } + for (let i = 0; i < galaxySets.length; i++) { + const set = galaxySets[i]; + const markers = galaxies[i].markers; + + // clear catalog markers + set.markerlayer.clear(); + + // clear overlay graphics + if (set.has_overlay && set.overlaylayer) { + set.overlaylayer.removeAll(); + } - // rebuild markers - for (let j = 0; j < markers.length; j++) { - const m = markers[j]; + // rebuild markers + for (let j = 0; j < markers.length; j++) { + const m = markers[j]; - const marker = A.marker(m.ra, m.dec, { - popupTitle: m.name, - popupDesc: m.info - }); + const marker = A.marker(m.ra, m.dec, { + popupTitle: m.name, + popupDesc: m.info + }); - set.markerlayer.addSources([marker]); + set.markerlayer.addSources([marker]); - if (set.has_overlay) { - set.overlaylayer.add( - A.circle(m.ra, m.dec, m.radius, { - color: set.markerlayer.color - }) - ); + if (set.has_overlay) { + set.overlaylayer.add( + A.circle(m.ra, m.dec, m.radius, { + color: set.markerlayer.color + }) + ); + } } } } - } - // --------------------------- - // GET GALAXIES - // --------------------------- - if (button.innerHTML === 'Get') { + // --------------------------- + // GET GALAXIES + // --------------------------- + if (button.innerHTML === 'Get') { - $('#alert_event_galaxies').prop('disabled', true); + $('#alert_event_galaxies').prop('disabled', true); - $.ajax({ - url: '/ajax_event_galaxies', - data: 'alertid=' + alertid - }) - .done(function (event_galaxies) { + $.ajax({ + url: '/ajax_event_galaxies', + data: 'alertid=' + alertid + }) + .done(function (event_galaxies) { - try { - if (!event_galaxies || !event_galaxies.length) { - $('#alert_gal_div').html('

No Results

'); - $('#alert_event_galaxies').prop('disabled', false); - return; - } + try { + if (!event_galaxies || !event_galaxies.length) { + $('#alert_gal_div').html('

No Results

'); + $('#alert_event_galaxies').prop('disabled', false); + return; + } - const firstGroupMarkers = event_galaxies[0].markers; + const firstGroupMarkers = event_galaxies[0].markers; - // configure bounds (NOT required) - if (maxRankInput) { - maxRankInput.min = 1; - maxRankInput.max = firstGroupMarkers.length; - } + // configure bounds + if (maxRankInput) { + maxRankInput.min = 1; + maxRankInput.max = firstGroupMarkers.length; + } - // --------------------------- - // Initial render - // --------------------------- - let max_rank = getMaxRankOrAll(maxRankInput, firstGroupMarkers.length); + // --------------------------- + // Initial render + // --------------------------- + let max_rank = getMaxRank(maxRankInput, firstGroupMarkers.length); - if (max_rank === null) { - max_rank = firstGroupMarkers.length; - } + if (max_rank === null) { + max_rank = firstGroupMarkers.length; + } - const limited_galaxies = limitAllGroups(event_galaxies, max_rank); + const limited_galaxies = limitAllGroups(event_galaxies, max_rank); - window.CURRENT_GALAXY_LIST = limited_galaxies; + window.CURRENT_GALAXY_LIST = limited_galaxies; - const galaxySets = aladin_setMarkers(aladin, limited_galaxies); + const galaxySets = aladin_setMarkers(aladin, limited_galaxies); - set_aladin_markerlist['alert_gal'] = galaxySets; - marker_list['alert_gal'] = limited_galaxies; + set_aladin_markerlist['alert_gal'] = galaxySets; + marker_list['alert_gal'] = limited_galaxies; - aladin_setMarkerHtml(limited_galaxies, 'alert_gal_div'); + aladin_setMarkerHtml(limited_galaxies, 'alert_gal_div'); - // --------------------------- - // Max-rank change handler - // --------------------------- - if (maxRankInput) { + // --------------------------- + // Max-rank change handler + // --------------------------- + if (maxRankInput) { - if (maxRankInput._onMaxRankChange) { - maxRankInput.removeEventListener( - 'change', - maxRankInput._onMaxRankChange - ); - } + if (maxRankInput._onMaxRankChange) { + maxRankInput.removeEventListener( + 'change', + maxRankInput._onMaxRankChange + ); + } - maxRankInput._onMaxRankChange = function () { + maxRankInput._onMaxRankChange = function () { + const maxAvailable = firstGroupMarkers.length; + const result = getMaxRank(maxRankInput, maxAvailable); - const new_max = getMaxRankOrAll(maxRankInput, firstGroupMarkers.length); + // invalid input → show error + if (result === undefined) { + maxRankInput.setCustomValidity( + `Enter a whole number between 1 and ${maxAvailable}, or leave blank` + ); + maxRankInput.reportValidity(); + return; + } - // invalid (but not blank) - if (new_max === null) { - maxRankInput.setCustomValidity( - `Enter a number between 1 and ${firstGroupMarkers.length}, or leave blank` - ); - maxRankInput.reportValidity(); + // ✅ clear any previous error maxRankInput.setCustomValidity(''); - return; - } - const new_limited_galaxies = limitAllGroups(event_galaxies, new_max); + // blank → show all + const max_rank = + result === null ? maxAvailable : result; - window.CURRENT_GALAXY_LIST = new_limited_galaxies; + const new_limited_galaxies = + limitAllGroups(event_galaxies, max_rank); + + window.CURRENT_GALAXY_LIST = new_limited_galaxies; - // 🔄 update markers in place - refreshGalaxyMarkersInCatalog( - set_aladin_markerlist['alert_gal'], - new_limited_galaxies - ); - - marker_list['alert_gal'] = new_limited_galaxies; - aladin_setMarkerHtml(new_limited_galaxies, 'alert_gal_div'); + refreshGalaxyMarkersInCatalog( + set_aladin_markerlist['alert_gal'], + new_limited_galaxies + ); - // ❌ removed requestSubmit() → no page reload - }; + marker_list['alert_gal'] = new_limited_galaxies; + aladin_setMarkerHtml(new_limited_galaxies, 'alert_gal_div'); + }; - maxRankInput.addEventListener( - 'change', - maxRankInput._onMaxRankChange - ); - } + maxRankInput.addEventListener( + 'change', + maxRankInput._onMaxRankChange + ); + } - button.innerHTML = 'Hide'; - $('#alert_event_galaxies').prop('disabled', false); + button.innerHTML = 'Hide'; + $('#alert_event_galaxies').prop('disabled', false); - } catch (err) { - console.error('Error processing event_galaxies', err); - $('#alert_gal_div').html('

Error :(

'); + } catch (err) { + console.error('Error processing event_galaxies', err); + $('#alert_gal_div').html('

Error :(

'); + $('#alert_event_galaxies').prop('disabled', false); + } + }) + .fail(function () { $('#alert_event_galaxies').prop('disabled', false); - } - }) - .fail(function () { - $('#alert_event_galaxies').prop('disabled', false); - $('#alert_gal_div').html( - 'Error fetching galaxies' - ); - }); + $('#alert_gal_div').html( + 'Error fetching galaxies' + ); + }); - return; - } + return; + } - // --------------------------- - // HIDE / SHOW TOGGLE - // --------------------------- - if (button.innerHTML === 'Hide') { - aladin_markerToggleAll( - set_aladin_markerlist['alert_gal'], - false - ); - button.innerHTML = 'Show'; - $('.gal_coll input:checkbox').prop('checked', false); + // --------------------------- + // HIDE / SHOW TOGGLE + // --------------------------- + if (button.innerHTML === 'Hide') { + aladin_markerToggleAll( + set_aladin_markerlist['alert_gal'], + false + ); + button.innerHTML = 'Show'; + $('.gal_coll input:checkbox').prop('checked', false); - } else if (button.innerHTML === 'Show') { - aladin_markerToggleAll( - set_aladin_markerlist['alert_gal'], - true - ); - button.innerHTML = 'Hide'; - $('.gal_coll input:checkbox').prop('checked', true); - } + } else if (button.innerHTML === 'Show') { + aladin_markerToggleAll( + set_aladin_markerlist['alert_gal'], + true + ); + button.innerHTML = 'Hide'; + $('.gal_coll input:checkbox').prop('checked', true); + } - }); -}); + }); + }); //Function that calls the XRT sources and populates them From 2d23f565fe4a3236335f60c90167493ec0a984b8 Mon Sep 17 00:00:00 2001 From: Kathryn Wynn Date: Mon, 12 Jan 2026 16:11:57 -0800 Subject: [PATCH 4/4] cleaning up comments --- src/templates/alert_info.html | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/templates/alert_info.html b/src/templates/alert_info.html index 7d555c69..31937243 100644 --- a/src/templates/alert_info.html +++ b/src/templates/alert_info.html @@ -170,8 +170,6 @@

GRB Coverage

Sources

- -
@@ -670,7 +668,6 @@

Candidates

var d = gwtmAladinInit(data) data.aladin = d.aladin var aladin = d.aladin - window.aladin = d.aladin; // global reference var detectionoverlaylist = d.detectionoverlaylist var grboverlaylist = d.grboverlaylist var instoverlaylist = {} @@ -1203,6 +1200,7 @@

Candidates

// ---------------------------- window.CURRENT_GALAXY_LIST = null; + //Function that generates/refreshes the galaxy visualization $(document).ready(function () { $('#alert_event_galaxies').click(function (e) { @@ -1212,9 +1210,7 @@

Candidates

const alertid = document.getElementById('hidden_alertid').value; const maxRankInput = document.querySelector('#max_rank'); - // --------------------------- - // Helper: limit markers in all groups - // --------------------------- + // function to limit markers in all groups function limitAllGroups(galaxies, limit) { return galaxies.map(group => ({ ...group, @@ -1222,10 +1218,7 @@

Candidates

})); } - // --------------------------- - // Helper: parse max-rank - // --------------------------- - + // function to parse max-rank function getMaxRank(input, maxAvailable) { if (!input) return null; @@ -1246,9 +1239,7 @@

Candidates

return value; } - // --------------------------- - // Helper: refresh markers in place - // --------------------------- + // function to refresh markers in place function refreshGalaxyMarkersInCatalog(galaxySets, galaxies) { if (!galaxySets) return; @@ -1286,9 +1277,8 @@

Candidates

} } - // --------------------------- - // GET GALAXIES - // --------------------------- + + // get galaxies if (button.innerHTML === 'Get') { $('#alert_event_galaxies').prop('disabled', true); @@ -1314,9 +1304,7 @@

Candidates

maxRankInput.max = firstGroupMarkers.length; } - // --------------------------- // Initial render - // --------------------------- let max_rank = getMaxRank(maxRankInput, firstGroupMarkers.length); if (max_rank === null) { @@ -1334,9 +1322,7 @@

Candidates

aladin_setMarkerHtml(limited_galaxies, 'alert_gal_div'); - // --------------------------- // Max-rank change handler - // --------------------------- if (maxRankInput) { if (maxRankInput._onMaxRankChange) { @@ -1359,7 +1345,7 @@

Candidates

return; } - // ✅ clear any previous error + // clear any previous error maxRankInput.setCustomValidity(''); // blank → show all @@ -1368,7 +1354,6 @@

Candidates

const new_limited_galaxies = limitAllGroups(event_galaxies, max_rank); - window.CURRENT_GALAXY_LIST = new_limited_galaxies; refreshGalaxyMarkersInCatalog( @@ -1405,9 +1390,7 @@

Candidates

return; } - // --------------------------- // HIDE / SHOW TOGGLE - // --------------------------- if (button.innerHTML === 'Hide') { aladin_markerToggleAll( set_aladin_markerlist['alert_gal'],