+ public boolean add(SeqCigar seq)
+ {
+ if (!seq.isMemberOf(this))
+ {
+ seqs.add(seq);
+ seq.setGroupMembership(this);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @param seq
+ * @return true if seq was a member and was removed from group
+ */
+ public boolean remove(SeqCigar seq)
+ {
+ if (seq.removeGroupMembership(this))
+ {
+ seqs.remove(seq);
+ return true;
+ }
+ return false;
+ }
+
+ public int size()
+ {
+ return seqs.size();
+ }
+
+ public SequenceGroup getNewSequenceGroup(char c)
+ {
+ SequenceGroup newsg = new SequenceGroup(sg);
+ for (SeqCigar seq : seqs)
+ {
+ newsg.addSequence(seq.getSeq(c), false);
+ }
+ return newsg;
+ }
+ }
+
+ /**
+ * vector of selected seqCigars. This vector is also referenced by each
+ * seqCigar contained in it.
+ */
+ private ScGroup selected;
+
+ /**
+ * Construct an alignmentView from a live jalview alignment view. Note -
+ * hidden rows will be excluded from alignmentView Note: JAL-1179
+ *
+ * @param alignment
+ * - alignment as referenced by an AlignViewport
+ * @param columnSelection
+ * -
+ * @param selection
+ * @param hasHiddenColumns
+ * - mark the hidden columns in columnSelection as hidden in the view
+ * @param selectedRegionOnly
+ * - when set, only include the selected region in the view,
+ * otherwise just mark the selected region on the constructed view.
+ * @param recordGroups
+ * - when set, any groups on the given alignment will be marked on
+ * the view
+ */
+ public AlignmentView(AlignmentI alignment, HiddenColumns hidden,
+ SequenceGroup selection, boolean hasHiddenColumns,
+ boolean selectedRegionOnly, boolean recordGroups)
+ {
+ // refactored from AlignViewport.getAlignmentView(selectedOnly);
+ this(new jalview.datamodel.CigarArray(alignment,
+ (hasHiddenColumns ? hidden : null),
+ (selectedRegionOnly ? selection : null)),
+ (selectedRegionOnly && selection != null)
+ ? selection.getStartRes()
+ : 0);
+ isNa = alignment.isNucleotide();
+ // walk down SeqCigar array and Alignment Array - optionally restricted by
+ // selected region.
+ // test group membership for each sequence in each group, store membership
+ // and record non-empty groups in group list.
+ // record / sub-select selected region on the alignment view
+ SequenceI[] selseqs;
+ if (selection != null && selection.getSize() > 0)
+ {
+ this.selected = new ScGroup();
+ selseqs = selection.getSequencesInOrder(alignment,
+ selectedRegionOnly);
+ }
+ else
+ {
+ selseqs = alignment.getSequencesArray();
+ }
+
+ List<List<SequenceI>> seqsets = new ArrayList<>();
+ // get the alignment's group list and make a copy
+ List<SequenceGroup> grps = new ArrayList<>();
+ List<SequenceGroup> gg = alignment.getGroups();
+ grps.addAll(gg);
+ ScGroup[] sgrps = null;
+ boolean addedgps[] = null;
+ if (grps != null)
+ {
+ if (selection != null && selectedRegionOnly)
+ {
+ // trim annotation to the region being stored.
+ // strip out any groups that do not actually intersect with the
+ // visible and selected region
+ int ssel = selection.getStartRes(), esel = selection.getEndRes();
+ List<SequenceGroup> isg = new ArrayList<>();
+ for (SequenceGroup sg : grps)
+ {
+ if (!(sg.getStartRes() > esel || sg.getEndRes() < ssel))
+ {
+ // adjust bounds of new group, if necessary.
+ if (sg.getStartRes() < ssel)
+ {
+ sg.setStartRes(ssel);
+ }
+ if (sg.getEndRes() > esel)
+ {
+ sg.setEndRes(esel);
+ }
+ sg.setStartRes(sg.getStartRes() - ssel + 1);
+ sg.setEndRes(sg.getEndRes() - ssel + 1);
+
+ isg.add(sg);
+ }
+ }
+ grps = isg;
+ }
+
+ sgrps = new ScGroup[grps.size()];
+ addedgps = new boolean[grps.size()];
+ for (int g = 0; g < sgrps.length; g++)
+ {
+ SequenceGroup sg = grps.get(g);
+ sgrps[g] = new ScGroup();
+ sgrps[g].sg = new SequenceGroup(sg);
+ addedgps[g] = false;
+ // can't set entry 0 in an empty list
+ // seqsets.set(g, sg.getSequences(null));
+ seqsets.add(sg.getSequences());
+ }
+ // seqsets now contains vectors (should be sets) for each group, so we can
+ // track when we've done with the group
+ }
+ int csi = 0;
+ for (int i = 0; i < selseqs.length; i++)
+ {
+ if (selseqs[i] != null)
+ {
+ if (selection != null && selection.getSize() > 0
+ && !selectedRegionOnly)
+ {
+ selected.add(sequences[csi]);
+ }
+ if (seqsets != null)
+ {
+ for (int sg = 0; sg < sgrps.length; sg++)
+ {
+ if ((seqsets.get(sg)).contains(selseqs[i]))
+ {
+ sgrps[sg].sg.deleteSequence(selseqs[i], false);
+ sgrps[sg].add(sequences[csi]);
+ if (!addedgps[sg])
+ {
+ if (scGroups == null)
+ {
+ scGroups = new ArrayList<>();
+ }
+ addedgps[sg] = true;
+ scGroups.add(sgrps[sg]);
+ }
+ }
+ }
+ }
+ csi++;
+ }
+ }
+ // finally, delete the remaining sequences (if any) not selected
+ for (int sg = 0; sg < sgrps.length; sg++)
+ {
+ SequenceI[] sqs = sgrps[sg].sg.getSequencesAsArray(null);
+ for (int si = 0; si < sqs.length; si++)
+ {
+ sgrps[sg].sg.deleteSequence(sqs[si], false);
+ }
+ sgrps[sg] = null;
+ }
+ }
+
+ /**
+ * construct an alignmentView from a SeqCigarArray. Errors are thrown if the
+ * seqcigararray.isSeqCigarArray() flag is not set.
+ */