[docs]defvalidate(self,all_morphos):self._cache_patterns()repo_names={m.get_meta()["name"]forminall_morphos}missing=[nforn,patinself._patterns.items()ifnotany(pat.match(rn)forrninrepo_names)]ifmissing:err="Morphology repository misses the following morphologies"ifself._config_parentisnotNone:node=self._config_parent._config_parenterr+=f" required by {node.get_node_name()}"err+=f": {', '.join(missing)}"raiseMissingMorphologyError(err)
[docs]@config.nodeclassNeuroMorphoSelector(NameSelector,classmap_entry="from_neuromorpho"):_url="http://cng.gmu.edu:8080/neuroMorpho/"# "https://neuromorpho.org/"_meta="api/neuron/select?q=neuron_name:"_files="dableFiles/"def__boot__(self):ifself.scaffold.is_main_process():try:morphos=self._scrape_nm(self.names)except:self.scaffold._comm.barrier()raiseforname,morphoinmorphos.items():self.scaffold.morphologies.save(name,morpho,overwrite=True)self.scaffold._comm.barrier()@classmethoddef_swc_url(cls,archive,name):return(f"{cls._url}{cls._files}{urllib.parse.quote(archive.lower())}/"f"CNG%20version/{name}.CNG.swc")@classmethoddef_scrape_nm(cls,names):# Weak DH key on neuromorpho.org# https://stackoverflow.com/questions/38015537/python-requests-exceptions-sslerror-dh-key-too-smallrequests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS+=":HIGH:!DH:!aNULL"# Pass if no pyopenssl support used / needed / availablewithcontextlib.suppress(AttributeError):requests.packages.urllib3.contrib.pyopenssl.util.ssl_.DEFAULT_CIPHERS+=(":HIGH:!DH:!aNULL")withwarnings.catch_warnings():warnings.simplefilter("ignore")withThreadPoolExecutor()asexecutor:# Certificate issues with neuromorpho --> verify=Falseres=requests.get(cls._url+cls._meta+",".join(names),verify=False)ifres.status_code==404:raiseSelectorError(f"'{names[0]}' is not a valid NeuroMorpho name.")elifres.status_code!=200:raiseSelectorError("NeuroMorpho API error: "+res.message)metas={n:Noneforninnames}formetainres.json()["_embedded"]["neuronResources"]:delmeta["_links"]metas[meta["neuron_name"]]=metamissing=[nameforname,metainmetas.items()ifmetaisNone]ifmissing:raiseSelectorError(", ".join(f"'{n}'"forninmissing)+" are not valid NeuroMorpho names.")swc_urls={n:cls._swc_url(metas[n]["archive"],n)forninnames}defreq(n):returnrequests.get(swc_urls[n],verify=False)defsub(n):returnexecutor.submit(req,n),nfutures=dict(map(sub,names))morphos={n:Noneforninnames}withtempfile.TemporaryDirectory()astempdir:forfutureinconcurrent.futures.as_completed(futures.keys()):name=futures[future]path=tempdir+f"/{name}.swc"withopen(path,"w")asf:f.write(future.result().text)morphos[name]=Morphology.from_swc(path,meta=metas[name])missing=[nameforname,minmorphos.items()ifmisNone]ifmissing:# pragma: nocoverraiseSelectorError("Downloading NeuroMorpho failed for "+", ".join(f"'{n}'"forninmissing)+".")returnmorphos