local p = { }
local navbar = require('Module:Navbar')._navbar
local infobox = require('Module:Infobox3cols').infobox
local infoboxImage = require('Module:InfoboxImage').InfoboxImage
--on a page {{#invoke:Sandbox/genewiki/alllua|getTemplateData|QID=Q14865053}}
--in debug window
--frame = mw.getCurrentFrame()
--frame.args = {QID="Q14865053"}
--print(p.getTemplateData(frame))
p.getTemplateData = function(frame)
--make some guesses about whether the provided QID is a good one
--could expand here if we had some kind of error handling framework
--did we get it from the page
local root_qid = mw.text.trim(frame.args['QID'] or "") --try to get it from the args
--pull all the entity objects that we will need
local entity = ""
local entity_protein = ""
local entity_mouse = ""
local entity_mouse_protein = ""
local checkOrtholog = "" --flag used to see if mouse data avaliable
local mouse_propertyID = "P684"
local protein_propertyID = "P688"
local entity_works
--get root gene entity
if root_qid == "" then
entity = mw.wikibase.getEntityObject()
if entity then root_qid = entity.id else root_qid = "" end
else
--assuming we think its good make one call to retrieve and store its wikidata representation
entity = mw.wikibase.getEntity(root_qid)
end
--get the other related entities
if entity then
local claims = ""
--get protein entity object
claims = entity.claims[protein_propertyID]
if claims then
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
local protein_itemID = "Q" .. claims[1].mainsnak.datavalue.value["numeric-id"]
entity_protein = mw.wikibase.getEntity(protein_itemID)
end --will return nothing if no claims are found
end
--get mouse entity object
claims = entity.claims[mouse_propertyID]
if claims then
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
local mouse_itemID = "Q" .. claims[1].mainsnak.datavalue.value["numeric-id"]
entity_mouse = mw.wikibase.getEntity(mouse_itemID)
checkOrtholog = 1
end --will return nothing if no claims are found
else
checkOrtholog = 0
end
--get mouse protein entity object
claims = entity_mouse.claims[protein_propertyID]
if claims then
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
local protein_itemID = "Q" .. claims[1].mainsnak.datavalue.value["numeric-id"]
entity_mouse_protein = mw.wikibase.getEntity(protein_itemID)
end --will return nothing if no claims are found
end
end
if entity then --only require the main gene entity
--a list variables of all the data in the info box
local entrez_gene = p.getValue(entity, "P351")
local image = p.getDefaultImage(entity) --need to set size
local uniprotID_hs = p.getValue(entity_protein, "P352")
local uniprotID_mm = p.getValue(entity_mouse_protein, "P352")
local pdbIDs = p.getPDB(entity_protein) --makes a list with links to RCSB
local aliases = p.getAliases(entity)
local gene_symbol = p.getValue(entity, "P353")
local hgnc_id = p.getValue(entity, "P354")
local homologene_id = p.getValue(entity, "P593")
local omim_id = p.getValue(entity, "P492")
local genome_start = p.getChromosomeLoc(entity, "P644")
local genome_end = p.getChromosomeLoc(entity, "P645")
--define Global Color Scheme
rowBGcolor = '#eee'
titleBGcolor = '#ddd'
sideTitleBGcolor = '#c3fdb8'
p.createTable()
p.renderUpperTitle()
--p.renderCaption()
root:newline()
p.renderImage(image)
root:newline()
p.renderAvaliableStructures(uniprotID_hs, uniprotID_mm, checkOrtholog, pdbIDs) --PDB info
root:newline()
p.renderIdentifiers(aliases, hgnc_id, gene_symbol, homologene_id, omim_id, entrez_gene)
root:newline()
return tostring(root)
else return "root entity not set"
end
end
p.createTable = function(subbox)
if subbox == 'sub' then --doesn't work
root
:tag('table')
:css('padding', '0')
:css('border', 'none')
:css('margin', '0')
:css('width', 'auto')
:css('min-width', '100%')
:css('font-size', '100%')
:css('clear', 'none')
:css('float', 'none')
:css('background-color', 'transparent')
else
root = mw.html.create('table')
root
:addClass('infobox')
:css('width', '26.4em')
end
end
--Title above image
p.renderUpperTitle = function()
local title = tostring(mw.title.getCurrentTitle())
if not title then return "error: failed to getCurrentTitle()"; end
root
:tag('tr')
:tag('th')
:attr('colspan', 4)
:css('text-align', 'center')
:css('font-size', '125%')
:css('font-weight', 'bold')
:wikitext(title)
end
--This is a place holder for the image caption, which is stored in wikicommons comments unsure how to access
p.renderCaption = function(entity)
--caption
end
--gets default image
p.renderImage = function(image)
root
:tag('tr')
:tag('td')
:attr('colspan', 4)
:css('text-align', 'center')
:wikitext(image)
:done()
end
p.renderAvaliableStructures = function(uniprotID_hs, uniprotID_mm, checkOrtholog, pdbIDs)
local title = 'Available structures'
local pdb_link = "[[Protein_Data_Bank|PDB]]"
local searchTitle = ""
local listTitle = "List of PDB id codes"
local PDBe_base = 'http://www.ebi.ac.uk/pdbe/searchResults.html?display=both&term='
local RCSB_base = 'http://www.rcsb.org/pdb/search/smartSubquery.do?smartSearchSubtype=UpAccessionIdQuery&accessionIdList='
local url_uniprot = " "
if checkOrtholog == 1 then
searchTitle = 'Ortholog search: '
url_uniprot = uniprotID_mm
else
searchTitle = 'Human UniProt search: '
url_uniprot = uniprotID_hs
end
local PDBe = "["..PDBe_base..url_uniprot.." PDBe]"
local RCSB = "["..RCSB_base..url_uniprot.." RCSB]"
--p.formatRow(title)---how to not close the tags is a mystery and I could condense code once I figure out
root
:tag('tr')
:tag('td')
:attr('colspan', 4)
:css('text-align', 'center')
:css('background-color', rowBGcolor)
:newline()
--p.createTable('sub')
:tag('table')
:css('padding', '0')
:css('border', 'none')
:css('margin', '0')
:css('width', '100%')
:css('text-align', 'left')
:newline()
:tag('tr') --create title header
:css('background-color',titleBGcolor)
:css('text-align', 'center')
:tag('th')
:attr('colspan',"2")
:wikitext(title)
:done()
:done()
:newline()
--p.rowLabel(pdb_link)
:tag('tr')
:tag('th')
:attr('rowspan', '2')
:css('background-color', sideTitleBGcolor)
:css('width', '43px')
:wikitext(pdb_link)
:done()
:tag('td')
:attr('colspan', '2')
:css('background-color', rowBGcolor)
:wikitext(searchTitle)
:wikitext(PDBe)
:wikitext(RCSB)
:done()
:done() --this may not be needed
:newline()
--new row for collapsible list of PDB codes
:tag('tr')
:tag('td')
:tag('table')
:attr('class', 'collapsible collapsed')
:css('padding', '0')
:css('border', 'none')
:css('margin', '0')
:css('width', '100%')
:css('text-align', 'left')
:newline()
:tag('tr')
:css('background-color',titleBGcolor)
:css('text-align', 'center')
:newline()
:tag('th')
:attr('colspan', '2')
:wikitext(listTitle)
:done()
:newline()
:done()
:tag('tr')
:tag('td')
:attr('colspan', '2')
:css('background-color', rowBGcolor)
:newline()
:tag('p')
:wikitext(pdbIDs)
end
p.renderIdentifiers = function(aliases, hgnc_id, gene_symbol, homologene_id, omim_id, entrez_gene)
local title = "Identifiers"
local label_aliases = "[https://en.wikipedia.org/wiki/Human_Genome_Organisation Aliases]"
local symbol_url = "[http://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id"..hgnc_id.." "..gene_symbol.."] "
aliases = string.gsub(aliases, gene_symbol, "") --get rid of gene name if in aliases list
aliases = string.gsub(aliases, ", ,", ",") --remove comma from middle
aliases = string.gsub(aliases, ", $", "") --remove comma from end
local label_ext_id = "External IDs"
local omim = "[[Mendelian_Inheritance_in_Man|OMIM:]]".." ".."[https://omim.org/entry/"..omim_id.." "..omim_id.."]"
local homolo = "[[HomoloGene|HomoloGene:]]".." ".."[http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=homologene&dopt=HomoloGene&list_uids="..homologene_id.." "..homologene_id.."]"
local genecards = "[[GeneCards|GeneCards:]]".." ".."[http://www.genecards.org/cgi-bin/carddisp.pl?id_type=entrezgene&id="..entrez_gene.." "..entrez_gene.."]"
p.formatRow(title)
--p.rowLabel(label)
root
:tag('tr')
:tag('th')
:attr('rowspan', '2')
:css('background-color', sideTitleBGcolor)
:css('width', '43px')
:wikitext(label_aliases)
:done()
:newline()
:tag('td')
:attr('colspan', '3')
:css('background-color', rowBGcolor)
:wikitext(symbol_url)
:wikitext(aliases)
:done()
:done()
:done()
:newline()
:tag('tr')
:tag('th')
:attr('rowspan', '2')
:css('background-color', sideTitleBGcolor)
:css('width', '43px')
:wikitext(label_ext_id)
:done()
:newline()
:tag('td')
:attr('colspan', '3')
:css('background-color', rowBGcolor)
:wikitext(omim)
:wikitext(homolo)
:wikitext(genecards)
:done()
end
p.formatRow = function(title)
root
:tag('tr')
:tag('td')
:attr('colspan', 4)
:css('text-align', 'center')
:css('background-color', rowBGcolor)
:newline()
--p.createTable('sub')
:tag('table')
:css('padding', '0')
:css('border', 'none')
:css('margin', '0')
:css('width', '100%')
:css('text-align', 'left')
:newline()
:tag('tr') --create title header
:css('background-color',titleBGcolor)
:css('text-align', 'center')
:tag('th')
:attr('colspan',"2")
:wikitext(title)
:done()
:done()
:newline()
end
p.rowLabel=function(label)
root
:tag('tr')
:tag('th')
:attr('rowspan', '2')
:css('background-color', sideTitleBGcolor)
:css('width', '43px')
:wikitext(label)
--:done()
end
--general function to get value given an entity and property
p.getValue = function(entity, propertyID)
local claims
local value = ""
if entity and entity.claims then
claims = entity.claims[propertyID]
end
--will return nothing if no claims are found
if claims then
value = "has claims"
if (claims[1]) then
local out = {}
for k, v in pairs(claims) do
local datav = v.mainsnak.datavalue.value
out[#out + 1] = datav
end
value = table.concat(out, sep)
else
return "" -- no claims
end
else
value = ""
end
return value
end
--gets an image
p.getDefaultImage = function(entity)
local propertyID = "P18"
local sep = mw.text.trim(" ")
local imgsize = mw.text.trim("250px")
local claims
if entity and entity.claims then
claims = entity.claims[propertyID]
end
if claims then
if (claims[1] and claims[1].mainsnak.datatype == "commonsMedia") then
local out = {}
for k, v in pairs(claims) do
local filename = v.mainsnak.datavalue.value
out[#out + 1] = "[[File:" .. filename .. "|" .. imgsize .. "]]"
end
return table.concat(out, sep)
else
return ""
end
else
return ""
end
end
p.getPDB = function(entity)
local pdb_propertyID = "P638"
local claims = entity.claims[pdb_propertyID]
local sitelink = "http://www.rcsb.org/pdb/explore/explore.do?pdbId="
if claims then
if (claims[1] and claims[1].mainsnak.snaktype == "value") then
local out = {}
for k, v in pairs(claims) do
local label = mw.wikibase.label(v.mainsnak.datavalue.value)
if label == nil then label = v.mainsnak.datavalue.value end
if sitelink then
out[#out + 1] = "[" .. sitelink .. label .. " " ..label .. "]"
else
out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value .. "|" .. label .. "]]"
end
end
return table.concat(out, ", ")
else
return entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
end
else
return ""
end
end
function p.getAliases(entity)
a = ''
if entity['aliases'] ~= nil then
test = entity['aliases']['en']
for key, value in ipairs(test) do
a = a .. ', ' .. value['value']
end
return a
else
return ""
end
end
--get a geneome start P644 or end P645
p.getChromosomeLoc = function(entity, propertyID)
-- will contain the numeric value for the requested coordinate
local output = ""
local sep = " "
-- can only be P644 (genomic start) or P645 (genomic end) for this to work
-- should probably try to catch that. Might also increase legibility to use specific variable names when possible
-- local propertyID = mw.text.trim(frame.args[1] or "")
-- this can really only be P659 right now. I'm not sure of the value of including it as a parameter as other values will likely break this function
local qualifierID = "P659" --mw.text.trim(frame.args[2] or "")
-- Why do we include this here? What should happen if FETCH_WIKIDATA is not included?
--local input_parm = mw.text.trim(frame.args[3] or "")
-- this can needs to be fed to the function either by a call to {{#invoke:Wikidata|pageId}} or by setting it directly (e.g. if the function was applied on a page other than the targeted gene)
--alert if this id is not a valid thing in wikidata, a Lua error will occur that says
--The ID entered is unknown to the system. Please use a valid entity ID.
--local itemID = mw.text.trim(frame.args[4] or "")
-- will track the different builds pulled from the qualifiers
local newest_build = "0"
-- starts the process
--local entity = mw.wikibase.getEntityObject(itemID)
local claims
--gets a table of claims on the (genomic start or end) property Q19847637
if entity and entity.claims then
claims = entity.claims[propertyID]
end
--will return nothing if no claims are found
if claims then
--checking to be sure claims is populated, not sure it its needed
if (claims[1] ) then
--useful for debugging
--local out = {}
--pulls the genome location from the claim
for k, v in pairs(claims) do
local location = v.mainsnak.datavalue.value
--debugging
--out[#out + 1] = k.." location:" .. location.. " || "
--gets the qualifiers linked to the current claim
local quals = v.qualifiers.P659
--if there are any
if quals then
for qk, qv in pairs(quals) do
local qual_obj_id = "Q"..qv.datavalue.value["numeric-id"]
--get to the entity targeted by the qualifier property. Genome builds are Items in wikidata
local qual_obj = mw.wikibase.getEntityObject(qual_obj_id)
local alias = ""
--this uses the aliases to pull out version numbers
--seems like there ought to be a better way to do this, but likely would need to change the data added by the bot
if qual_obj["aliases"] ~= nil then
local test = qual_obj["aliases"]["en"]
for key, value in ipairs(test) do
if string.match(value['value'], '^hg') then
alias = value['value']
local build_no = alias:gsub("hg","")
--report only the most location associated with the most recent build
--if there is more than one location per build, just give one back as that is not our problem right now.
if build_no > newest_build then
output = location
newest_build = build_no
end
end
end
end
end
--in case there are no qualifiers, but there is a location, might as well return it
else output = location
end
end
return output
else
return ""
end
else
return ""
--debug
--"no claims for "..itemID.." prop "..propertyID
end
end
return p