Beispiel #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="aminoAcidSet"></param>
        /// <param name="shiftedMass"></param>
        /// <param name="isForward"></param>
        /// <param name="maxSequenceLength"></param>
        /// <param name="maxSequenceMass"></param>
        public ShiftedSequenceGraph(AminoAcidSet aminoAcidSet, double shiftedMass, bool isForward, int maxSequenceLength, double maxSequenceMass = 50000.0)
        {
            AminoAcidSet        = aminoAcidSet;
            _modificationParams = aminoAcidSet.GetModificationParams();

            _isForward = isForward;

            _index           = 0;
            _maxSeqIndex     = maxSequenceLength + 2; // shift + Term + length
            _maxSequenceMass = maxSequenceMass;

            _aminoAcidSequence = new AminoAcid[_maxSeqIndex];
            var shiftAa = new AminoAcid('\0', "Shift", new CompositionWithDeltaMass(shiftedMass));

            _aminoAcidSequence[0] = shiftAa;

            ShiftMass = shiftedMass;

            _fragmentComposition    = new Composition.Composition[_maxSeqIndex];
            _fragmentComposition[0] = shiftAa.Composition;

            _graph    = new Node[_maxSeqIndex][];
            _graph[0] = new[] { new Node(0) };

            _nodeComposition     = new Composition.Composition[_maxSeqIndex][];
            _compNodeComposition = new Composition.Composition[_maxSeqIndex][];
            for (var i = 0; i < _maxSeqIndex; i++)
            {
                _compNodeComposition[i] = new Composition.Composition[_modificationParams.NumModificationCombinations];
                _nodeComposition[i]     = new Composition.Composition[_modificationParams.NumModificationCombinations];
            }

            IsValid = true;
        }
        protected IntRange GetMinMaxChargeRange(Composition.Composition fragmentComposition)
        {
            var mostAbundantIsotopeIndex = fragmentComposition.GetMostAbundantIsotopeZeroBasedIndex();
            var fragmentIonMostAbuMass   = fragmentComposition.Mass + Constants.C13MinusC12 * mostAbundantIsotopeIndex;

            return(GetMinMaxChargeRange(fragmentIonMostAbuMass));
        }
Beispiel #3
0
        public ShiftedSequenceGraph(AminoAcidSet aminoAcidSet, double shiftedMass, bool isForward, int maxSequenceLength, double maxSequenceMass = 50000.0)
        {
            _aminoAcidSet = aminoAcidSet;
            _modificationParams = aminoAcidSet.GetModificationParams();

            _isForward = isForward;

            _index = 0;
            _maxSeqIndex = maxSequenceLength + 2;   // shift + Term + length
            _maxSequenceMass = maxSequenceMass;

            _aminoAcidSequence = new AminoAcid[_maxSeqIndex];
            var shiftAa = new AminoAcid('\0', "Shift", new CompositionWithDeltaMass(shiftedMass));
            _aminoAcidSequence[0] = shiftAa;

            ShiftMass = shiftedMass;

            _fragmentComposition = new Composition.Composition[_maxSeqIndex];
            _fragmentComposition[0] = shiftAa.Composition;

            _graph = new Node[_maxSeqIndex][];
            _graph[0] = new[] { new Node(0) };

            _nodeComposition = new Composition.Composition[_maxSeqIndex][]; 
            _compNodeComposition = new Composition.Composition[_maxSeqIndex][];
            for (var i = 0; i < _maxSeqIndex; i++)
            {
                _compNodeComposition[i] = new Composition.Composition[_modificationParams.NumModificationCombinations];
                _nodeComposition[i] = new Composition.Composition[_modificationParams.NumModificationCombinations];
            }

            IsValid = true;
        }
Beispiel #4
0
 public AminoAcid(char residue, string name, Composition.Composition comp)
 {
     Residue      = residue;
     Name         = name;
     Composition  = comp;
     Mass         = Composition.Mass;
     _nominalMass = Composition.NominalMass;
 }
Beispiel #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="prefixComposition"></param>
        /// <param name="prefixResidue"></param>
        /// <param name="suffixComposition"></param>
        /// <param name="suffixResidue"></param>
        public Cleavage(Composition.Composition prefixComposition, AminoAcid prefixResidue, Composition.Composition suffixComposition, AminoAcid suffixResidue)
        {
            PrefixComposition = prefixComposition;
            SuffixComposition = suffixComposition;

            PrefixResidue = prefixResidue;
            SuffixResidue = suffixResidue;
        }
Beispiel #6
0
 public IonType(string name, Composition.Composition offsetComposition,
                int charge, bool isPrefixIon)
 {
     Name = name;
     OffsetComposition = offsetComposition;
     Charge            = charge;
     IsPrefixIon       = isPrefixIon;
     BaseIonType       = null;
     _offsetMass       = offsetComposition.Mass;
 }
Beispiel #7
0
 /// <summary>
 /// Gets all possible compositions of the current sequence
 /// </summary>
 /// <returns>all possible compositions</returns>
 public Composition.Composition[] GetSequenceCompositions()
 {
     var numCompositions = _graph[_index].Length;
     var compositions = new Composition.Composition[numCompositions];
     for (var modIndex = 0; modIndex < numCompositions; modIndex++)
     {
         compositions[modIndex] = GetComposition(_index, modIndex);
     }
     return compositions;
 }
Beispiel #8
0
        /// <summary>
        /// Gets all possible compositions of the current sequence
        /// </summary>
        /// <returns>all possible compositions</returns>
        public Composition.Composition[] GetSequenceCompositions()
        {
            var numCompositions = _graph[_index].Length;
            var compositions    = new Composition.Composition[numCompositions];

            for (var modIndex = 0; modIndex < numCompositions; modIndex++)
            {
                compositions[modIndex] = GetComposition(_index, modIndex);
            }
            return(compositions);
        }
Beispiel #9
0
        public static Modification RegisterAndGetModification(string name, Composition.Composition composition)
        {
            var mod = Get(name);

            if (mod != null)
            {
                return(mod);
            }

            mod = new Modification(-1, composition, name);
            Register(mod);
            return(mod);
        }
Beispiel #10
0
        /// <summary>
        /// Build a sequence from the supplied list of amino acids
        /// </summary>
        /// <param name="aaArr"></param>
        public Sequence(IEnumerable <AminoAcid> aaArr)
        {
            var aminoAcids = aaArr as IList <AminoAcid> ?? aaArr.ToList();

            PrefixComposition    = new Composition.Composition[aminoAcids.Count + 1];
            PrefixComposition[0] = Data.Composition.Composition.Zero;
            for (var i = 0; i < aminoAcids.Count; i++)
            {
                var aa = aminoAcids[i] ?? AminoAcid.Empty;
                Add(aa);
                PrefixComposition[i + 1] = PrefixComposition[i] + aa.Composition;
            }

            Composition = PrefixComposition[aminoAcids.Count];
            _prefixMass = PrefixComposition.Select(c => c.Mass).ToArray();
        }
Beispiel #11
0
        private readonly double _offsetMass;    // duplication but stored for performance

        internal IonType(
            string name,
            Composition.Composition offsetComposition,
            int charge,
            BaseIonType baseIonType,
            NeutralLoss neutralLoss
            )
        {
            Name              = name;
            _offsetMass       = offsetComposition.Mass;
            OffsetComposition = offsetComposition;
            Charge            = charge;
            IsPrefixIon       = baseIonType.IsPrefix;
            BaseIonType       = baseIonType;
            NeutralLoss       = neutralLoss;
        }
Beispiel #12
0
        /// <summary>
        /// Generate a sequence graph for the provided data
        /// </summary>
        /// <param name="aminoAcidSet"></param>
        /// <param name="nTerm"></param>
        /// <param name="sequence"></param>
        /// <param name="cTerm"></param>
        protected SequenceGraph(AminoAcidSet aminoAcidSet, AminoAcid nTerm, string sequence, AminoAcid cTerm)
        {
            _aminoAcidSet = aminoAcidSet;
            _sequence     = sequence;
            _nTerm        = nTerm;

            _modificationParams = aminoAcidSet.GetModificationParams();

            _maxSeqIndex = sequence.Length + 3;  // init + C-term + sequence length + N-term

            _index = 0;

            _aminoAcidSequence    = new AminoAcid[_maxSeqIndex];
            _aminoAcidSequence[0] = AminoAcid.Empty;

            _suffixComposition    = new Composition.Composition[_maxSeqIndex];
            _suffixComposition[0] = Composition.Composition.Zero;

            _graph    = new Node[_maxSeqIndex][];
            _graph[0] = new[] { new Node(0) };

            _nodeComposition     = new Composition.Composition[_maxSeqIndex][]; //, _modificationParams.NumModificationCombinations];
            _compNodeComposition = new Composition.Composition[_maxSeqIndex][]; //, _modificationParams.NumModificationCombinations];

            for (var i = 0; i < _maxSeqIndex; i++)
            {
                _compNodeComposition[i] = new Composition.Composition[_modificationParams.NumModificationCombinations];
                _nodeComposition[i]     = new Composition.Composition[_modificationParams.NumModificationCombinations];
            }

            NumNTermCleavages = 0;
            IsValid           = true;
            SetNTerminalAminoAcid(nTerm);
            AddAminoAcid(cTerm.Residue);
            for (var i = sequence.Length - 1; i >= 0; i--)
            {
                if (AddAminoAcid(sequence[i]) == false)
                {
                    IsValid = false;
                    break;
                }
            }
            if (IsValid)
            {
                AddAminoAcid(nTerm.Residue);
            }
        }
        protected IEnumerable <DeconvolutedPeak> FindMatchedPeaks(Composition.Composition fragmentComposition,
                                                                  double corrThreshold, double distThreshold)
        {
            var mostAbundantIsotopeIndex = fragmentComposition.GetMostAbundantIsotopeZeroBasedIndex();
            var fragmentIonMass          = fragmentComposition.Mass;

            //var matchedPeak = new MatchedFragmentPeak();
            //var deconvPeak = new DeconvolutedPeak()
            if (fragmentIonMass < Ms2Spectrum.Peaks.First().Mz)
            {
                yield break;
            }

            var prevObservedCharge     = 0;
            var fragmentIonMostAbuMass = fragmentIonMass + Constants.C13MinusC12 * mostAbundantIsotopeIndex;
            var chargeRange            = GetMinMaxChargeRange(fragmentIonMostAbuMass);

            for (var charge = chargeRange.Min; charge <= chargeRange.Max; charge++)
            {
                var ion = new Ion(fragmentComposition, charge);

                var observedPeaks = Ms2Spectrum.GetAllIsotopePeaks(ion, Tolerance, RelativeIsotopeIntensityThreshold);
                if (observedPeaks == null)
                {
                    if (prevObservedCharge > 0 && charge - prevObservedCharge > 1)
                    {
                        yield break;
                    }
                    continue;
                }

                var distCorr = GetDistCorr(ion, observedPeaks);
                if (distCorr.Item2 < corrThreshold && distCorr.Item1 > distThreshold)
                {
                    if (prevObservedCharge > 0 && charge - prevObservedCharge > 1)
                    {
                        yield break;
                    }
                    continue;
                }
                var matchedPeak = new DeconvolutedPeak(fragmentIonMass, observedPeaks[mostAbundantIsotopeIndex].Intensity, charge, distCorr.Item2, distCorr.Item1, observedPeaks);
                prevObservedCharge = charge;

                yield return(matchedPeak);
            }
        }
        /*
         * protected Peak[] FindMostAbundantPeak(Composition.Composition fragmentComposition,
         *         double corrThreshold, double distThreshold,
         *         out int observedCharge, out double envelopeCorr, out double envelopeDist)
         * {
         *  //Peak[] intenseObservedPeaks = null;
         *  var mostAbundantIsotopeIndex = fragmentComposition.GetMostAbundantIsotopeZeroBasedIndex();
         *  var fragmentIonMass = fragmentComposition.Mass;
         *  observedCharge = 0;
         *  envelopeCorr = 0d;
         *  envelopeDist = 1.0d;
         *
         *  if (fragmentIonMass < Ms2Spectrum.Peaks.First().Mz) return null;
         *
         *  var fragmentIonMostAbuMass = fragmentIonMass + Constants.C13MinusC12 * mostAbundantIsotopeIndex;
         *  var chargeRange = GetMinMaxChargeRange(fragmentIonMostAbuMass);
         *
         *  for (var charge = chargeRange.Min; charge <= chargeRange.Max; charge++)
         *  {
         *      var ion = new Ion(fragmentComposition, charge);
         *
         *      var observedPeaks = Ms2Spectrum.GetAllIsotopePeaks(ion, Tolerance, RelativeIsotopeIntensityThreshold);
         *      if (observedPeaks == null) continue;
         *
         *      var distCorr = GetDistCorr(ion, observedPeaks);
         *      if (distCorr.Item2 < corrThreshold && distCorr.Item1 > distThreshold) continue;
         *      //var mostAbuPeak = observedPeaks[mostAbundantIsotopeIndex];
         *      //if (intenseObservedPeaks == null || mostAbuPeak.Intensity > intenseObservedPeaks[mostAbundantIsotopeIndex].Intensity)
         *      //{
         *          //intenseObservedPeaks = observedPeaks;
         *      observedCharge = charge;
         *      envelopeDist = distCorr.Item1;
         *      envelopeCorr = distCorr.Item2;
         *      return observedPeaks;
         *      //}
         *  }
         *  return null;
         * }
         */
        protected Peak[] FindMostIntensePeak(Composition.Composition fragmentComposition, double corrThreshold, double distThreshold, out int observedCharge, out double envelopeCorr, out double envelopeDist)
        {
            Peak[] intenseObservedPeaks     = null;
            var    mostAbundantIsotopeIndex = fragmentComposition.GetMostAbundantIsotopeZeroBasedIndex();
            var    fragmentIonMass          = fragmentComposition.Mass;

            observedCharge = 0;
            envelopeCorr   = 0d;
            envelopeDist   = 1.0d;

            if (fragmentIonMass < Ms2Spectrum.Peaks.First().Mz)
            {
                return(null);
            }

            var fragmentIonMostAbuMass = fragmentIonMass + Constants.C13MinusC12 * mostAbundantIsotopeIndex;
            var chargeRange            = GetMinMaxChargeRange(fragmentIonMostAbuMass);

            for (var charge = chargeRange.Min; charge <= chargeRange.Max; charge++)
            {
                var ion = new Ion(fragmentComposition, charge);

                var observedPeaks = Ms2Spectrum.GetAllIsotopePeaks(ion, Tolerance, RelativeIsotopeIntensityThreshold);
                if (observedPeaks == null)
                {
                    continue;
                }

                var distCorr = GetDistCorr(ion, observedPeaks);
                if (distCorr.Item2 < corrThreshold && distCorr.Item1 > distThreshold)
                {
                    continue;
                }
                var mostAbuPeak = observedPeaks[mostAbundantIsotopeIndex];

                if (intenseObservedPeaks == null || mostAbuPeak.Intensity > intenseObservedPeaks[mostAbundantIsotopeIndex].Intensity)
                {
                    intenseObservedPeaks = observedPeaks;
                    observedCharge       = charge;
                    envelopeDist         = distCorr.Item1;
                    envelopeCorr         = distCorr.Item2;
                }
            }
            return(intenseObservedPeaks);
        }
Beispiel #15
0
        /// <summary>
        /// Find a neutral monoisotopic peak corrsponding to a single compound/
        /// </summary>
        /// <param name="composition">The compound to look for.</param>
        /// <param name="tolerance">The peak tolerance to use.</param>
        /// <returns>The neutral monoisotopic peak.</returns>
        public DeconvolutedPeak FindPeak(Composition.Composition composition, Tolerance tolerance)
        {
            double           mass             = composition.Mass;
            DeconvolutedPeak deconvolutedPeak = null;
            double           maxIntensity     = 0.0;

            for (int charge = this.minCharge; charge <= this.maxCharge; charge++)
            {
                var ion          = new Ion(composition, charge);
                var isotopePeaks = this.spectrum.GetAllIsotopePeaks(ion, tolerance);
                var intensity    = isotopePeaks.Max(peak => peak.Intensity);
                var corrCos      = this.GetCorrCos(ion, isotopePeaks);
                if (intensity > maxIntensity)
                {
                    deconvolutedPeak = new DeconvolutedPeak(mass, intensity, charge, corrCos.Item1, corrCos.Item2, isotopePeaks);
                }
            }

            return(deconvolutedPeak);
        }
Beispiel #16
0
        // Added by Chris
        /// <summary>
        /// Register a new modification or update existing modification.
        /// </summary>
        /// <param name="name">The name of the modification.</param>
        /// <param name="composition">The composition of the modification.</param>
        /// <returns>Registered modification.</returns>
        public static Modification UpdateAndGetModification(string name, Composition.Composition composition)
        {
            if (NameToModMap.ContainsKey(name))
            {
                NameToModMap.Remove(name);
            }

            var massStr = string.Format("{0:N3}", composition.Mass);

            if (MassToModMap.ContainsKey(massStr))
            {
                MassToModMap.Remove(massStr);
            }

            var modification = new Modification(-1, composition, name);

            Register(modification);

            return(modification);
        }
Beispiel #17
0
        // Added by Chris
        /// <summary>
        /// Register a new modification or update existing modification.
        /// </summary>
        /// <param name="name">The name of the modification.</param>
        /// <param name="composition">The composition of the modification.</param>
        /// <returns>Registered modification.</returns>
        public static Modification UpdateAndGetModification(string name, Composition.Composition composition)
        {
            // Names should be case-insensitive.
            var lowerName = name.ToLower();

            if (NameToModMap.ContainsKey(lowerName))
            {
                NameToModMap.Remove(lowerName);
            }

            var massStr = string.Format(MOD_MASS_FORMAT_STRING, composition.Mass);

            if (MassToModMap.ContainsKey(massStr))
            {
                MassToModMap.Remove(massStr);
            }

            // Use original-cased name in modification object.
            var modification = new Modification(-1, composition, name);

            Register(modification);

            return(modification);
        }
Beispiel #18
0
 /// <summary>
 /// Get possible ions for <paramref name="cutComposition"/> and <paramref name="terminalResidue"/>
 /// </summary>
 /// <param name="cutComposition"></param>
 /// <param name="terminalResidue"></param>
 /// <returns></returns>
 public IEnumerable <Ion> GetPossibleIons(Composition.Composition cutComposition, AminoAcid terminalResidue)
 {
     return(BaseIonType.GetPossibleCompositions(terminalResidue)
            .Select(offsetComposition => cutComposition + offsetComposition - NeutralLoss.Composition)
            .Select(comp => new Ion(comp, Charge)));
 }
 public abstract double GetFragmentScore(Composition.Composition prefixFragmentComposition, Composition.Composition suffixFragmentComposition);
Beispiel #20
0
 private BaseIonType(string symbol, bool isPrefix, Composition.Composition offsetComposition)
 {
     Symbol            = symbol;
     IsPrefix          = isPrefix;
     OffsetComposition = offsetComposition;
 }
Beispiel #21
0
 public double GetMz(Composition.Composition prefixComposition)
 {
     Debug.Assert(prefixComposition != null, "prefixComposition must not be null");
     return(GetMz(prefixComposition.Mass));
 }
Beispiel #22
0
 public Cleavage(Composition.Composition prefixComposition, Composition.Composition suffixComposition)
 {
     PrefixComposition = prefixComposition;
     SuffixComposition = suffixComposition;
 }
Beispiel #23
0
        protected SequenceGraph(AminoAcidSet aminoAcidSet, AminoAcid nTerm, string sequence, AminoAcid cTerm)
        {
            _aminoAcidSet = aminoAcidSet;
            _sequence = sequence;
            _nTerm = nTerm;

            _modificationParams = aminoAcidSet.GetModificationParams();

            _maxSeqIndex = sequence.Length + 3;  // init + C-term + sequence length + N-term

            _index = 0;

            _aminoAcidSequence = new AminoAcid[_maxSeqIndex];
            _aminoAcidSequence[0] = AminoAcid.Empty;

            _suffixComposition = new Composition.Composition[_maxSeqIndex];
            _suffixComposition[0] = Composition.Composition.Zero;

            _graph = new Node[_maxSeqIndex][];
            _graph[0] = new[] { new Node(0) };

            _nodeComposition = new Composition.Composition[_maxSeqIndex][]; //, _modificationParams.NumModificationCombinations];
            _compNodeComposition = new Composition.Composition[_maxSeqIndex][]; //, _modificationParams.NumModificationCombinations];
            
            for (var i = 0; i < _maxSeqIndex; i++)
            {
                _compNodeComposition[i] = new Composition.Composition[_modificationParams.NumModificationCombinations];
                _nodeComposition[i] = new Composition.Composition[_modificationParams.NumModificationCombinations];
            }
            
            NumNTermCleavages = 0;
            IsValid = true;
            SetNTerminalAminoAcid(nTerm);
            AddAminoAcid(cTerm.Residue);
            for (var i = sequence.Length - 1; i >= 0; i--)
            {
                if (AddAminoAcid(sequence[i]) == false)
                {
                    IsValid = false;
                    break;
                }
            }
            if (IsValid) AddAminoAcid(nTerm.Residue);
        }
Beispiel #24
0
 /// <summary>
 /// Get the peak that matches <paramref name="composition"/> and <paramref name="tolerance"/>
 /// </summary>
 /// <param name="composition"></param>
 /// <param name="tolerance"></param>
 /// <returns></returns>
 public DeconvolutedPeak FindPeak(Composition.Composition composition, Tolerance tolerance)
 {
     return(base.FindPeak(composition.Mass, tolerance) as DeconvolutedPeak);
 }
Beispiel #25
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="name"></param>
 /// <param name="symbol"></param>
 /// <param name="composition"></param>
 public NeutralLoss(string name, string symbol, Composition.Composition composition)
 {
     Symbol      = symbol;
     Name        = name;
     Composition = composition;
 }
Beispiel #26
0
 public Ion GetIon(Composition.Composition cutComposition)
 {
     return(new Ion(cutComposition + OffsetComposition, Charge));
 }
Beispiel #27
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="accessionNum"></param>
 /// <param name="composition"></param>
 /// <param name="name"></param>
 public Modification(int accessionNum, Composition.Composition composition, string name)
 {
     AccessionNum = accessionNum;
     Composition  = composition;
     Name         = name;
 }
Beispiel #28
0
 public NeutralLoss(string name, Composition.Composition composition)
 {
     Name        = name;
     Composition = composition;
 }
Beispiel #29
0
 public Ion(Composition.Composition composition, int charge)
 {
     Composition = composition;
     Charge      = charge;
 }
Beispiel #30
0
        protected override void WriteXmlBase(System.Xml.XmlWriter writer)
        {
            base.WriteXmlBase(writer);

            string prefix    = RmXmlSerializer.UseOpenEhrPrefix(writer);
            string xsiPrefix = RmXmlSerializer.UseXsiPrefix(writer);

            writer.WriteStartElement("uid", RmXmlSerializer.OpenEhrNamespace);
            this.Uid.WriteXml(writer);
            writer.WriteEndElement();

            if (this.Data != null)
            {
                writer.WriteStartElement("data", RmXmlSerializer.OpenEhrNamespace);

                OpenEhr.RM.Common.Archetyped.Impl.Locatable dataLocatable = this.Data
                                                                            as OpenEhr.RM.Common.Archetyped.Impl.Locatable;
                if (dataLocatable == null)
                {
                    throw new NotSupportedException("Only support locatable as version data: "
                                                    + Data.GetType().Name);
                }
                string dataType = ((IRmType)dataLocatable).GetRmTypeName();
                if (!string.IsNullOrEmpty(prefix))
                {
                    dataType = prefix + ":" + dataType;
                }
                writer.WriteAttributeString(xsiPrefix, "type", RmXmlSerializer.XsiNamespace, dataType);
                Composition.Composition com = this.Data as Composition.Composition;
                com.WriteXml(writer);
                writer.WriteEndElement();
            }

            if (this.PrecedingVersionUid != null)
            {
                writer.WriteStartElement("preceding_version_uid", RmXmlSerializer.OpenEhrNamespace);
                this.PrecedingVersionUid.WriteXml(writer);
                writer.WriteEndElement();
            }

            // otherInputVersionUids
            if (this.OtherInputVersionUids != null)
            {
                foreach (ObjectVersionId objectVersionId in this.OtherInputVersionUids)
                {
                    writer.WriteStartElement("other_input_version_uids", RmXmlSerializer.OpenEhrNamespace);
                    objectVersionId.WriteXml(writer);
                    writer.WriteEndElement();
                }
            }

            // attestation
            if (this.Attestations != null)
            {
                foreach (Generic.Attestation a in this.Attestations)
                {
                    writer.WriteStartElement("attestations", RmXmlSerializer.OpenEhrNamespace);
                    a.WriteXml(writer);
                    writer.WriteEndElement();
                }
            }

            writer.WriteStartElement("lifecycle_state", RmXmlSerializer.OpenEhrNamespace);
            this.LifecycleState.WriteXml(writer);
            writer.WriteEndElement();
        }