Jump to content

Module:Infobox gene

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Sebotic (talk | contribs) at 05:02, 6 November 2015 (Created page with 'local p = { } local navbar = require('Module:Navbar')._navbar local infobox = require('Module:Infobox3cols').infobox local infoboxImage = require('Module:Infobo...'). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

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