Readers.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-4.2.0).
003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.xml;
021 
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024 import static io.jenetics.xml.stream.Reader.attr;
025 import static io.jenetics.xml.stream.Reader.elem;
026 import static io.jenetics.xml.stream.Reader.elems;
027 import static io.jenetics.xml.stream.Reader.text;
028 
029 import java.io.InputStream;
030 import java.util.List;
031 import java.util.function.Function;
032 import java.util.function.IntFunction;
033 import java.util.stream.Stream;
034 
035 import javax.xml.stream.XMLStreamException;
036 
037 import io.jenetics.BoundedGene;
038 import io.jenetics.Chromosome;
039 import io.jenetics.DoubleGene;
040 import io.jenetics.EnumGene;
041 import io.jenetics.Gene;
042 import io.jenetics.IntegerGene;
043 import io.jenetics.LongGene;
044 import io.jenetics.util.CharSeq;
045 import io.jenetics.util.ISeq;
046 import io.jenetics.util.MSeq;
047 
048 import io.jenetics.xml.stream.AutoCloseableXMLStreamReader;
049 import io.jenetics.xml.stream.Reader;
050 import io.jenetics.xml.stream.XML;
051 
052 /**
053  * This class contains static fields and methods, for creating chromosome- and
054  * genotype readers for different gene types.
055  *
056  <pre>{@code
057  * final Reader<Genotype<BitGene> bgr =
058  *     Readers.Genotype.reader(Readers.BitChromosome.reader()));
059  *
060  * final Reader<Genotype<IntegerGene>> igr =
061  *     Writers.Genotype.reader(Readers.IntegerChromosome.reader()));
062  *
063  * final Reader<Genotype<DoubleGene>> dgr =
064  *     Readers.Genotype.reader(Readers.DoubleChromosome.reader()));
065  * }</pre>
066  *
067  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
068  @version 3.9
069  @since 3.9
070  */
071 public final class Readers {
072     private Readers() {}
073 
074     /**
075      * Bit chromosome reader methods, which reads XML-representations of
076      * bit-chromosomes.
077      <p>
078      <b>XML</b>
079      <pre> {@code
080      <bit-chromosome length="20" ones-probability="0.5">11100011101011001010</bit-chromosome>
081      * }</pre>
082      * }
083      */
084     public static final class BitChromosome {
085         private BitChromosome() {}
086 
087         /**
088          * Return a XML reader for {@link io.jenetics.BitChromosome} objects.
089          *
090          @return a chromosome reader
091          */
092         public static Reader<io.jenetics.BitChromosome> reader() {
093             return elem(
094                 v -> io.jenetics.BitChromosome.of(
095                     (String)v[2](int)v[0](double)v[1]
096                 ),
097                 Writers.BitChromosome.ROOT_NAME,
098                 attr(Writers.BitChromosome.LENGTH_NAME)
099                     .map(Integer::parseInt),
100                 attr(Writers.BitChromosome.ONES_PROBABILITY_NAME)
101                     .map(Double::parseDouble),
102                 text()
103             );
104         }
105 
106         /**
107          * Read a new {@link io.jenetics.BitChromosome} from the given input
108          * stream.
109          *
110          @param in the data source of the bit-chromosome
111          @return the bit-chromosome read from the input stream
112          @throws XMLStreamException if reading the chromosome fails
113          @throws NullPointerException if the given input stream is {@code null}
114          */
115         public static io.jenetics.BitChromosome read(final InputStream in)
116             throws XMLStreamException
117         {
118             try (AutoCloseableXMLStreamReader xml = XML.reader(in)) {
119                 xml.next();
120                 return reader().read(xml);
121             }
122         }
123     }
124 
125     /**
126      * Reader methods for {@link io.jenetics.CharacterChromosome} objects.
127      <p>
128      <b>XML format</b>
129      <pre> {@code
130      <character-chromosome length="4">
131      *     <valid-alleles>ABCDEFGHIJKLMNOPQRSTUVWXYZ<valid-alleles>
132      *     <alleles>ASDF</alleles>
133      </character-chromosome>
134      * }</pre>
135      */
136     public static final class CharacterChromosome {
137         private CharacterChromosome() {}
138 
139         /**
140          * Return a XML reader for {@link io.jenetics.CharacterChromosome}
141          * objects.
142          *
143          @return a chromosome reader
144          */
145         public static Reader<io.jenetics.CharacterChromosome> reader() {
146             return elem(
147                 v -> io.jenetics.CharacterChromosome.of(
148                     (String)v[2](CharSeq)v[1]
149                 ),
150                 Writers.CharacterChromosome.ROOT_NAME,
151                 attr(Writers.CharacterChromosome.LENGTH_NAME)
152                     .map(Integer::parseInt),
153                 elem(Writers.CharacterChromosome.VALID_ALLELES_NAME,
154                     text().map(CharSeq::new)),
155                 elem(Writers.CharacterChromosome.ALLELES_NAME, text())
156             );
157         }
158 
159         /**
160          * Read a new {@link io.jenetics.CharacterChromosome} from the given
161          * input stream.
162          *
163          @param in the data source of the chromosome
164          @return the bit-chromosome read from the input stream
165          @throws XMLStreamException if reading the chromosome fails
166          @throws NullPointerException if the given input stream is {@code null}
167          */
168         public static io.jenetics.CharacterChromosome read(final InputStream in)
169             throws XMLStreamException
170         {
171             try (AutoCloseableXMLStreamReader xml = XML.reader(in)) {
172                 xml.next();
173                 return reader().read(xml);
174             }
175         }
176 
177     }
178 
179     /**
180      * Reader methods for {@link io.jenetics.BoundedChromosome} objects.
181      <p>
182      <b>XML format</b>
183      <pre> {@code
184      <root-name length="3">
185      *     <min>aaa</min>
186      *     <max>zzz</max>
187      *     <alleles>
188      *         <allele>iii</allele>
189      *         <allele>fff</allele>
190      *         <allele>ggg</allele>
191      *     </alleles>
192      </root-name>
193      * }</pre>
194      */
195     public static final class BoundedChromosome {
196         private BoundedChromosome() {}
197 
198         /**
199          * Create a bounded chromosome reader with the given configuration.
200          *
201          @param name the root element name
202          @param gene the gene creator
203          @param genes the gene array creator
204          @param chromosome the chromosome creator
205          @param alleleReader the allele reader
206          @param <A> the allele type
207          @param <G> the gene type
208          @param <C> the chromosome type
209          @return a bounded chromosome reader
210          @throws NullPointerException if one of the arguments is {@code null}
211          */
212         public static <
213             extends Comparable<? super A>,
214             extends BoundedGene<A, G>,
215             extends io.jenetics.BoundedChromosome<A, G>
216         >
217         Reader<C> reader(
218             final String name,
219             final BoundedGeneCreator<A, G> gene,
220             final IntFunction<G[]> genes,
221             final Function<G[], C> chromosome,
222             final Reader<? extends A> alleleReader
223         ) {
224             return elem(v -> {
225                 final int length = (int)v[0];
226                 @SuppressWarnings("unchecked")
227                 final A min = (A)v[1];
228                 @SuppressWarnings("unchecked")
229                 final A max = (A)v[2];
230                 @SuppressWarnings("unchecked")
231                 final List<A> alleles = (List<A>)v[3];
232 
233                 if (alleles.size() != length) {
234                     throw new IllegalArgumentException(format(
235                         "Expected %d alleles, but got %d,",
236                         length, alleles.size()
237                     ));
238                 }
239 
240                 return chromosome.apply(
241                     alleles.stream()
242                         .map(value -> gene.create(value, min, max))
243                         .toArray(genes)
244                 );
245             }, name,
246                 attr(Writers.BoundedChromosome.LENGTH_NAME).map(Integer::parseInt),
247                 elem(Writers.BoundedChromosome.MIN_NAME, alleleReader),
248                 elem(Writers.BoundedChromosome.MAX_NAME, alleleReader),
249                 elem(Writers.BoundedChromosome.ALLELES_NAME,
250                     elems(elem(Writers.BoundedChromosome.ALLELE_NAME, alleleReader))
251                 )
252             );
253         }
254 
255     }
256 
257     /**
258      * Reader methods for {@link io.jenetics.IntegerChromosome} objects.
259      <p>
260      <b>XML format</b>
261      <pre> {@code
262      <int-chromosome length="3">
263      *     <min>-2147483648</min>
264      *     <max>2147483647</max>
265      *     <alleles>
266      *         <allele>-1878762439</allele>
267      *         <allele>-957346595</allele>
268      *         <allele>-88668137</allele>
269      *     </alleles>
270      </int-chromosome>
271      * }</pre>
272      */
273     public static final class IntegerChromosome {
274         private IntegerChromosome() {}
275 
276         /**
277          * Return the default allele reader for the {@code IntegerChromosome}.
278          *
279          @return the default allele reader
280          */
281         public static Reader<Integer> alleleReader() {
282             return text().map(Integer::parseInt);
283         }
284 
285         /**
286          * Return a {@link io.jenetics.IntegerChromosome} reader.
287          *
288          @return a integer chromosome reader
289          */
290         public static Reader<io.jenetics.IntegerChromosome> reader() {
291             return BoundedChromosome.reader(
292                 Writers.IntegerChromosome.ROOT_NAME,
293                 IntegerGene::of,
294                 IntegerGene[]::new,
295                 io.jenetics.IntegerChromosome::of,
296                 alleleReader()
297             );
298         }
299 
300         /**
301          * Read a new {@link io.jenetics.IntegerChromosome} from the given
302          * input stream.
303          *
304          @param in the data source of the chromosome
305          @return a new chromosome
306          @throws XMLStreamException if reading the chromosome fails
307          @throws NullPointerException if the given input stream is {@code null}
308          */
309         public static io.jenetics.IntegerChromosome read(final InputStream in)
310             throws XMLStreamException
311         {
312             try (AutoCloseableXMLStreamReader reader = XML.reader(in)) {
313                 reader.next();
314                 return reader().read(reader);
315             }
316         }
317 
318     }
319 
320     /**
321      * Reader methods for {@link io.jenetics.LongChromosome} objects.
322      <p>
323      <b>XML format</b>
324      <pre> {@code
325      <long-chromosome length="3">
326      *     <min>-9223372036854775808</min>
327      *     <max>9223372036854775807</max>
328      *     <alleles>
329      *         <allele>-1345217698116542402</allele>
330      *         <allele>-7144755673073475303</allele>
331      *         <allele>6053786736809578435</allele>
332      *     </alleles>
333      </long-chromosome>
334      * }</pre>
335      */
336     public static final class LongChromosome {
337         private LongChromosome() {}
338 
339         /**
340          * Return the default allele reader for the {@code LongChromosome}.
341          *
342          @return the default allele reader
343          */
344         public static Reader<Long> alleleReader() {
345             return text().map(Long::parseLong);
346         }
347 
348         /**
349          * Return a {@link io.jenetics.LongChromosome} reader.
350          *
351          @return a long chromosome reader
352          */
353         public static Reader<io.jenetics.LongChromosome> reader() {
354             return BoundedChromosome.reader(
355                 Writers.LongChromosome.ROOT_NAME,
356                 LongGene::of,
357                 LongGene[]::new,
358                 io.jenetics.LongChromosome::of,
359                 alleleReader()
360             );
361         }
362 
363         /**
364          * Read a new {@link io.jenetics.LongChromosome} from the given
365          * input stream.
366          *
367          @param in the data source of the chromosome
368          @return a new chromosome
369          @throws XMLStreamException if reading the chromosome fails
370          @throws NullPointerException if the given input stream is {@code null}
371          */
372         public static io.jenetics.LongChromosome read(final InputStream in)
373             throws XMLStreamException
374         {
375             try (AutoCloseableXMLStreamReader reader = XML.reader(in)) {
376                 reader.next();
377                 return reader().read(reader);
378             }
379         }
380 
381     }
382 
383     /**
384      * Reader methods for {@link io.jenetics.DoubleChromosome} objects.
385      <p>
386      <b>XML format</b>
387      <pre> {@code
388      <double-chromosome length="3">
389      *     <min>0.0</min>
390      *     <max>1.0</max>
391      *     <alleles>
392      *         <allele>0.27251556008507416</allele>
393      *         <allele>0.003140816229067145</allele>
394      *         <allele>0.43947528327497376</allele>
395      *     </alleles>
396      </double-chromosome>
397      * }</pre>
398      */
399     public static final class DoubleChromosome {
400         private DoubleChromosome() {}
401 
402         /**
403          * Return the default allele reader for the {@code DoubleChromosome}.
404          *
405          @return the default allele reader
406          */
407         public static Reader<Double> alleleReader() {
408             return text().map(Double::parseDouble);
409         }
410 
411         /**
412          * Return a {@link io.jenetics.DoubleChromosome} reader.
413          *
414          @return a double chromosome reader
415          */
416         public static Reader<io.jenetics.DoubleChromosome> reader() {
417             return BoundedChromosome.reader(
418                 Writers.DoubleChromosome.ROOT_NAME,
419                 DoubleGene::of,
420                 DoubleGene[]::new,
421                 io.jenetics.DoubleChromosome::of,
422                 alleleReader()
423             );
424         }
425 
426         /**
427          * Read a new {@link io.jenetics.DoubleChromosome} from the given
428          * input stream.
429          *
430          @param in the data source of the chromosome
431          @return a new chromosome
432          @throws XMLStreamException if reading the chromosome fails
433          @throws NullPointerException if the given input stream is {@code null}
434          */
435         public static io.jenetics.DoubleChromosome read(final InputStream in)
436             throws XMLStreamException
437         {
438             try (AutoCloseableXMLStreamReader reader = XML.reader(in)) {
439                 reader.next();
440                 return reader().read(reader);
441             }
442         }
443 
444     }
445 
446     /**
447      * Reader methods for {@link io.jenetics.PermutationChromosome} objects.
448      <p>
449      <b>XML format</b>
450      <pre> {@code
451      <permutation-chromosome length="5">
452      *     <valid-alleles type="java.lang.Integer">
453      *         <allele>0</allele>
454      *         <allele>1</allele>
455      *         <allele>2</allele>
456      *         <allele>3</allele>
457      *         <allele>4</allele>
458      *     </valid-alleles>
459      *     <order>2 1 3 5 4</order>
460      </permutation-chromosome>
461      * }</pre>
462      */
463     public static final class PermutationChromosome {
464         private PermutationChromosome() {}
465 
466         /**
467          * Return a reader for permutation chromosomes with the given allele
468          * reader.
469          *
470          @param alleleReader the allele reader
471          @param <A> the allele type
472          @return a permutation chromosome reader
473          @throws NullPointerException if the given allele reader is
474          *        {@code null}
475          */
476         public static <A> Reader<io.jenetics.PermutationChromosome<A>>
477         reader(final Reader<? extends A> alleleReader) {
478             requireNonNull(alleleReader);
479 
480             return elem(v -> {
481                 final int length = (int)v[0];
482                 @SuppressWarnings("unchecked")
483                 final ISeq<A> validAlleles = ISeq.of((List<A>)v[1]);
484 
485                 final int[] order = Stream.of(((Stringv[2]).split("\\s"))
486                     .mapToInt(Integer::parseInt)
487                     .toArray();
488 
489                 final MSeq<EnumGene<A>> alleles = MSeq.ofLength(length);
490                 for (int i = 0; i < length; ++i) {
491                     final EnumGene<A> gene = EnumGene.of(order[i], validAlleles);
492                     alleles.set(i, gene);
493                 }
494 
495                 return new io.jenetics.PermutationChromosome<A>(alleles.toISeq());
496             },
497                 Writers.PermutationChromosome.ROOT_NAME,
498                 attr(Writers.PermutationChromosome.LENGTH_NAME).map(Integer::parseInt),
499                 elem(Writers.PermutationChromosome.VALID_ALLELES_NAME,
500                     elems(elem(Writers.PermutationChromosome.ALLELE_NAME, alleleReader))
501                 ),
502                 elem(Writers.PermutationChromosome.ORDER_NAME, text())
503             );
504         }
505 
506         /**
507          * Reads a new {@link io.jenetics.PermutationChromosome} from the given
508          * input stream.
509          *
510          @param <A> the allele type
511          @param in the data source of the chromosome
512          @param alleleReader the allele reader
513          @return a new permutation chromosome
514          @throws XMLStreamException if reading the chromosome fails
515          @throws NullPointerException if one of the arguments is {@code null}
516          */
517         public static <A> io.jenetics.PermutationChromosome<A>
518         read(final InputStream in, final Reader<? extends A> alleleReader)
519             throws XMLStreamException
520         {
521             requireNonNull(alleleReader);
522             requireNonNull(in);
523 
524             try (AutoCloseableXMLStreamReader xml = XML.reader(in)) {
525                 xml.next();
526                 return PermutationChromosome.<A>reader(alleleReader).read(xml);
527             }
528         }
529 
530     }
531 
532     /**
533      * Writer methods for {@link io.jenetics.Genotype} objects.
534      <p>
535      <b>XML format</b>
536      <pre> {@code
537      <genotype length="2" ngenes="5">
538      *     <double-chromosome length="3">
539      *         <min>0.0</min>
540      *         <max>1.0</max>
541      *         <alleles>
542      *             <allele>0.27251556008507416</allele>
543      *             <allele>0.003140816229067145</allele>
544      *             <allele>0.43947528327497376</allele>
545      *         </alleles>
546      *     </double-chromosome>
547      *     <double-chromosome length="2">
548      *         <min>0.0</min>
549      *         <max>1.0</max>
550      *         <alleles>
551      *             <allele>0.4026521545744768</allele>
552      *             <allele>0.36137605952663554</allele>
553      *         <alleles>
554      *     </double-chromosome>
555      </genotype>
556      * }</pre>
557      */
558     public static final class Genotype {
559         private Genotype() {}
560 
561         /**
562          * Create a genotype reader with he given chromosome reader.
563          *
564          @param chromosomeReader the underlying chromosome reader
565          @param <A> the allele type
566          @param <G> the gene type
567          @param <C> the chromosome type
568          @return a genotype reader with he given chromosome reader
569          @throws NullPointerException if the given {@code chromosomeReader} is
570          *         {@code null}
571          */
572         public static <
573             A,
574             extends Gene<A, G>,
575             extends Chromosome<G>
576         >
577         Reader<io.jenetics.Genotype<G>>
578         reader(final Reader<? extends C> chromosomeReader) {
579             requireNonNull(chromosomeReader);
580 
581             return elem(v -> {
582                 @SuppressWarnings("unchecked")
583                 final List<C> chromosomes = (List<C>)v[2];
584                 final io.jenetics.Genotype<G> genotype =
585                     io.jenetics.Genotype.of(chromosomes);
586 
587                 final int length = (int)v[0];
588                 final int ngenes = (int)v[1];
589                 if (length != genotype.length()) {
590                     throw new IllegalArgumentException(format(
591                         "Expected %d chromosome, but read %d.",
592                         length, genotype.length()
593                     ));
594                 }
595                 if (ngenes != genotype.geneCount()) {
596                     throw new IllegalArgumentException(format(
597                         "Expected %d genes, but read %d.",
598                         ngenes, genotype.geneCount()
599                     ));
600                 }
601 
602                 return genotype;
603             },
604                 Writers.Genotype.ROOT_NAME,
605                 attr(Writers.Genotype.LENGTH_NAME).map(Integer::parseInt),
606                 attr(Writers.Genotype.NGENES_NAME).map(Integer::parseInt),
607                 elems(chromosomeReader)
608             );
609         }
610 
611         /**
612          * Reads a genotype by using the given chromosome reader.
613          *
614          @param <A> the allele type
615          @param <G> the gene type
616          @param <C> the chromosome type
617          @param in the input stream to read the genotype from
618          @param chromosomeReader the used chromosome reader
619          @return a genotype by using the given chromosome reader
620          @throws XMLStreamException if reading the genotype fails
621          @throws NullPointerException if one of the arguments is {@code null}
622          */
623         public static <
624             A,
625             extends Gene<A, G>,
626             extends Chromosome<G>
627         >
628         io.jenetics.Genotype<G>
629         read(final InputStream in, final Reader<? extends C> chromosomeReader)
630             throws XMLStreamException
631         {
632             requireNonNull(chromosomeReader);
633             requireNonNull(in);
634 
635             try (AutoCloseableXMLStreamReader xml = XML.reader(in)) {
636                 xml.next();
637                 return reader(chromosomeReader).read(xml);
638             }
639         }
640     }
641 
642     /**
643      * This class contains static reader methods for
644      {@link io.jenetics.Genotype} objects.
645      <p>
646      <b>XML format</b>
647      <pre> {@code
648      <genotypes length="1">
649      *     <genotype length="2" ngenes="5">
650      *         <double-chromosome length="3">
651      *             <min>0.0</min>
652      *             <max>1.0</max>
653      *             <alleles>
654      *                 <allele>0.27251556008507416</allele>
655      *                 <allele>0.003140816229067145</allele>
656      *                 <allele>0.43947528327497376</allele>
657      *             </alleles>
658      *         </double-chromosome>
659      *         <double-chromosome length="2">
660      *             <min>0.0</min>
661      *             <max>1.0</max>
662      *             <alleles>
663      *                 <allele>0.4026521545744768</allele>
664      *                 <allele>0.36137605952663554</allele>
665      *             <alleles>
666      *         </double-chromosome>
667      *     </genotype>
668      </genotypes>
669      * }</pre>
670      */
671     public static final class Genotypes {
672         private Genotypes() {}
673 
674         /**
675          * Return a genotypes reader using the given chromosome reader.
676          *
677          @param chromosomeReader the underlying chromosome reader
678          @param <A> the allele type
679          @param <G> the gene type
680          @param <C> the chromosome type
681          @return a genotypes reader using the given chromosome reader
682          @throws NullPointerException if the given {@code chromosomeReader} is
683          *         {@code null}
684          */
685         @SuppressWarnings("unchecked")
686         public static <
687             A,
688             extends Gene<A, G>,
689             extends Chromosome<G>
690         >
691         Reader<List<io.jenetics.Genotype<G>>>
692         reader(final Reader<C> chromosomeReader) {
693             return elem(
694                 p -> (List<io.jenetics.Genotype<G>>)p[0],
695                 Writers.Genotypes.ROOT_NAME,
696                 elems(Genotype.reader(chromosomeReader))
697             );
698         }
699 
700         /**
701          * Reads the genotypes by using the given chromosome reader.
702          *
703          @param <A> the allele type
704          @param <G> the gene type
705          @param <C> the chromosome type
706          @param in the input stream to read the genotype from
707          @param chromosomeReader the used chromosome reader
708          @return a genotype by using the given chromosome reader
709          @throws XMLStreamException if reading the genotype fails
710          @throws NullPointerException if one of the arguments is {@code null}
711          */
712         public static <
713             A,
714             extends Gene<A, G>,
715             extends Chromosome<G>
716         >
717         List<io.jenetics.Genotype<G>>
718         read(final InputStream in, final Reader<? extends C> chromosomeReader)
719             throws XMLStreamException
720         {
721             requireNonNull(chromosomeReader);
722             requireNonNull(in);
723 
724             try (AutoCloseableXMLStreamReader xml = XML.reader(in)) {
725                 xml.next();
726                 return reader(chromosomeReader).read(xml);
727             }
728         }
729 
730     }
731 
732     /**
733      * Reads the genotypes by using the given chromosome reader.
734      *
735      @see Genotypes#read(InputStream, Reader)
736      *
737      @param <A> the allele type
738      @param <G> the gene type
739      @param <C> the chromosome type
740      @param in the input stream to read the genotype from
741      @param chromosomeReader the used chromosome reader
742      @return a genotype by using the given chromosome reader
743      @throws XMLStreamException if reading the genotype fails
744      @throws NullPointerException if one of the arguments is {@code null}
745      */
746     public static <
747         A,
748         extends Gene<A, G>,
749         extends Chromosome<G>
750     >
751     List<io.jenetics.Genotype<G>>
752     read(final InputStream in, final Reader<? extends C> chromosomeReader)
753         throws XMLStreamException
754     {
755         return Genotypes.read(in, chromosomeReader);
756     }
757 
758 }