Esempio n. 1
0
	def __init__(self,parent=None):
		IRIDAQueryLayout.__init__(self,parent)
		self.GBIFGeneric = GBIFGeneric()
		self.login = Login(self)
		#self.credentials = Credentials()
		self.SetIcon(wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",wx.BITMAP_TYPE_ICO))
		self.m_Add.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Add.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		
		self.m_IDList.Clear()
		self.m_Search.Enable(False)
		self.m_Calc.Enable(False)
		#fix to expand summary box enough to print two lines of text properly
		
		#Map Data
		if GenGIS.layerTree.GetNumMapLayers() > 0 :
			self.m_AddData.Enable()
			borders = GenGIS.layerTree.GetMapLayer(0).GetController().GetMapBorders()
			#check if geographic coordinates are used or some other measure; only geographic are compatible
			geographic = GenGIS.StudyController.IsUsingGeographic(GenGIS.study.GetController())
			projected = GenGIS.StudyController.IsUsingProjection(GenGIS.study.GetController())
			if(not (geographic or projected)):
				wx.MessageBox("Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with MG-RAST. Geographic range will need to be manually set, and any returned data will not display correctly.","Warning")
				self.m_AddData.Disable()
		credential = Credentials(self,False)
		credential.OnCredentialClose("fake")
		
		# By this point the active credential should be loaded.
		if self.clientId and self.clientSecret:
			self.login.ShowModal()
Esempio n. 2
0
	def __init__(self,parent=None):
		MaxLon,MinLon,MaxLat,MinLat = 180,-180,90,-90
		self.GBIFSpecific = GBIFSpecific()
		self.GBIFGeneric = GBIFGeneric()
		GBIFQueryLayout.__init__(self,parent)
		self.SetIcon(wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",wx.BITMAP_TYPE_ICO))
		self.m_Compass.SetIcon(wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/GBIF_compass_small.png",wx.BITMAP_TYPE_PNG))
		self.m_Add.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Add.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		
		self.graphicalElementIds=[]
		self.__selectedTaxon__=set()
		self.__obs__ = []
		self.m_IDList.Clear()
		#fix to expand summary box enough to print two lines of text properly
		self.m_Summary.SetLabel("\n\n")
		
		#No Map Data
		self.m_AddData.Disable()
		
		#Map Data
		if GenGIS.layerTree.GetNumMapLayers() > 0 :
			self.m_AddData.Enable()
			borders = GenGIS.layerTree.GetMapLayer(0).GetController().GetMapBorders()
			#check if geographic coordinates are used or some other measure; only geographic are compatible
			geographic = GenGIS.StudyController.IsUsingGeographic(GenGIS.study.GetController())
			projected = GenGIS.StudyController.IsUsingProjection(GenGIS.study.GetController())
			if(not (geographic or projected)):
				wx.MessageBox("Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with GBIF. Geographic range will need to be manually set, and any returned data will not display correctly.","Warning")
				self.m_AddData.Disable()
				self.m_MinLat.SetValue(str(MinLat))
				self.m_MaxLat.SetValue(str(MaxLat))
				self.m_MinLon.SetValue(str(MinLon))
				self.m_MaxLon.SetValue(str(MaxLon))
			else:
				#Text boxes hate non String types. use int to round, and string to make them fit the container
				self.m_MinLat.SetValue(str(max(MinLat,borders.y1)))
				self.m_MaxLat.SetValue(str(min(MaxLat,borders.dy)))
				self.m_MinLon.SetValue(str(max(MinLon,borders.x1)))
				self.m_MaxLon.SetValue(str(min(MaxLon,borders.dx)))
Esempio n. 3
0
	def __init__(self):
		self.GBIFGeneric = GBIFGeneric()
		self.__description__ = set()
		self.__warnings__=[0,0]
		self.__uniqueNodeList__=set()
Esempio n. 4
0
class GBIFQuery(GBIFQueryLayout):
	#	Global variables to store queried information
	__obs__ = []
	__selectedTaxon__= set()
	__description__=""
	
	def __init__(self,parent=None):
		MaxLon,MinLon,MaxLat,MinLat = 180,-180,90,-90
		self.GBIFSpecific = GBIFSpecific()
		self.GBIFGeneric = GBIFGeneric()
		GBIFQueryLayout.__init__(self,parent)
		self.SetIcon(wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",wx.BITMAP_TYPE_ICO))
		self.m_Compass.SetIcon(wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/GBIF_compass_small.png",wx.BITMAP_TYPE_PNG))
		self.m_Add.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Add.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		
		self.graphicalElementIds=[]
		self.__selectedTaxon__=set()
		self.__obs__ = []
		self.m_IDList.Clear()
		#fix to expand summary box enough to print two lines of text properly
		self.m_Summary.SetLabel("\n\n")
		
		#No Map Data
		self.m_AddData.Disable()
		
		#Map Data
		if GenGIS.layerTree.GetNumMapLayers() > 0 :
			self.m_AddData.Enable()
			borders = GenGIS.layerTree.GetMapLayer(0).GetController().GetMapBorders()
			#check if geographic coordinates are used or some other measure; only geographic are compatible
			geographic = GenGIS.StudyController.IsUsingGeographic(GenGIS.study.GetController())
			projected = GenGIS.StudyController.IsUsingProjection(GenGIS.study.GetController())
			if(not (geographic or projected)):
				wx.MessageBox("Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with GBIF. Geographic range will need to be manually set, and any returned data will not display correctly.","Warning")
				self.m_AddData.Disable()
				self.m_MinLat.SetValue(str(MinLat))
				self.m_MaxLat.SetValue(str(MaxLat))
				self.m_MinLon.SetValue(str(MinLon))
				self.m_MaxLon.SetValue(str(MaxLon))
			else:
				#Text boxes hate non String types. use int to round, and string to make them fit the container
				self.m_MinLat.SetValue(str(max(MinLat,borders.y1)))
				self.m_MaxLat.SetValue(str(min(MaxLat,borders.dy)))
				self.m_MinLon.SetValue(str(max(MinLon,borders.x1)))
				self.m_MaxLon.SetValue(str(min(MaxLon,borders.dx)))
			
	#	Query GBIF for Taxa in Lat/Lon Boundary
	def OnSearch(self,event):
		wx.BeginBusyCursor()
		#	Clear the results list
		self.m_Result.Clear()
		
		taxon = self.m_TaxonName.GetLineText(0)
		taxon=taxon.split()
		if(len(taxon)==0):
			wx.MessageBox("You did not enter a taxon name.")
		else:
			minLatitude= float(self.m_MinLat.GetValue())
			maxLatitude= float(self.m_MaxLat.GetValue())
			minLongitude= float(self.m_MinLon.GetValue())
			maxLongitude= float(self.m_MaxLon.GetValue())
			result=self.GBIFSpecific.GETTAXRESULT(taxon,self.m_Result)
			self.m_Result.InsertItems(result,0)
		wx.EndBusyCursor()
		
	#	Create Sequence and Location files for selected Taxa
	def OnCalculate(self,event):
		self.m_Summary.SetLabel("\n")
		records,distLocations = 0,0
		self.__obs__=[]
		self.__conversions__=[]
		self.__description__=""
		wx.BeginBusyCursor()
		if(self.__selectedTaxon__):
			minLatitude= float(self.m_MinLat.GetValue())
			maxLatitude= float(self.m_MaxLat.GetValue())
			minLongitude= float(self.m_MinLon.GetValue())
			maxLongitude= float(self.m_MaxLon.GetValue())
			self.m_Progress.WriteText("Starting...\n")
			for tax in self.__selectedTaxon__:
				obs,recs,distLocs,description= self.GBIFSpecific.GETOBSENTIRERANGE(tax[1].split(),tax[0],minLatitude,maxLatitude,minLongitude,maxLongitude,self.m_Progress)
				self.__obs__.append(obs)
				self.__description__+="%s\n" % description
				records += recs
				distLocations +=distLocs
			self.m_Progress.WriteText("Done.\n")
		else:
			wx.MessageBox("Please select some Taxa.")
		summaryText = ("%d records retrieved.\n%d distinct locations." %(records,distLocations))
		f = self.m_Summary.GetFont()
		dc = wx.WindowDC(self.m_Summary)
		dc.SetFont(f)
		aSize = dc.GetMultiLineTextExtent(summaryText)
		aSize = wx.Size(aSize[0],aSize[1])
		self.m_Summary.SetSize(aSize)
		
		self.m_Summary.SetLabel(summaryText)
		wx.EndBusyCursor()
	
	#	Present the number of locations a user is about to query
	#	Used as a check by the user to know they aren't going to produce way too much data.
	def OnPreCalculate(self,event):
		wx.BeginBusyCursor()
		self.m_Progress.WriteText("Retrieving record counts.\n")
		self.m_Summary.SetLabel("\n")
		if(self.__selectedTaxon__):
			minLatitude= self.GBIFGeneric.roundCoord(self.m_MinLat.GetValue())
			maxLatitude= self.GBIFGeneric.roundCoord(self.m_MaxLat.GetValue())
			minLongitude= self.GBIFGeneric.roundCoord(self.m_MinLon.GetValue())
			maxLongitude= self.GBIFGeneric.roundCoord(self.m_MaxLon.GetValue())
			count=0
			for tax in self.__selectedTaxon__:
				count+=self.GBIFSpecific.GETCOUNT(tax[1].split(),tax[0],minLatitude,maxLatitude,minLongitude,maxLongitude,self.m_Progress)
			self.m_Summary.SetLabel("There were %d records for the given location." % count)
		else:
			wx.MessageBox("Please select some Taxa.")
		wx.EndBusyCursor()
		
	#	Redirects User to Wiki page for this plugin
	def OnHelp(self, event):
		wx.LaunchDefaultBrowser( 'http://kiwi.cs.dal.ca/GenGIS/Description_of_GenGIS_plugins#GBIF_Query' )
	
	#	Adds Data to GenGIS
	def OnAddData(self,event):
		if (len(self.__obs__) > 0):
			OUTLText, OUTSText = self.GBIFGeneric.GETTEXT(self.__obs__)
			OUTLArray=self.GBIFGeneric.CPPOUT(OUTLText)
			OUTSArray=self.GBIFGeneric.CPPOUT(OUTSText)
			# Removing some Gridding based artifacts, may become useful again in the future.
			#OUTLArray.insert(0,"Site ID,Latitude,Longitude,Richness,Cell ID,Taxon,Genus")
			OUTLArray.insert(0,"Site ID,Latitude,Longitude,Cell ID,Taxon,Genus")
			#OUTSArray.insert(0,"Sequence ID,Site ID,CellLat,CellLong,Taxon,Genus,TrueLat,TrueLong,Count,AllRecords")					
			OUTSArray.insert(0,"Sequence ID,Site ID,Taxon,Genus,TrueLat,TrueLong,Count,AllRecords")					
			OUTLArray.pop()
			OUTSArray.pop()
			layerName = "GBIFLayer_%d" % GenGIS.layerTree.GetNumLocationSetLayers()
			GenGIS.mainWindow.OpenLocationsCSVFile(OUTLArray, layerName)
			GenGIS.mainWindow.OpenSequenceCSVFile(OUTSArray, layerName)
			
			#Get the number of last location layer added (the gbif one)
			numLocationLayers=GenGIS.layerTree.GetNumLocationSetLayers()
			locationSetLayer = GenGIS.layerTree.GetLocationSetLayer(numLocationLayers-1)
			locationSetLayer.SetDescription(self.__description__)
			
		else:
			wx.MessageBox("Please make a successful GBIF Query first.")
		
	#	Exports Location and Sequence Data to a location of the users choice
	def OnExportData(self,event):
		if (len(self.__obs__) > 0):
			fileTypes = 'Loc and Seq Files (*.csv)|*.csv'
			dlg = wx.FileDialog(self, "Save plot", "", "", fileTypes, wx.SAVE)
			if dlg.ShowModal()==wx.ID_OK:
				filename =	dlg.GetFilename()
				dir = dlg.GetDirectory()
				file_split = filename.split(".",1)
				#creates the directories
				OUTLfile = ("%s/%s_locs.csv" % (dir,file_split[0]))				
				OUTSfile = ("%s/%s_seqs.csv" % (dir,file_split[0]))
				OUTDfile = ("%s/%s_source.txt" % (dir,file_split[0]))
				OUTLText, OUTSText = self.GBIFGeneric.GETTEXT(self.__obs__)
				# Removing some Gridding based artifacts, may become useful again in the future.
			#	self.GBIFGeneric.WRITEEXPORT(OUTLfile,OUTLText,"Site ID,Latitude,Longitude,Richness,Cell ID,Taxon,Genus\n")
				self.GBIFGeneric.WRITEEXPORT(OUTLfile,OUTLText,"Site ID,Latitude,Longitude,Cell ID,Taxon,Genus\n")
			#	self.GBIFGeneric.WRITEEXPORT(OUTSfile,OUTSText,"Sequence ID,Site ID,CellLat,CellLong,Taxon,Genus,TrueLat,TrueLong,Count,AllRecords\n")
				self.GBIFGeneric.WRITEEXPORT(OUTSfile,OUTSText,"Sequence ID,Site ID,Taxon,Genus,TrueLat,TrueLong,Count,AllRecords\n")
				description = self.__description__.encode('utf-8')
				self.GBIFGeneric.WRITEEXPORT(OUTDfile,description,"")
			dlg.Destroy()
		else:
			wx.MessageBox("Please make a successful GBIF Query first.")
	
	#	Add Data from Results Table to ID List
	def OnAdd(self,event):
		i=0
		IDCount = self.m_IDList.GetCount()
		for index in self.m_Result.GetSelections():
			selected = self.m_Result.GetString(index)
			split = selected.split(" | ")
			if (int(split[0]),split[1]) not in self.__selectedTaxon__:
				self.m_IDList.InsertItems(["%s" % selected],IDCount+i)
				self.__selectedTaxon__.add((int(split[0]),split[1]))
				i+=1
			
	#	Remove Data from ID List
	def OnRemove(self,event):
		candidates = sorted(self.m_IDList.GetSelections(),reverse=True)
		for index in candidates:
			selected = self.m_IDList.GetString(index)
			split = selected.split(" | ")
			self.__selectedTaxon__.remove((int(split[0]),split[1]))
			self.m_IDList.Delete(index)
	
	#	Close the Plugin
	def OnClose(self, event):
		# remove plotted lines
		for id in self.graphicalElementIds:
			GenGIS.graphics.RemoveLine(id)

		GenGIS.viewport.Refresh()
		event.Skip()
	
	#	Close the Plugin
	def OnOK( self, event ):
		self.Close()	
		
	def OnLatEnter(self,event):
		str = event.GetString()
		str2 = re.sub('[^\d\.\-]','',str)
		if str2 and str !="-":
			str3=float(str2)
			if str3 > 90:
				str2 = str2[:-1]
			elif str3 < -90:
				str2 = str2[:-1]
		event.GetClientData().SetValue(str2)
		event.GetClientData().SetInsertionPoint(len(str2))
		
	def OnLonEnter(self,event):
		str = event.GetString()
		str2 = re.sub('[^\d\.\-]','',str)
		if str2 and str !="-":
			str3=float(str2)
			if str3 > 180:
				str2 = str[:-1]
			elif str3 < -180:
				str2 = str[:-1]
		event.GetClientData().SetValue(str2)
		event.GetClientData().SetInsertionPoint(len(str2))
		
		
		
Esempio n. 5
0
    def __init__(self, parent=None):
        MaxLon, MinLon, MaxLat, MinLat = 180, -180, 90, -90
        self.GBIFSpecific = GBIFSpecific()
        self.GBIFGeneric = GBIFGeneric()
        GBIFQueryLayout.__init__(self, parent)
        self.SetIcon(
            wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",
                    wx.BITMAP_TYPE_ICO))
        self.m_Compass.SetIcon(
            wx.Icon(
                GenGIS.mainWindow.GetExeDir() +
                "images/GBIF_compass_small.png", wx.BITMAP_TYPE_PNG))
        self.m_Add.SetBitmapLabel(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Add.SetBitmapHover(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() +
                "images/green_arrow_down_hover.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Remove.SetBitmapLabel(
            wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",
                     wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Remove.SetBitmapHover(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() +
                "images/red_arrow_up_hover.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())

        self.graphicalElementIds = []
        self.__selectedTaxon__ = set()
        self.__obs__ = []
        self.m_IDList.Clear()
        #fix to expand summary box enough to print two lines of text properly
        self.m_Summary.SetLabel("\n\n")

        #No Map Data
        self.m_AddData.Disable()

        #Map Data
        if GenGIS.layerTree.GetNumMapLayers() > 0:
            self.m_AddData.Enable()
            borders = GenGIS.layerTree.GetMapLayer(
                0).GetController().GetMapBorders()
            #check if geographic coordinates are used or some other measure; only geographic are compatible
            geographic = GenGIS.StudyController.IsUsingGeographic(
                GenGIS.study.GetController())
            projected = GenGIS.StudyController.IsUsingProjection(
                GenGIS.study.GetController())
            if (not (geographic or projected)):
                wx.MessageBox(
                    "Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with MG-RAST. Geographic range will need to be manually set, and any returned data will not display correctly.",
                    "Warning")
                self.m_AddData.Disable()
                self.m_MinLat.SetValue(str(MinLat))
                self.m_MaxLat.SetValue(str(MaxLat))
                self.m_MinLon.SetValue(str(MinLon))
                self.m_MaxLon.SetValue(str(MaxLon))
            else:
                #Text boxes hate non String types. use int to round, and string to make them fit the container

                # if projected coordinates but not geographic, a conversion may be possible
                if (projected and not geographic):
                    convTop = self.GBIFGeneric.SpecialUTMConversion(
                        borders.x1, borders.y1)
                    convBottom = self.GBIFGeneric.SpecialUTMConversion(
                        borders.dx, borders.dy)
                    borders.x1 = convTop.easting
                    borders.y1 = convTop.northing
                    borders.dx = convBottom.easting
                    borders.dy = convBottom.northing
                #limiting borders
                self.m_MinLat.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MinLat, borders.y1, max)))
                self.m_MaxLat.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MaxLat, borders.dy, min)))
                self.m_MinLon.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MinLon, borders.x1, max)))
                self.m_MaxLon.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MaxLon, borders.dx, min)))
Esempio n. 6
0
class GBIFQuery(GBIFQueryLayout):
    #	Global variables to store queried information
    __obs__ = []
    __selectedTaxon__ = set()
    __description__ = ""
    masterKeys = set()

    def __init__(self, parent=None):
        MaxLon, MinLon, MaxLat, MinLat = 180, -180, 90, -90
        self.GBIFSpecific = GBIFSpecific()
        self.GBIFGeneric = GBIFGeneric()
        GBIFQueryLayout.__init__(self, parent)
        self.SetIcon(
            wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",
                    wx.BITMAP_TYPE_ICO))
        self.m_Compass.SetIcon(
            wx.Icon(
                GenGIS.mainWindow.GetExeDir() +
                "images/GBIF_compass_small.png", wx.BITMAP_TYPE_PNG))
        self.m_Add.SetBitmapLabel(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Add.SetBitmapHover(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() +
                "images/green_arrow_down_hover.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Remove.SetBitmapLabel(
            wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",
                     wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Remove.SetBitmapHover(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() +
                "images/red_arrow_up_hover.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())

        self.graphicalElementIds = []
        self.__selectedTaxon__ = set()
        self.__obs__ = []
        self.m_IDList.Clear()
        #fix to expand summary box enough to print two lines of text properly
        self.m_Summary.SetLabel("\n\n")

        #No Map Data
        self.m_AddData.Disable()

        #Map Data
        if GenGIS.layerTree.GetNumMapLayers() > 0:
            self.m_AddData.Enable()
            borders = GenGIS.layerTree.GetMapLayer(
                0).GetController().GetMapBorders()
            #check if geographic coordinates are used or some other measure; only geographic are compatible
            geographic = GenGIS.StudyController.IsUsingGeographic(
                GenGIS.study.GetController())
            projected = GenGIS.StudyController.IsUsingProjection(
                GenGIS.study.GetController())
            if (not (geographic or projected)):
                wx.MessageBox(
                    "Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with MG-RAST. Geographic range will need to be manually set, and any returned data will not display correctly.",
                    "Warning")
                self.m_AddData.Disable()
                self.m_MinLat.SetValue(str(MinLat))
                self.m_MaxLat.SetValue(str(MaxLat))
                self.m_MinLon.SetValue(str(MinLon))
                self.m_MaxLon.SetValue(str(MaxLon))
            else:
                #Text boxes hate non String types. use int to round, and string to make them fit the container

                # if projected coordinates but not geographic, a conversion may be possible
                if (projected and not geographic):
                    convTop = self.GBIFGeneric.SpecialUTMConversion(
                        borders.x1, borders.y1)
                    convBottom = self.GBIFGeneric.SpecialUTMConversion(
                        borders.dx, borders.dy)
                    borders.x1 = convTop.easting
                    borders.y1 = convTop.northing
                    borders.dx = convBottom.easting
                    borders.dy = convBottom.northing
                #limiting borders
                self.m_MinLat.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MinLat, borders.y1, max)))
                self.m_MaxLat.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MaxLat, borders.dy, min)))
                self.m_MinLon.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MinLon, borders.x1, max)))
                self.m_MaxLon.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MaxLon, borders.dx, min)))

    #	Query GBIF for Taxa in Lat/Lon Boundary
    def OnSearch(self, event):
        wx.BeginBusyCursor()
        #	Clear the results list
        self.m_Result.Clear()

        taxon = self.m_TaxonName.GetLineText(0)
        taxon = taxon.split()
        if (len(taxon) == 0):
            wx.MessageBox("You did not enter a taxon name.")
        else:
            minLatitude = float(self.m_MinLat.GetValue())
            maxLatitude = float(self.m_MaxLat.GetValue())
            minLongitude = float(self.m_MinLon.GetValue())
            maxLongitude = float(self.m_MaxLon.GetValue())
            result = self.GBIFSpecific.GETTAXRESULT(taxon, self.m_Result)
            self.m_Result.InsertItems(result, 0)
        wx.EndBusyCursor()

    #	Create Sequence and Location files for selected Taxa
    def OnCalculate(self, event):
        self.m_Summary.SetLabel("\n")
        records, distLocations = 0, 0
        self.__obs__ = []
        self.__conversions__ = []
        self.__description__ = ""
        wx.BeginBusyCursor()
        if (self.__selectedTaxon__):
            minLatitude = float(self.m_MinLat.GetValue())
            maxLatitude = float(self.m_MaxLat.GetValue())
            minLongitude = float(self.m_MinLon.GetValue())
            maxLongitude = float(self.m_MaxLon.GetValue())
            self.m_Progress.WriteText("Starting...\n")
            for tax in self.__selectedTaxon__:
                obs, self.masterKeys, records = self.GBIFSpecific.GETOBSENTIRERANGE(
                    tax[0], minLatitude, maxLatitude, minLongitude,
                    maxLongitude, self.m_Progress)
                self.__obs__.append(obs)
                distLocations += len(obs)
            self.m_Progress.WriteText("Done.\n")
        else:
            wx.MessageBox("Please select some Taxa.")
        summaryText = ("%d records retrieved.\n%d distinct locations." %
                       (records, distLocations))
        f = self.m_Summary.GetFont()
        dc = wx.WindowDC(self.m_Summary)
        dc.SetFont(f)
        aSize = dc.GetMultiLineTextExtent(summaryText)
        aSize = wx.Size(aSize[0], aSize[1])
        self.m_Summary.SetSize(aSize)

        self.m_Summary.SetLabel(summaryText)
        wx.EndBusyCursor()

    #	Present the number of locations a user is about to query
    #	Used as a check by the user to know they aren't going to produce way too much data.
    def OnPreCalculate(self, event):
        wx.BeginBusyCursor()
        self.m_Progress.WriteText("Retrieving record counts.\n")
        self.m_Summary.SetLabel("\n")
        if (self.__selectedTaxon__):
            count = 0
            for tax in self.__selectedTaxon__:
                count += self.GBIFSpecific.GETCOUNT(tax[1].split(), tax[0],
                                                    self.m_Progress)
            self.m_Summary.SetLabel(
                "There were %d records for the given location." % count)
        else:
            wx.MessageBox("Please select some Taxa.")
        wx.EndBusyCursor()

    #	Redirects User to Wiki page for this plugin
    def OnHelp(self, event):
        wx.LaunchDefaultBrowser(
            'http://kiwi.cs.dal.ca/GenGIS/index.php/Description_of_GenGIS_plugins#GBIF_Query'
        )

    #	Adds Data to GenGIS
    def OnAddData(self, event):
        if (len(self.__obs__) > 0):
            OUTLText, OUTSText = self.GBIFGeneric.GETTEXT(
                self.__obs__, self.masterKeys)
            OUTLArray = self.GBIFGeneric.CPPOUT(OUTLText)
            OUTSArray = self.GBIFGeneric.CPPOUT(OUTSText)
            OUTLArray.pop()
            OUTSArray.pop()
            layerName = "GBIFLayer_%d" % GenGIS.layerTree.GetNumLocationSetLayers(
            )
            GenGIS.mainWindow.OpenLocationsCSVFile(OUTLArray, layerName)
            GenGIS.mainWindow.OpenSequenceCSVFile(OUTSArray, layerName)

            #Get the number of last location layer added (the gbif one)
            numLocationLayers = GenGIS.layerTree.GetNumLocationSetLayers()
            locationSetLayer = GenGIS.layerTree.GetLocationSetLayer(
                numLocationLayers - 1)
        else:
            wx.MessageBox("Please make a successful GBIF Query first.")

    #	Exports Location and Sequence Data to a location of the users choice
    def OnExportData(self, event):
        if (len(self.__obs__) > 0):
            fileTypes = 'Loc and Seq Files (*.csv)|*.csv'
            dlg = wx.FileDialog(self, "Save plot", "", "", fileTypes, wx.SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                filename = dlg.GetFilename()
                dir = dlg.GetDirectory()
                file_split = filename.split(".", 1)
                #creates the directories
                OUTLfile = os.path.join(dir, file_split[0] + "_locs.csv")
                OUTSfile = os.path.join(dir, file_split[0] + "_seqs.csv")

                OUTLText, OUTSText = self.GBIFGeneric.GETTEXT(
                    self.__obs__, self.masterKeys)
                self.GBIFGeneric.WRITEEXPORT(OUTLfile, OUTLText)
                self.GBIFGeneric.WRITEEXPORT(OUTSfile, OUTSText)
            dlg.Destroy()
        else:
            wx.MessageBox("Please make a successful GBIF Query first.")

    #	Add Data from Results Table to ID List
    def OnAdd(self, event):
        i = 0
        IDCount = self.m_IDList.GetCount()
        for index in self.m_Result.GetSelections():
            selected = self.m_Result.GetString(index)
            split = selected.split(" | ")
            if (int(split[0]), split[1]) not in self.__selectedTaxon__:
                self.m_IDList.InsertItems(["%s" % selected], IDCount + i)
                self.__selectedTaxon__.add((int(split[0]), split[1]))
                i += 1

    #	Remove Data from ID List
    def OnRemove(self, event):
        candidates = sorted(self.m_IDList.GetSelections(), reverse=True)
        for index in candidates:
            selected = self.m_IDList.GetString(index)
            split = selected.split(" | ")
            self.__selectedTaxon__.remove((int(split[0]), split[1]))
            self.m_IDList.Delete(index)

    #	Close the Plugin
    def OnClose(self, event):
        # remove plotted lines
        for id in self.graphicalElementIds:
            GenGIS.graphics.RemoveLine(id)

        GenGIS.viewport.Refresh()
        event.Skip()

    #	Close the Plugin
    def OnOK(self, event):
        self.Close()

    def OnLatEnter(self, event):
        str = event.GetString()
        str2 = re.sub('[^\d\.\-]', '', str)
        if str2 and str != "-":
            str3 = float(str2)
            if str3 > 90:
                str2 = str2[:-1]
            elif str3 < -90:
                str2 = str2[:-1]
        event.GetClientData().SetValue(str2)
        event.GetClientData().SetInsertionPoint(len(str2))

    def OnLonEnter(self, event):
        str = event.GetString()
        str2 = re.sub('[^\d\.\-]', '', str)
        if str2 and str != "-":
            str3 = float(str2)
            if str3 > 180:
                str2 = str[:-1]
            elif str3 < -180:
                str2 = str[:-1]
        event.GetClientData().SetValue(str2)
        event.GetClientData().SetInsertionPoint(len(str2))
Esempio n. 7
0
class IRIDA(IRIDAQueryLayout):
	#baseURL =  "https://irida.corefacility.ca/irida-public-test/irida-api/"
	#baseURL =  "https://irida.corefacility.ca/staging/api/"
	#baseURL =  "http://localhost:48888/irida/api/"
	baseURL =  "http://129.173.66.114:48888/irida/api/"
	
	#clientId = "gengis"
	clientId = ""
	# THIS NEEDS TO BE HIDDEN
	clientSecret = ""
	#clientSecret = "bledjijitFeOpEerichFeatsatHowGheibwenecWijWifciek/"
	username = ""
	password = ""
	service = ""
	token = ""
	selectedTaxon = set()
	# this will be a 1:1 mapping of Project Name to Unique ID
	projectMap = {}
	obs = []
	phylo = ""
	
	def __init__(self,parent=None):
		IRIDAQueryLayout.__init__(self,parent)
		self.GBIFGeneric = GBIFGeneric()
		self.login = Login(self)
		#self.credentials = Credentials()
		self.SetIcon(wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",wx.BITMAP_TYPE_ICO))
		self.m_Add.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Add.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapLabel(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		self.m_Remove.SetBitmapHover(wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up_hover.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		
		self.m_IDList.Clear()
		self.m_Search.Enable(False)
		self.m_Calc.Enable(False)
		#fix to expand summary box enough to print two lines of text properly
		
		#Map Data
		if GenGIS.layerTree.GetNumMapLayers() > 0 :
			self.m_AddData.Enable()
			borders = GenGIS.layerTree.GetMapLayer(0).GetController().GetMapBorders()
			#check if geographic coordinates are used or some other measure; only geographic are compatible
			geographic = GenGIS.StudyController.IsUsingGeographic(GenGIS.study.GetController())
			projected = GenGIS.StudyController.IsUsingProjection(GenGIS.study.GetController())
			if(not (geographic or projected)):
				wx.MessageBox("Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with MG-RAST. Geographic range will need to be manually set, and any returned data will not display correctly.","Warning")
				self.m_AddData.Disable()
		credential = Credentials(self,False)
		credential.OnCredentialClose("fake")
		
		# By this point the active credential should be loaded.
		if self.clientId and self.clientSecret:
			self.login.ShowModal()
	
	def ReLogin(self, event):
		self.login.ShowModal()
		# Bring the main IRIDA instance back to the foreground after running login.
		self.Raise()
	
	def SetClientID(self,ID):
		self.clientId = ID
		
	def SetClientSecret(self,secret):
		self.clientSecret = secret
	
	def HandleLinks(self, result, type):
		response = {}
		if type == 'label':
			response['label'] = '';
			
		links = result[type]
		for val in links:
			if type=='links':
				response[val['rel']] = val['href']
			elif type == 'label':
				response['label'] = response['label'] + val
			else:
				if 'name' in val:
					response[val['name']] = val
				elif 'sampleName' in val:
					response[val['sampleName']] = val
				
		return response
		
	def ngs_request(self, url, oauth_service, access_token,debug=False):
		session = oauth_service.get_session(access_token)
		# the raw json being fetched
		response = session.get(url)
	#	print response.text
		if debug:
			print response.text
		result = json.loads(response.text)
		return result
	
	def newick_request( self, url, oauth_service, access_token, debug = False):
		session = oauth_service.get_session(access_token)
		# the raw newick being fetched
		response = session.request("GET",url, True,headers={'Accept':'text/plain'})
		if debug:
			print response.text
		return response.text
	
	def decoder(self,returnDict):
	# NEEDS A WAY TO DETECT BAD PASSWORD
	#	print returnDict
	#	if "Error report" in returnDict:
	#		print "error occured"
	#		return {}
		iridaDict = ast.literal_eval(returnDict)

		if "error" in iridaDict.keys():
			wx.MessageBox(iridaDict['error_description'], iridaDict['error'])
			return None
		return iridaDict

	def GetOauthService(self):
		oauth_service = OAuth2Service(
		client_id = self.clientId,
		client_secret = self.clientSecret,
		name="irida",
		access_token_url = self.baseURL + "oauth/token",
		base_url=self.baseURL)
		return oauth_service

	def GetParams(self):
		params = {'data' : {'grant_type' : 'password',
			'client_id' : self.clientId,
			'client_secret' : self.clientSecret,
			'username' : self.username,
			'password' : self.password}}
		return params
		
	def GetToken(self):
		oauth_service = self.GetOauthService()
		params = self.GetParams()
	
		try:
		#	print "sandwich"
			access_token = oauth_service.get_access_token(decoder = self.decoder,**params)
		#	print "banana"
			
		except:
			return None, None
		session = oauth_service.get_session(access_token)
		return oauth_service, access_token

	# Type is either RESOURCES or LINKS
	def GetResponse(self, url, oauth_service, access_token, type, debug=False):
		result = self.ngs_request(url, oauth_service, access_token, debug)
		if debug:
			print "#########\n\n",result,"\n\n#########"
		response = {}
		try:
			# parse out the response from the server
			response = self.HandleLinks(result['resource'],type)
		except ValueError:
			print "Server replied but reponse is in an unsupported format."
			sys.exit(1)
		return response
	
	# Formates a lat/lon into one string with 2 decimal places
	def FormatLocation(self, value):
		lat = value['latitude']
		lon = value['longitude']
		if lat != None and lon != None:
			loc = '%.2f_%.2f'%(float(lat),float(lon))
			return lon,lat,loc
		else:
			loc = '0_0'
			return 0,0,loc
			
	#Given All samples create a set of unique locations and the sequences that belong to them
	#Returns a dictionary of this information
	def CreateLocations(self, samples):
		idNum = 1
		idString = 'Loc_'
		locations = {}
		for sample in samples:
			for key, value in sample.items():
				lon,lat,loc = self.FormatLocation(value)
				id = idString + '%0*d' %(3,idNum)
				idNum += 1
				if loc in locations:
					locations[loc].append(key)
				else:
					locations[loc] = [id, lon, lat, key]
		return locations
		
	def CreateOutText(self, locations, samples):
		locationText = ""
		sequenceText = ""
		locationHeader = "Site ID, Longitude, Latitude\n"
		sequencesHeader = ["Sequence ID, Site ID "]
		first = True
		#first create locations
		for key, value in locations.items():
			locationText = '%s%s, %s, %s\n' %( locationText, value[0], value[1], value[2] ) 
		locationText = locationHeader + locationText
		
		#then create sequences
		for sample in samples:
			for key, values in sample.items():
				seq = []			
				#Append Sequence ID
				seq.append(key)
				#Append Site ID
			#	seq.append('Seq_%0*d' %(3, idNum) )
				lon,lat,loc = self.FormatLocation(values)
				seq.append(locations[loc][0])
				for i,j in values.items():
					if i == 'links':
						continue
					if first:
						sequencesHeader.append(str(i))
					seq.append(str(j).replace(',','|'))
				first = False
				text = ','.join(seq)
				sequenceText = sequenceText + text + '\n'
		
		sequenceHeader = ','.join(sequencesHeader)
		sequenceText = sequenceHeader + '\n' + sequenceText
		return locationText, sequenceText
		
	def OnHelp(self, event):
		wx.LaunchDefaultBrowser( 'http://kiwi.cs.dal.ca/GenGIS/index.php/Description_of_GenGIS_plugins#MG-RAST_Query' )
	#	Close the Plugin
	def OnClose(self, event):
		if self.login:
			self.login.Close()
		event.Skip()
	
	#	Close the Plugin
	def OnOK( self, event ):
		self.Close()

	#	Add Data from Results Table to ID List
	def OnAdd(self,event):
		i=0
		IDCount = self.m_IDList.GetCount()
		for index in self.m_Result.GetSelections():
			selected = self.m_Result.GetString(index)
			split = selected.split(": ")
			if (split[0],split[1]) not in self.selectedTaxon:
				self.m_IDList.InsertItems(["%s" % selected],IDCount+i)
				#add study ID and study location
				self.selectedTaxon.add((split[0],split[1]))
				i+=1
			
	#	Remove Data from ID List
	def OnRemove(self,event):
		candidates = sorted(self.m_IDList.GetSelections(),reverse=True)
		for index in candidates:
			selected = self.m_IDList.GetString(index)
			split = selected.split(": ")
			self.selectedTaxon.remove((split[0],split[1]))
			self.m_IDList.Delete(index)
	
	# Retrieves token from IRIDA API. 
	def AuthorizeToken(self):
		if self.username == "" or self.password == "":
			wx.MessageBox("Please enter a username and/or password.")
			return 0
		if self.clientId == "" or self.clientSecret == "":
			wx.MessageBox("No Client Credentials have been loaded.")
			return -1
		try:
			self.service, self.token = self.GetToken()
			if self.service == None or self.token == None:
				wx.MessageBox("Bad username and/or password.")
				return 0
		except ValueError:
			wx.MessageBox("Unable to retrieve token from API at this time. Please try again later.")
			return 0
		return 1

	def InitializeResults(self):
		wx.BeginBusyCursor()
		result = []
		links = self.GetResponse(self.baseURL+'projects/', self.service, self.token,'resources')
		if len(links.keys())==0:
			wx.MessageBox("No Projects currently stored in IRIDA")
		else:
			for key,value in links.items():
				str = "%s: %s" %(key,value['projectDescription'])
				# add mapping for this project
				self.projectMap[key] = value['identifier']
				result.append(str)
			self.m_Result.InsertItems(result,self.m_Result.GetCount())
		wx.EndBusyCursor()
	
	def InitializeAnalyses(self):
		wx.BeginBusyCursor()
		result = []
		links = self.GetResponse(self.baseURL+'analysisSubmissions/', self.service, self.token,'resources')
		if len(links.keys())==0:
			wx.MessageBox("No analyses currently stored in IRIDA")
		else:
			for key,value in links.items():
				str = "%s: %s" %(key,value['label'])
				# add mapping for this project
				self.projectMap[key] = value['identifier']
				result.append(str)
			self.m_Result.InsertItems(result,self.m_Result.GetCount())
		wx.EndBusyCursor()
	
	def OnSearch(self,event):
		wx.BeginBusyCursor()
		#	Clear the results list
		projName = self.m_ProjectName.GetValue()
		if projName not in self.projectMap.keys():
			wx.EndBusyCursor()
			wx.MessageBox("Please enter a valid Project name.")
			return

		project = projName
		if(len(project)==0):
			wx.MessageBox("You did not enter a taxon name.")
		else:
			self.selectedTaxon.clear()
			self.selectedTaxon.add((project,"dummy value"))
			self.OnCalculate(wx.EVT_BUTTON)

		wx.EndBusyCursor()
	
	def OnCalculate( self, event):
		self.RetrieveSamples()
	#	self.RetrievePhylogeny()
		
#	def RetrieveSamples(self,event):
	def RetrieveSamples(self):
		if(self.selectedTaxon):
			#index of which taxon is being used
			index = 0
			for proj in self.selectedTaxon:
				self.m_Progress.WriteText("Retrieving %s...\n" %(proj[0]))
				project = self.projectMap[proj[0]]
			#	projectURL = '%sprojects/%s' %(self.baseURL,project)
				projectURL = '%sprojects/%s' %(self.baseURL,3)
				self.phylo = self.RetrieveKnownPhylogeny(project)
			#	print newick
				projLink = self.GetResponse(projectURL, self.service, self.token,'links')
				sampleURL = projLink['project/samples']
				samples = self.GetResponse(sampleURL, self.service, self.token, 'resources')
	
				# obs is just a list of these samples
				self.obs.append(samples)
				self.m_Progress.WriteText("%s samples retrieved.\n" %(len(samples.keys())))
				self.m_Progress.WriteText("Done.\n")
			
#	def RetrievePhylogeny(self,event):
	def RetrievePhylogeny(self):
		if(self.selectedTaxon):
			#index of which taxon is being used
			index = 0
			for proj in self.selectedTaxon:
				self.m_Progress.WriteText("Retrieving %s...\n" %(proj[0]))
				project = self.projectMap[proj[0]]
				projectURL = '%sanalysisSubmissions/%s' %(self.baseURL,project)
				print projectURL
				projLink = self.GetResponse(projectURL, self.service, self.token,'links')
				analysisURL = projLink['analysis']
				print analysisURL
				# get samples
				'''
				sequenceURL = analysisURL + "/sequenceFiles/pairs"
				print "pants"
				sequenceLink = self.GetResponse(projectURL, self.service, self.token, 'response',True)
				print "sandwich"
				'''
				
				# get phylogeny
				links = self.GetResponse(analysisURL, self.service, self.token, 'links')
				newickURL = links['outputFile/tree']
				newick = self.newick_request(newickURL, self.service,self.token,True)
	
				# obs is just a list of these samples
		#		self.obs.append(samples)
		
				self.m_Progress.WriteText("%s samples retrieved.\n" %(len(samples.keys())))
				self.m_Progress.WriteText("Done.\n")
		
	def RetrieveKnownPhylogeny(self, identifier):
		projectURL = '%sanalysisSubmissions/%s' %(self.baseURL,identifier)
		projLink = self.GetResponse(projectURL, self.service, self.token,'links')
		analysisURL = projLink['analysis']
		
		# get phylogeny
		links = self.GetResponse(analysisURL, self.service, self.token, 'links')
		newickURL = links['outputFile/tree']
		newick = self.newick_request(newickURL, self.service,self.token)
		return newick

	
	def OnAddData(self, event):
		if GenGIS.layerTree.GetNumMapLayers() == 0:
			wx.MessageBox("This action requires a Map layer. Please load a Map.")
			return
		if len(self.obs) > 0:
			loc = self.CreateLocations(self.obs)
			locText, seqText = self.CreateOutText(loc,self.obs)
			locArray = locText.split('\n')
			seqArray = seqText.split('\n')
			locArray.pop()
			seqArray.pop()
			layerName = "IRIDALayer_%d" % GenGIS.layerTree.GetNumLocationLayers()
			GenGIS.mainWindow.OpenLocationsCSVFile(locArray, layerName)
			GenGIS.mainWindow.OpenSequenceCSVFile(seqArray, layerName)
			print self.phylo
			self.phylo = self.phylo.replace("reference:0.00000001,","")
			print self.phylo
			fh = "phylogeny.nwk"
			file = open("phylogeny.nwk",'w')
			file.write(self.phylo)
			file.close()
			GenGIS.mainWindow.OpenTreeFile(fh)
		else:
			wx.MessageBox("Please make a successful IRIDA query first.")
			
	def OnExportData(self,event):
		if (len(self.obs) > 0):
			fileTypes = 'Loc and Seq Files (*.csv)|*.csv'
			dlg = wx.FileDialog(self, "Save plot", "", "", fileTypes, wx.SAVE)
			if dlg.ShowModal()==wx.ID_OK:
				filename =	dlg.GetFilename()
				dir = dlg.GetDirectory()
				file_split = filename.split(".",1)
				OUTLfile = os.path.join(dir,file_split[0]+"_locs.csv")		
				OUTSfile = os.path.join(dir,file_split[0]+"_seqs.csv")
				loc = self.CreateLocations(self.obs)
				locText, seqText = self.CreateOutText(loc,self.obs)
				self.GBIFGeneric.WRITEEXPORT(OUTLfile , locText )
				self.GBIFGeneric.WRITEEXPORT(OUTSfile, seqText )
				
	def SetToken(self,tok):
		self.token = tok
	
	def OnCredentials(self,event):
		credentials = Credentials(self)
		credentials.Show()

	def OnCredentialClose(self,active):
	#	self.credential = active
		self.clientId = active.GetID()
		self.clientSecret = active.GetSecret()
		
Esempio n. 8
0
class MGRastQuery(MGRASTQueryLayout):
    #	Global variables to store queried information
    __obs__ = []
    __selectedTaxon__ = set()
    __description__ = ""
    __options__ = ""
    __metaVals__ = {}
    __TAXON__ = [
        "Domain", "Phylum", "Class", "Order", "Family", "Genus", "Species",
        "Strain"
    ]

    def __init__(self, parent=None):
        self.__options__ = Options()
        self.MGRastSpecific = MGRastSpecific()
        MGRASTQueryLayout.__init__(self, parent)
        self.GBIFGeneric = GBIFGeneric()
        self.SetIcon(
            wx.Icon(GenGIS.mainWindow.GetExeDir() + "images/CrazyEye.ico",
                    wx.BITMAP_TYPE_ICO))
        self.m_Add.SetBitmapLabel(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() + "images/green_arrow_down.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Add.SetBitmapHover(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() +
                "images/green_arrow_down_hover.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Remove.SetBitmapLabel(
            wx.Image(GenGIS.mainWindow.GetExeDir() + "images/red_arrow_up.png",
                     wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Remove.SetBitmapHover(
            wx.Image(
                GenGIS.mainWindow.GetExeDir() +
                "images/red_arrow_up_hover.png",
                wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        self.m_Compass.SetIcon(
            wx.Icon(
                GenGIS.mainWindow.GetExeDir() +
                "images/GBIF_compass_small.png", wx.BITMAP_TYPE_PNG))
        MaxLon, MinLon, MaxLat, MinLat = 180, -180, 90, -90

        self.m_IDList.Clear()
        #fix to expand summary box enough to print two lines of text properly
        self.m_Summary.SetLabel("\n\n")

        #Map Data
        if GenGIS.layerTree.GetNumMapLayers() > 0:
            self.m_AddData.Enable()
            borders = GenGIS.layerTree.GetMapLayer(
                0).GetController().GetMapBorders()
            #check if geographic coordinates are used or some other measure; only geographic are compatible
            geographic = GenGIS.StudyController.IsUsingGeographic(
                GenGIS.study.GetController())
            projected = GenGIS.StudyController.IsUsingProjection(
                GenGIS.study.GetController())
            if (not (geographic or projected)):
                wx.MessageBox(
                    "Geographic coordinates are not being used in the current map file. Only geographic coordinates are compatible with MG-RAST. Geographic range will need to be manually set, and any returned data will not display correctly.",
                    "Warning")
                self.m_AddData.Disable()
                self.m_MinLat.SetValue(str(MinLat))
                self.m_MaxLat.SetValue(str(MaxLat))
                self.m_MinLon.SetValue(str(MinLon))
                self.m_MaxLon.SetValue(str(MaxLon))
            else:
                #Text boxes hate non String types. use int to round, and string to make them fit the container

                # if projected coordinates but not geographic, a conversion may be possible
                if (projected and not geographic):
                    convTop = self.GBIFGeneric.SpecialUTMConversion(
                        borders.x1, borders.y1)
                    convBottom = self.GBIFGeneric.SpecialUTMConversion(
                        borders.dx, borders.dy)
                    borders.x1 = convTop.easting
                    borders.y1 = convTop.northing
                    borders.dx = convBottom.easting
                    borders.dy = convBottom.northing
                #limiting borders
                self.m_MinLat.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MinLat, borders.y1, max)))
                self.m_MaxLat.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MaxLat, borders.dy, min)))
                self.m_MinLon.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MinLon, borders.x1, max)))
                self.m_MaxLon.SetValue(
                    str("%.1f" %
                        self.GBIFGeneric.BorderTest(MaxLon, borders.dx, min)))

    #	Query GBIF for Taxa in Lat/Lon Boundary
    def OnSearch(self, event):
        wx.BeginBusyCursor()
        #	Clear the results list
        self.m_Result.Clear()
        searchType = self.__options__.GetSearchType()
        taxon = self.m_TaxonName.GetLineText(0)
        taxon = taxon.split()
        if (len(taxon) == 0):
            wx.MessageBox("You did not enter a taxon name.")
        else:
            minLatitude = float(self.m_MinLat.GetValue())
            maxLatitude = float(self.m_MaxLat.GetValue())
            minLongitude = float(self.m_MinLon.GetValue())
            maxLongitude = float(self.m_MaxLon.GetValue())
            if searchType == "study":
                self.__selectedTaxon__.clear()
                #	test data for multiple study search mgm4440037.3 mgm4440055.3 mgm4440064.3
                for tax in taxon:
                    self.__selectedTaxon__.add(("dummy value", tax))
                self.OnCalculate(wx.EVT_BUTTON)
            else:
                matches = self.MGRastSpecific.GETTAXRESULT(
                    taxon, searchType, minLatitude, maxLatitude, minLongitude,
                    maxLongitude, self.m_Summary)
                if matches:
                    self.m_Result.InsertItems(matches, 0)
        wx.EndBusyCursor()

    #	Create Sequence and Location files for selected Taxa
    ######################
    #
    #	CAN NOT PERFORM MORE THAN ONE QUERY PER SECOND
    #
    ######################
    def OnCalculate(self, event):
        self.MGRastSpecific.RESETSEQUENCE()
        self.__obs__ = []
        self.__metaVals__ = {}
        sequence = {}
        self.m_Summary.SetLabel("\n")
        records, distLocations = 0, 0
        searchType = self.__options__.GetSearchType()
        additFields = "%s%s%s%s%s%s%s" % (
            self.__options__.GetFilterLevel(),
            self.__options__.GetFilterSource(),
            self.__options__.GetGroupLevel(), self.__options__.GetHitType(),
            self.__options__.GetIdentity(), self.__options__.GetLength(),
            self.__options__.GetSource())
        if (self.__selectedTaxon__):
            self.m_Progress.WriteText("Starting...\n")
            #index of which taxon is being used
            index = 0
            for tax in self.__selectedTaxon__:
                startTime = time.time()
                obs, metaVals, taxonLength = self.MGRastSpecific.GETOBS(
                    tax[1], searchType, additFields, self.m_Progress)
                # Some sort of error occured trying to get that object, skip to next one
                if not obs:
                    self.SetFocus()
                    continue
                taxonomy = []
                for i in range(0, taxonLength):
                    if i < len(self.__TAXON__):
                        taxonomy.append(self.__TAXON__[i])
                    else:
                        taxonomy[i].append("Level_%s" % i)
                self.__TAXON__ = taxonomy
                if obs:
                    self.__obs__.append(obs)
                if sequence:
                    self.__sequences__.append(sequence)
                # add all unique key/val pairs from json files
                for key, value in metaVals.iteritems():
                    if key in self.__metaVals__:
                        self.__metaVals__[key][index] = value
                    else:
                        list = [''] * len(self.__selectedTaxon__)
                        list[index] = value
                        self.__metaVals__[key] = list
                index += 1
                if (time.time() - startTime) < 1:
                    sleep.time(1)
                # Now query again for the Sequence to that study
                if self.__options__.GetSequence():
                    fileTypes = 'Sequence data files (*.fasta)|*.fasta'
                    dlg = wx.FileDialog(self, "Save plot", "", "", fileTypes,
                                        wx.SAVE)
                    if dlg.ShowModal() == wx.ID_OK:
                        filename = dlg.GetFilename()
                        dir = dlg.GetDirectory()
                        file_split = filename.split(".", 1)
                        outFile = ("%s/%s_sequenceData.fasta.gz" %
                                   (dir, file_split[0]))
                    self.MGRastSpecific.GETSEQUENCES(tax[1], self.m_Progress,
                                                     outFile)
        else:
            wx.MessageBox("Please select some Taxa.")
        self.m_Progress.WriteText("Done\n")

    #	Redirects User to Wiki page for this plugin
    def OnHelp(self, event):
        wx.LaunchDefaultBrowser(
            'http://kiwi.cs.dal.ca/GenGIS/index.php/Description_of_GenGIS_plugins#MG-RAST_Query'
        )

    #	Adds Data to GenGIS
    def OnAddData(self, event):
        # check required data has been loaded
        if GenGIS.layerTree.GetNumMapLayers() == 0:
            wx.MessageBox(
                "This action requires a Map layer. Please load a Map.")
            self.Close()
            return
        taxonLevels = ','.join(str(i) for i in self.__TAXON__)

        if (len(self.__obs__) > 0):
            OUTLText, OUTSText = self.MGRastSpecific.GETTEXT(
                self.__obs__, self.__metaVals__)
            OUTLArray = self.GBIFGeneric.CPPOUT(OUTLText)
            OUTSArray = self.GBIFGeneric.CPPOUT(OUTSText)
            metKey = ','.join(sorted(self.__metaVals__.keys()))
            OUTLArray.insert(0,
                             "Site ID,Latitude,Longitude,Cell ID,%s" % metKey)
            OUTSArray.insert(
                0,
                "Sequence ID,Site ID,CellLat,CellLong,Richness,%s,Taxonomy" %
                taxonLevels)
            OUTLArray.pop()
            OUTSArray.pop()
            layerName = "MGRASTLayer_%d" % GenGIS.layerTree.GetNumLocationLayers(
            )
            GenGIS.mainWindow.OpenLocationsCSVFile(OUTLArray, layerName)
            GenGIS.mainWindow.OpenSequenceCSVFile(OUTSArray, layerName)

            #Get the number of last location layer added (the gbif one)
            numLocationLayers = GenGIS.layerTree.GetNumLocationSetLayers()
            locationSetLayer = GenGIS.layerTree.GetLocationSetLayer(
                numLocationLayers - 1)
        #	locationSetLayer.SetDescription(self.__description__)

        else:
            wx.MessageBox("Please make a successful MG-RAST Query first.")

    #	Exports Location and Sequence Data to a location of the users choice
    def OnExportData(self, event):
        if (len(self.__obs__) > 0):
            taxonLevels = ','.join(str(i) for i in self.__TAXON__)
            fileTypes = 'Loc and Seq Files (*.csv)|*.csv'
            dlg = wx.FileDialog(self, "Save plot", "", "", fileTypes, wx.SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                filename = dlg.GetFilename()
                dir = dlg.GetDirectory()
                file_split = filename.split(".", 1)
                #creates the directories
                OUTLfile = os.path.join(dir, file_split[0] + "_locs.csv")
                OUTSfile = os.path.join(dir, file_split[0] + "_seqs.csv")
                OUTLText, OUTSText = self.MGRastSpecific.GETTEXT(
                    self.__obs__, self.__metaVals__)
                #	metKey = ','.join(str(x) for x in self.__metaKeys__)
                metKey = ','.join(sorted(self.__metaVals__.keys()))
                #	print metKey
                self.GBIFGeneric.WRITEEXPORT(
                    OUTLfile, OUTLText,
                    "Site ID,Latitude,Longitude,Cell ID,%s\n" % metKey)
                self.GBIFGeneric.WRITEEXPORT(
                    OUTSfile, OUTSText,
                    "Sequence ID,Site ID,CellLat,CellLong,Richness,%s,Taxonomy\n"
                    % taxonLevels)
            #	if self.__options__.GetSequence():
            #		self.MGRastSpecific.WRITESEQUENCES(dir,file_split[0],self.__sequences__)
            dlg.Destroy()
        else:
            wx.MessageBox("Please make a successful MG-RAST Query first.")

    #	Add Data from Results Table to ID List
    def OnAdd(self, event):
        i = 0
        IDCount = self.m_IDList.GetCount()
        for index in self.m_Result.GetSelections():
            selected = self.m_Result.GetString(index)
            split = selected.split(" | ")
            if (split[0], split[1]) not in self.__selectedTaxon__:
                self.m_IDList.InsertItems(["%s" % selected], IDCount + i)
                #add study ID and study location
                self.__selectedTaxon__.add((split[0], split[1]))
                i += 1

    #	Remove Data from ID List
    def OnRemove(self, event):
        candidates = sorted(self.m_IDList.GetSelections(), reverse=True)
        for index in candidates:
            selected = self.m_IDList.GetString(index)
            split = selected.split(" | ")
            self.__selectedTaxon__.remove((split[0], split[1]))
            self.m_IDList.Delete(index)

    #	Close the Plugin
    def OnClose(self, event):
        self.__options__.Close()
        event.Skip()

    #	Close the Plugin
    def OnOK(self, event):
        self.Close()
        self.__options__.Close()

    def OnLatEnter(self, event):
        str = event.GetString()
        str2 = re.sub('[^\d\.\-]', '', str)
        if str2 and str != "-":
            str3 = float(str2)
            if str3 > 90:
                str2 = str2[:-1]
            elif str3 < -90:
                str2 = str2[:-1]
        event.GetClientData().SetValue(str2)
        event.GetClientData().SetInsertionPoint(len(str2))

    def OnLonEnter(self, event):
        str = event.GetString()
        str2 = re.sub('[^\d\.\-]', '', str)
        if str2 and str != "-":
            str3 = float(str2)
            if str3 > 180:
                str2 = str[:-1]
            elif str3 < -180:
                str2 = str[:-1]
        event.GetClientData().SetValue(str2)
        event.GetClientData().SetInsertionPoint(len(str2))

    def OnOptions(self, event):
        self.__options__.Show()