bugfixes for TCS Import
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / tcsxml / in / TcsXmlTaxonNameImport.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.io.tcsxml.in;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.List;
15
16 import org.apache.commons.lang.StringUtils;
17 import org.apache.log4j.Logger;
18 import org.jdom.Element;
19 import org.jdom.Namespace;
20 import org.springframework.stereotype.Component;
21
22 import eu.etaxonomy.cdm.common.ResultWrapper;
23 import eu.etaxonomy.cdm.common.XmlHelp;
24 import eu.etaxonomy.cdm.io.common.ICdmIO;
25 import eu.etaxonomy.cdm.io.common.ImportHelper;
26 import eu.etaxonomy.cdm.io.common.MapWrapper;
27 import eu.etaxonomy.cdm.io.tcsxml.TcsXmlTransformer;
28 import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
29 import eu.etaxonomy.cdm.model.agent.Person;
30 import eu.etaxonomy.cdm.model.agent.Team;
31 import eu.etaxonomy.cdm.model.name.CultivarPlantName;
32 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
33 import eu.etaxonomy.cdm.model.name.NonViralName;
34 import eu.etaxonomy.cdm.model.name.Rank;
35 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
36 import eu.etaxonomy.cdm.model.name.ZoologicalName;
37 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
38 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
39 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
40
41 @Component("tcsXmlTaxonNameIO")
42 public class TcsXmlTaxonNameImport extends TcsXmlImportBase implements ICdmIO<TcsXmlImportState> {
43 private static final Logger logger = Logger.getLogger(TcsXmlTaxonNameImport.class);
44
45 private static int modCount = 5000;
46
47 public TcsXmlTaxonNameImport(){
48 super();
49 }
50
51 @Override
52 public boolean doCheck(TcsXmlImportState state){
53 boolean result = true;
54 logger.warn("BasionymRelations not yet implemented");
55 logger.warn("Checking for TaxonNames not yet implemented");
56 //result &= checkArticlesWithoutJournal(tcsConfig);
57 //result &= checkPartOfJournal(tcsConfig);
58
59 return result;
60 }
61
62 //@SuppressWarnings("unchecked")
63 @Override
64 public boolean doInvoke(TcsXmlImportState state){
65
66 logger.info("start make TaxonNames ...");
67 MapWrapper<Person> authorMap = (MapWrapper<Person>)state.getStore(ICdmIO.TEAM_STORE);
68 MapWrapper<TaxonNameBase> taxonNameMap = (MapWrapper<TaxonNameBase>)state.getStore(ICdmIO.TAXONNAME_STORE);
69 MapWrapper<ReferenceBase> referenceMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.REFERENCE_STORE);
70
71 ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
72 String childName;
73 boolean obligatory;
74 String idNamespace = "TaxonName";
75
76 TcsXmlImportConfigurator config = state.getConfig();
77 Element elDataSet = getDataSetElement(config);
78 Namespace tcsNamespace = config.getTcsXmlNamespace();
79
80 childName = "TaxonNames";
81 obligatory = false;
82 Element elTaxonNames = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
83
84 String tcsElementName = "TaxonName";
85 List<Element> elTaxonNameList = (List<Element>)elTaxonNames.getChildren(tcsElementName, tcsNamespace);
86
87 int i = 0;
88 //for each taxonName
89 for (Element elTaxonName : elTaxonNameList){
90 if ((++i % modCount) == 0){ logger.info("Names handled: " + (i-1));}
91 List<String> elementList = new ArrayList<String>();
92
93 //create TaxonName element
94 String strId = elTaxonName.getAttributeValue("id");
95 String strNomenclaturalCode = elTaxonName.getAttributeValue("nomenclaturalCode");
96
97 childName = "Rank";
98 obligatory = false;
99 Element elRank = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
100 Rank rank = makeRank(elRank);
101 elementList.add(childName.toString());
102
103
104 try {
105 TaxonNameBase<?,?> nameBase;
106 NomenclaturalCode nomCode = TcsXmlTransformer.nomCodeString2NomCode(strNomenclaturalCode);
107 if (nomCode != null){
108 nameBase = nomCode.getNewTaxonNameInstance(rank);
109 }else{
110 nameBase = NonViralName.NewInstance(rank);
111 }
112 childName = "Simple";
113 obligatory = true;
114 Element elSimple = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
115 String simple = (elSimple == null)? "" : elSimple.getTextNormalize();
116 nameBase.setTitleCache(simple, false);
117 elementList.add(childName.toString());
118
119 childName = "CanonicalName";
120 obligatory = false;
121 Element elCanonicalName = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
122 makeCanonicalName(nameBase, elCanonicalName, taxonNameMap, success);
123 elementList.add(childName.toString());
124
125 childName = "CanonicalAuthorship";
126 obligatory = false;
127 Element elCanonicalAuthorship = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
128 makeCanonicalAuthorship(nameBase, elCanonicalAuthorship, authorMap, success);
129 elementList.add(childName.toString());
130
131 childName = "PublishedIn";
132 obligatory = false;
133 Element elPublishedIn = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
134 makePublishedIn(nameBase, elPublishedIn, referenceMap, success);
135 elementList.add(childName.toString());
136
137 childName = "Year";
138 obligatory = false;
139 Element elYear = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
140 makeYear(nameBase, elYear, success);
141 elementList.add(childName.toString());
142
143 childName = "MicroReference";
144 obligatory = false;
145 Element elMicroReference = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
146 makeMicroReference(nameBase, elMicroReference, success);
147 elementList.add(childName.toString());
148
149 childName = "Typification";
150 obligatory = false;
151 Element elTypification = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
152 makeTypification(nameBase, elTypification, success);
153 elementList.add(childName.toString());
154
155 childName = "PublicationStatus";
156 obligatory = false;
157 Element elPublicationStatus = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
158 makePublicationStatus(nameBase, elPublicationStatus, success);
159 elementList.add(childName.toString());
160
161 childName = "ProviderLink";
162 obligatory = false;
163 Element elProviderLink = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
164 makeProviderLink(nameBase, elProviderLink, success);
165 elementList.add(childName.toString());
166
167 childName = "ProviderSpecificData";
168 obligatory = false;
169 Element elProviderSpecificData = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
170 makeProviderSpecificData(nameBase, elProviderSpecificData, success);
171 elementList.add(childName.toString());
172
173
174 ImportHelper.setOriginalSource(nameBase, config.getSourceReference(), strId, idNamespace);
175
176 taxonNameMap.put(strId, nameBase);
177
178 } catch (UnknownCdmTypeException e) {
179 logger.warn("Name with id " + strId + " has unknown nomenclatural code.");
180 success.setValue(false);
181 }
182 }
183 logger.info(i + " names handled");
184 Collection<? extends TaxonNameBase> col = taxonNameMap.objects();
185 getNameService().save((Collection)col);
186
187 logger.info("end makeTaxonNames ...");
188 return success.getValue();
189
190 }
191
192 /**
193 * Returns the rank represented by the rank element.<br>
194 * Returns <code>null</code> if the element is null.<br>
195 * Returns <code>null</code> if the code and the text are both either empty or do not exists.<br>
196 * Returns the rank represented by the code attribute, if the code attribute is not empty and could be resolved.<br>
197 * If the code could not be resolved it returns the rank represented most likely by the elements text.<br>
198 * Returns UNKNOWN_RANK if code attribute and element text could not be resolved.
199 * @param elRank tcs rank element
200 * @return
201 */
202 protected static Rank makeRank(Element elRank){
203 Rank result;
204 if (elRank == null){
205 return null;
206 }
207 String strRankCode = elRank.getAttributeValue("code");
208 String strRankString = elRank.getTextNormalize();
209 if (strRankCode == null || "".equals(strRankCode.trim()) &&
210 strRankString == null || "".equals(strRankString.trim())
211 ){
212 return null;
213 }
214
215 Rank codeRank = null;
216 try {
217 codeRank = TcsXmlTransformer.rankCode2Rank(strRankCode);
218 } catch (UnknownCdmTypeException e1) {
219 codeRank = Rank.UNKNOWN_RANK();
220 }
221 Rank stringRank = null;
222 try {
223 boolean useUnknown = true;
224 stringRank = Rank.getRankByNameOrAbbreviation(strRankString, useUnknown);
225 } catch (UnknownCdmTypeException e1) {
226 //does not happen because of useUnknown = true
227 }
228
229 //codeRank exists
230 if (! (codeRank == null) && ! codeRank.equals(Rank.UNKNOWN_RANK())){
231 result = codeRank;
232 if (! codeRank.equals(stringRank) && ! stringRank.equals(Rank.UNKNOWN_RANK())){
233 logger.warn("code rank and string rank are unequal. code: " + codeRank.getLabel() + stringRank.getLabel());
234 }
235 }
236 //codeRank does not exist
237 else{
238 result = stringRank;
239 logger.warn("string rank used, because code rank does not exist or was not recognized: " + stringRank.getLabel());
240 }
241 return result;
242 }
243
244 private void makeCanonicalName(TaxonNameBase name, Element elCanonicalName, MapWrapper<TaxonNameBase> taxonNameMap, ResultWrapper<Boolean> success){
245 boolean cacheProtected = false;
246
247 if (elCanonicalName == null){
248 return;
249 }
250 Namespace ns = elCanonicalName.getNamespace();
251
252 String childName = "Simple";
253 boolean obligatory = true;
254 Element elSimple = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
255 String simple = (elSimple == null)? "" : elSimple.getTextNormalize();
256 name.setFullTitleCache(simple, cacheProtected);
257
258 if (name instanceof NonViralName<?>){
259 NonViralName<?> nonViralName = (NonViralName<?>)name;
260 childName = "Uninomial";
261 obligatory = false;
262 Element elUninomial = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
263 String uninomial = (elUninomial == null)? "" : elUninomial.getTextNormalize();
264 if (StringUtils.isNotBlank(uninomial)){
265 nonViralName.setGenusOrUninomial(uninomial);
266 if (nonViralName.getRank() != null && nonViralName.getRank().isLower(Rank.GENUS())){ // TODO check
267 logger.warn("Name " + simple + " lower then 'genus' but has a canonical name part 'Uninomial'.");
268 }
269 }
270 testNoMoreElements();
271
272 childName = "Genus";
273 obligatory = false;
274 Element elGenus = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
275 if (elGenus != null){
276 //TODO do Attributes reference
277 makeGenusReferenceType(name, elGenus, taxonNameMap, success);
278 String genus = elGenus.getTextNormalize();
279 if (StringUtils.isNotBlank(genus)){
280 nonViralName.setGenusOrUninomial(genus);
281 if (nonViralName.getRank() != null && ! nonViralName.getRank().isLower(Rank.GENUS() )){ // TODO check
282 logger.warn("Name " + simple + " is not lower then 'genus' but has canonical name part 'Genus'.");
283 }
284 }
285 }
286
287 childName = "InfragenericEpithet";
288 obligatory = false;
289 Element elInfrageneric = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
290 String infraGenericEpithet = (elInfrageneric == null)? "" : elInfrageneric.getTextNormalize();
291 if (! infraGenericEpithet.trim().equals("")){
292 nonViralName.setInfraGenericEpithet(infraGenericEpithet);
293 if (nonViralName.getRank() != null && ! name.getRank().isInfraGeneric()){
294 logger.warn("Name " + simple + " is not infra generic but has canonical name part 'InfragenericEpithet'.");
295 }
296 }
297 testNoMoreElements();
298
299 childName = "SpecificEpithet";
300 obligatory = false;
301 Element elSpecificEpithet = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
302 String specificEpithet = (elSpecificEpithet == null)? "" : elSpecificEpithet.getTextNormalize();
303 if (! specificEpithet.trim().equals("")){
304 nonViralName.setSpecificEpithet(specificEpithet);
305 if (nonViralName.getRank() != null && name.getRank().isHigher(Rank.SPECIES()) ){
306 logger.warn("Name " + simple + " is not species or below but has canonical name part 'SpecificEpithet'.");
307 }
308 }
309 testNoMoreElements();
310
311 childName = "InfraspecificEpithet";
312 obligatory = false;
313 Element elInfraspecificEpithet = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
314 String infraspecificEpithet = (elInfraspecificEpithet == null)? "" : elInfraspecificEpithet.getTextNormalize();
315 if (! infraspecificEpithet.trim().equals("")){
316 nonViralName.setInfraSpecificEpithet(infraspecificEpithet);
317 if (nonViralName.getRank() != null && ! name.isInfraSpecific() ){
318 logger.warn("Name " + simple + " is not infraspecific but has canonical name part 'InfraspecificEpithet'.");
319 }
320 }
321 testNoMoreElements();
322
323
324 }else{ //ViralName
325 //logger.warn("Non NonViralNames not yet supported by makeCanonicalName");
326 }
327
328
329 childName = "CultivarNameGroup";
330 obligatory = false;
331 Element elCultivarNameGroup = XmlHelp.getSingleChildElement(success, elCanonicalName, childName, ns, obligatory);
332 String cultivarNameGroup = (elCultivarNameGroup == null)? "" : elCultivarNameGroup.getTextNormalize();
333 if (! "".equals(cultivarNameGroup.trim())){
334 if (name instanceof CultivarPlantName){
335 makeCultivarName();
336 }else{
337 logger.warn("Non cultivar name has 'cultivar name group' element. Omitted");
338 }
339 }
340 return;
341 }
342
343 protected void testNoMoreElements(){
344 //TODO
345 //logger.info("testNoMoreElements Not yet implemented");
346 }
347
348 private void makeCultivarName(){
349 //TODO
350 //logger.warn("'makeCultivarName' Not yet implemented");
351 }
352
353 private void makeGenusReferenceType(TaxonNameBase name, Element elGenus, MapWrapper<TaxonNameBase> taxonNameMap, ResultWrapper<Boolean> success){
354 if(name instanceof NonViralName){
355 NonViralName nonViralName = (NonViralName)name;
356 if (elGenus != null && name != null){
357 TaxonNameBase genusReferenceName;
358 //TODO code
359 Class<? extends NonViralName> clazz = NonViralName.class;
360 genusReferenceName = makeReferenceType(elGenus, clazz, taxonNameMap, success);
361 NonViralName nvGenusReference = (NonViralName)genusReferenceName;
362 //Genus is stored either in Genus part (if ref) or in titleCache (if plain text)
363 String genus = nvGenusReference.getGenusOrUninomial()!= null ? nvGenusReference.getGenusOrUninomial(): genusReferenceName.getTitleCache();
364 nonViralName.setGenusOrUninomial(genus);
365 }else{
366 logger.warn("Missing Genus information");
367 }
368 }else{
369 //TODO (can be changed if Viral Name also has Genus in future
370 //logger.warn("Genus ref type for Viral Name not implemented yet");
371 }
372
373 }
374
375
376 @SuppressWarnings("unchecked")
377 private INomenclaturalAuthor makeNameCitation(Element elNameCitation, MapWrapper<Person> authorMap, ResultWrapper<Boolean> success){
378 INomenclaturalAuthor result = null;
379 String childName;
380 boolean obligatory;
381 if (elNameCitation != null){
382 Namespace ns = elNameCitation.getNamespace();
383
384 childName = "Authors";
385 obligatory = false;
386 Element elAuthors = XmlHelp.getSingleChildElement(success, elNameCitation, childName, ns, obligatory);
387 testNoMoreElements();
388
389 if (elAuthors != null){
390 childName = "AgentName";
391 List<Element> elAgentList = elAuthors.getChildren(childName, ns);
392 Team team = Team.NewInstance();
393 result = team;
394 if (elAgentList.size() > 1){
395 for(Element elAgent : elAgentList){
396 Person teamMember = makeAgent(elAgent, ns, authorMap, success);
397 team.addTeamMember(teamMember);
398 }
399 }else if(elAgentList.size() == 1){
400 result = makeAgent(elAgentList.get(0), ns, authorMap, success);
401 }
402 }else{
403 childName = "Simple";
404 obligatory = true;
405 Element elSimple = XmlHelp.getSingleChildElement(success, elNameCitation, childName, ns, obligatory);
406 String simple = (elSimple == null)? "" : elSimple.getTextNormalize();
407 result = Team.NewInstance();
408 result.setNomenclaturalTitle(simple);
409 }
410 }
411 return result;
412 }
413
414 private Person makeAgent(Element elAgentName, Namespace ns, MapWrapper<Person> agentMap, ResultWrapper<Boolean> success){
415 Person result = null;
416 if (elAgentName != null){
417 String authorTitle = elAgentName.getTextNormalize();
418 result = Person.NewTitledInstance(authorTitle);
419 Class<? extends Person> clazz = Person.class;
420 result = makeReferenceType(elAgentName, clazz, agentMap, success);
421 return result;
422 }else{
423 return null;
424 }
425 }
426
427 private void makeCanonicalAuthorship(TaxonNameBase name, Element elCanonicalAuthorship, MapWrapper<Person> authorMap, ResultWrapper<Boolean> success){
428 if (elCanonicalAuthorship != null){
429 Namespace ns = elCanonicalAuthorship.getNamespace();
430
431 if (name instanceof NonViralName){
432 NonViralName nonViralName = (NonViralName)name;
433
434 String childName = "Simple";
435 boolean obligatory = true;
436 Element elSimple = XmlHelp.getSingleChildElement(success, elCanonicalAuthorship, childName, ns, obligatory);
437 String simple = (elSimple == null)? "" : elSimple.getTextNormalize();
438 //TODO
439 //logger.warn("authorship cache cache protected not yet implemented");
440 //nonViralName.setAuthorshipCache(simple, cacheProtected);
441
442 childName = "Authorship";
443 obligatory = false;
444 Element elAuthorship = XmlHelp.getSingleChildElement(success, elCanonicalAuthorship, childName, ns, obligatory);
445 INomenclaturalAuthor author = makeNameCitation(elAuthorship, authorMap, success);
446 nonViralName.setCombinationAuthorTeam(author);
447 testNoMoreElements();
448
449 childName = "BasionymAuthorship";
450 obligatory = false;
451 Element elBasionymAuthorship = XmlHelp.getSingleChildElement(success, elCanonicalAuthorship, childName, ns, obligatory);
452 INomenclaturalAuthor basionymAuthor = makeNameCitation(elBasionymAuthorship, authorMap, success);
453 nonViralName.setBasionymAuthorTeam(basionymAuthor);
454 testNoMoreElements();
455
456 childName = "CombinationAuthorship";
457 obligatory = false;
458 Element elCombinationAuthorship = XmlHelp.getSingleChildElement(success, elCanonicalAuthorship, childName, ns, obligatory);
459 INomenclaturalAuthor combinationAuthor = makeNameCitation(elCombinationAuthorship, authorMap ,success);
460 nonViralName.setCombinationAuthorTeam(combinationAuthor);
461 testNoMoreElements();
462
463 if (elAuthorship != null && (elBasionymAuthorship != null || elCombinationAuthorship != null) ){
464 logger.warn("Authorship and (BasionymAuthorship or CombinationAuthorship) must not exist at the same time in CanonicalAuthorship");
465 success.setValue(false);
466 }
467 }
468 }
469 }
470
471
472 private void makePublishedIn(TaxonNameBase name, Element elPublishedIn, MapWrapper<ReferenceBase> referenceMap, ResultWrapper<Boolean> success){
473 if (elPublishedIn != null && name != null){
474 Class<? extends ReferenceBase> clazz = ReferenceBase.class;
475 ReferenceBase ref = makeReferenceType(elPublishedIn, clazz, referenceMap, success);
476 if (ref instanceof INomenclaturalReference){
477 name.setNomenclaturalReference(ref);
478 }else{
479 logger.warn("Reference is not of type INomenclaturalReference and could not be added to the name " + name.getTitleCache());
480 }
481 }else if (name == null){
482 logger.warn("TaxonName must not be 'null'");
483 success.setValue(false);
484 }
485 }
486
487
488 private void makeYear(TaxonNameBase name, Element elYear, ResultWrapper<Boolean> success){
489 if (elYear != null){
490 String year = elYear.getTextNormalize();
491 if (name instanceof ZoologicalName){
492 ((ZoologicalName)name).setPublicationYear(getIntegerYear(year));
493 }else{
494 logger.warn("Year can be set only for a zoological name");
495 }
496 }
497 }
498
499 private Integer getIntegerYear(String year){
500 try {
501 Integer result = Integer.valueOf(year);
502 return result;
503 } catch (NumberFormatException e) {
504 logger.warn("Year string could not be parsed. Set = 9999 instead");
505 return 9999;
506 }
507 }
508
509
510 private void makeMicroReference(TaxonNameBase name, Element elMicroReference, ResultWrapper<Boolean> success){
511 if (elMicroReference != null){
512 String microReference = elMicroReference.getTextNormalize();
513 name.setNomenclaturalMicroReference(microReference);
514 }
515 }
516
517
518 private void makeTypification(TaxonNameBase name, Element elTypifiacation, ResultWrapper<Boolean> success){
519 if (elTypifiacation != null){
520 //logger.warn("makeTypification not yet implemented");
521 //success.setValue(false);
522 }
523 }
524
525
526 private void makePublicationStatus(TaxonNameBase name, Element elPublicationStatus, ResultWrapper<Boolean> success){
527 //Status
528
529 if (elPublicationStatus != null){
530 //logger.warn("makePublicationStatus not yet implemented");
531 //success.setValue(false);
532 }
533 }
534
535 private void makeProviderLink(TaxonNameBase name, Element elProviderLink, ResultWrapper<Boolean> success){
536 if (elProviderLink != null){
537 //logger.warn("makeProviderLink not yet implemented");
538 //success.setValue(false);
539 }
540 }
541
542
543 private void makeProviderSpecificData(TaxonNameBase name, Element elProviderSpecificData, ResultWrapper<Boolean> success){
544 if (elProviderSpecificData != null){
545 //logger.warn("makeProviderSpecificData not yet implemented");
546 //success.setValue(false);
547 }
548 }
549
550
551 /* (non-Javadoc)
552 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
553 */
554 protected boolean isIgnore(TcsXmlImportState state){
555 return ! state.getConfig().isDoTaxonNames();
556 }
557
558 }