private float? _rPass1 = float.NaN; //  float.NaN;

        #endregion Fields

        #region Constructors

        public RGen1Pass1( ImportDataSet dsImport, LinksDataSet dsLinks, LinksDataSet.tblRelatedStructureRow drLeft, LinksDataSet.tblRelatedStructureRow drRight )
        {
            if ( dsImport == null ) throw new ArgumentNullException("dsImport");
            if ( dsLinks == null ) throw new ArgumentNullException("dsLinks");
            if ( drLeft == null ) throw new ArgumentNullException("drLeft");
            if ( drRight == null ) throw new ArgumentNullException("drRight");
            if ( dsImport.tblLinks2004Gen1.Count == 0 ) throw new InvalidOperationException("tblLinks2004Gen1 must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblMzManual.Count == 0 ) throw new InvalidOperationException("tblMzManual must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblSubject.Count == 0 ) throw new InvalidOperationException("tblSubject must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblRosterGen1.Count == 0 ) throw new InvalidOperationException("tblRosterGen1 must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblMarkerGen1.Count == 0 ) throw new InvalidOperationException("tblMarkerGen2 must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblSubjectDetails.Count == 0 ) throw new InvalidOperationException("tblSubjectDetails must NOT be empty before assigning R values from it.");

            _dsImport = dsImport;
            _dsLinks = dsLinks;
            _drLeft = drLeft;
            _drRight = drRight;
            _idRelatedLeft = _drLeft.ID;
            _idRelatedRight = _drRight.ID;
            _drSubjectDetails1 = _dsLinks.tblSubjectDetails.FindBySubjectTag(drLeft.SubjectTag_S1);
            _drSubjectDetails2 = _dsLinks.tblSubjectDetails.FindBySubjectTag(drLeft.SubjectTag_S2);
            _extendedID = _drLeft.tblSubjectRowByFK_tblRelatedStructure_tblSubject_Subject1.ExtendedID;

            //LinksDataSet.tblRosterGen1Row drRoster = _dsLinks.tblRosterGen1.FindByRelatedID(drLeft.ID);
            //Tristate rosterShareBiomom = (Tristate)drRoster.ShareBiomom;
            //Tristate rosterShareBiodad = (Tristate)drRoster.ShareBiodad;
            //if ( drRoster.IsRNull() ) _rRoster = null;
            //else _rRoster = (float)drRoster.R;

            if ( _drSubjectDetails1.BirthOrderInNls <= _drSubjectDetails2.BirthOrderInNls ) {//This is the way it usually is.  Remember that twins were assigned tied birth orders
                _idRelatedOlderAboutYounger = _idRelatedLeft;
                _idRelatedYoungerAboutOlder = _idRelatedRight;
            }
            else if ( _drSubjectDetails1.BirthOrderInNls > _drSubjectDetails2.BirthOrderInNls ) {
                _idRelatedOlderAboutYounger = _idRelatedRight;
                _idRelatedYoungerAboutOlder = _idRelatedLeft;
            }

            _dtMarkersGen1 = MarkerGen1.PairRelevantMarkerRows(_idRelatedLeft, _idRelatedRight, _dsLinks, _extendedID);

            LinksDataSet.tblMzManualRow drMz = Retrieve.MzManualRecord(_drLeft.SubjectTag_S1, _drLeft.SubjectTag_S2, _dsLinks);

            if ( drMz == null ) {
                _multipleBirth = MultipleBirth.No;
                _isMZ = Tristate.No;
                _isRelatedInMzManual = Tristate.DoNotKnow;
            }
            else {
                _multipleBirth = (MultipleBirth)drMz.MultipleBirthIfSameSex;
                _isMZ = (Tristate)drMz.IsMz;
                if ( drMz.IsRelatedNull() ) _isRelatedInMzManual = Tristate.DoNotKnow;
                else if ( drMz.Related ) _isRelatedInMzManual = Tristate.Yes;
                else _isRelatedInMzManual = Tristate.No;
            }

            MarkerEvidence explicitBiomomFromOlder = ReduceShareBioparentToOne(MarkerType.ShareBiomom, ItemYears.Gen1ShareBioparent.Length, _idRelatedOlderAboutYounger);
            MarkerEvidence explicitBiodadFromOlder = ReduceShareBioparentToOne(MarkerType.ShareBiodad, ItemYears.Gen1ShareBioparent.Length, _idRelatedOlderAboutYounger);
            MarkerEvidence explicitBiomomFromYounger = ReduceShareBioparentToOne(MarkerType.ShareBiomom, ItemYears.Gen1ShareBioparent.Length, _idRelatedYoungerAboutOlder);
            MarkerEvidence explicitBiodadFromYounger = ReduceShareBioparentToOne(MarkerType.ShareBiodad, ItemYears.Gen1ShareBioparent.Length, _idRelatedYoungerAboutOlder);

            MarkerEvidence biomomInHH1979 = MarkerGen1.RetrieveParentMarkerMultiYear(_idRelatedOlderAboutYounger, MarkerType.Gen1BiomomInHH, 1979, Bioparent.Mom, _dtMarkersGen1);
            MarkerEvidence biodadInHH1979 = MarkerGen1.RetrieveParentMarkerMultiYear(_idRelatedOlderAboutYounger, MarkerType.Gen1BiodadInHH, 1979, Bioparent.Dad, _dtMarkersGen1);

            MarkerEvidence biomomDeathAge = MarkerGen1.RetrieveParentMarkerSingleYear(_idRelatedOlderAboutYounger, MarkerType.Gen1BiomomDeathAge, Bioparent.Mom, _dtMarkersGen1);
            MarkerEvidence biodadDeathAge = MarkerGen1.RetrieveParentMarkerSingleYear(_idRelatedOlderAboutYounger, MarkerType.Gen1BiodadDeathAge, Bioparent.Dad, _dtMarkersGen1);

            _explicitShareBiomomPass1 = CommonFunctions.TranslateEvidenceToTristate(explicitBiomomFromOlder, explicitBiomomFromYounger);
            _explicitShareBiodadPass1 = CommonFunctions.TranslateEvidenceToTristate(explicitBiodadFromOlder, explicitBiodadFromYounger);

            _implicitShareBiomomPass1 = ImplicitShareBioparent(inHH1979: biomomInHH1979, deathAge: biomomDeathAge);
            _implicitShareBiodadPass1 = ImplicitShareBioparent(inHH1979: biodadInHH1979, deathAge: biodadDeathAge);

            _shareBiomomPass1 = CommonFunctions.TakePriority(_explicitShareBiomomPass1, _implicitShareBiomomPass1);
            _shareBiodadPass1 = CommonFunctions.TakePriority(_explicitShareBiodadPass1, _implicitShareBiodadPass1);

            _rExplicitOldestSibVersion = CalculateRExplicitSingleSibVersion(explicitBiomomFromOlder, explicitBiodadFromOlder);
            _rExplicitYoungestSibVersion = CalculateRExplicitSingleSibVersion(explicitBiomomFromYounger, explicitBiodadFromYounger);
            _rExplicitPass1 = CommonFunctions.TranslateToR(shareBiomom: _explicitShareBiomomPass1, shareBiodad: _explicitShareBiodadPass1, mustDecide: false);

            _rImplicitPass1 = CommonFunctions.TranslateToR(shareBiomom: _implicitShareBiomomPass1, shareBiodad: _implicitShareBiodadPass1, mustDecide: false);
            _rImplicit2004 = RetrieveRImplicit2004();

            _rPass1 = CalculateRFull(shareBiomom: _shareBiomomPass1, shareBiodad: _shareBiodadPass1,
                multiple: _multipleBirth, isMZ: _isMZ, isRelatedInMZManual: _isRelatedInMzManual, idRelated: _idRelatedLeft, dtRoster: _dsLinks.tblRosterGen1);
        }
 internal static LinksDataSet.tblMarkerGen1DataTable PairRelevantMarkerRows( Int64 relatedIDLeft, Int64 relatedIDRight, LinksDataSet dsLinks, Int32 extendedID )
 {
     string select = string.Format("{0}={1} AND {2} IN ({3},{4})",
         extendedID, dsLinks.tblMarkerGen1.ExtendedIDColumn.ColumnName,
         dsLinks.tblMarkerGen1.RelatedIDColumn.ColumnName, relatedIDLeft, relatedIDRight);
     LinksDataSet.tblMarkerGen1Row[] drs = (LinksDataSet.tblMarkerGen1Row[])dsLinks.tblMarkerGen1.Select(select);
     //if ( drs.Length <= 0 ) {
     //   return null;
     //}
     //else {
     LinksDataSet.tblMarkerGen1DataTable dt = new LinksDataSet.tblMarkerGen1DataTable();
     foreach ( LinksDataSet.tblMarkerGen1Row dr in drs ) {
         dt.ImportRow(dr);
     }
     return dt;
 }
        private float? _rPeek = null; //float.NaN;

        #endregion Fields

        #region Constructors

        public RGen1Pass2( LinksDataSet dsLinks, LinksDataSet.tblRelatedStructureRow drLeft, LinksDataSet.tblRelatedStructureRow drRight )
        {
            if ( dsLinks == null ) throw new ArgumentNullException("dsLinks");
            if ( drLeft == null ) throw new ArgumentNullException("drLeft");
            if ( drRight == null ) throw new ArgumentNullException("drRight");
            if ( dsLinks.tblRelatedValues.Count == 0 ) throw new InvalidOperationException("tblRelatedValues must be empty before updating rows for it.");
            if ( dsLinks.tblMzManual.Count == 0 ) throw new InvalidOperationException("tblMzManual must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblSubject.Count == 0 ) throw new InvalidOperationException("tblSubject must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblSubjectDetails.Count == 0 ) throw new InvalidOperationException("tblSubjectDetails must NOT be empty before assigning R values from it.");
            if ( dsLinks.tblMarkerGen1.Count == 0 ) throw new InvalidOperationException("tblMarkerGen1 must NOT be empty before assigning R values from it.");
            _dsLinks = dsLinks;
            _drLeft = drLeft;
            _drRight = drRight;
            _idRelatedLeft = _drLeft.ID;
            _idRelatedRight = _drRight.ID;
            _drSubjectDetails1 = _dsLinks.tblSubjectDetails.FindBySubjectTag(drLeft.SubjectTag_S1);
            _drSubjectDetails2 = _dsLinks.tblSubjectDetails.FindBySubjectTag(drLeft.SubjectTag_S2);
            _extendedID = _drLeft.tblSubjectRowByFK_tblRelatedStructure_tblSubject_Subject1.ExtendedID;

            if ( _drSubjectDetails1.BirthOrderInNls <= _drSubjectDetails2.BirthOrderInNls ) {//This is the way it usually is.  Recall twins were assigned tied birth orders
                _idRelatedOlderAboutYounger = _idRelatedLeft; //_idRelatedYoungerAboutOlder = _idRelatedRight;
            }
            else if ( _drSubjectDetails1.BirthOrderInNls > _drSubjectDetails2.BirthOrderInNls ) {
                _idRelatedOlderAboutYounger = _idRelatedRight;
            }

            _drValue = _dsLinks.tblRelatedValues.FindByID(_idRelatedLeft);
            _dtMarkersGen1 = MarkerGen1.PairRelevantMarkerRows(_idRelatedLeft, _idRelatedRight, _dsLinks, _extendedID);

            Tristate explicitShareBiomom = AddressExplicitBiomom();
            Tristate explicitShareBiodad = AddressExplicitBiodad();

            Tristate implicitShareBiomom = AddressImplicitBiomom();
            Tristate implicitShareBiodad = AddressImplicitBiodad();

            _rExplicit = CommonFunctions.TranslateToR(shareBiomom: explicitShareBiomom, shareBiodad: explicitShareBiodad, mustDecide: true);
            _rImplicit = CommonFunctions.TranslateToR(shareBiomom: implicitShareBiomom, shareBiodad: implicitShareBiodad, mustDecide: false);//Possibly 'true' later one

            //_rFull = RGen1Pass1.CalculateRFull(shareBiomom: shareBiomom, shareBiodad: shareBiodad,
            //   multiple: (MultipleBirth)_drValue.MultipleBirthIfSameSex, isMZ: (Tristate)_drValue.IsMz, isRelatedInMZManual: (Tristate)_drValue.IsRelatedInMzManual,
            //   idRelated: _idRelatedLeft, dtRoster: _dsLinks.tblRosterGen1);

            if ( !_drValue.IsRPass1Null() ) {
                _rFull = (float)_drValue.RPass1;
            }
            else { //Don't do the expensive interpolation unless it will be used
                Tristate shareBiomom = AddressBiomom(explicitShareBiomom, implicitShareBiomom);
                Tristate shareBiodad = AddressBiodad(explicitShareBiodad, implicitShareBiodad);
                _rFull = CommonFunctions.TranslateToR(shareBiomom: shareBiomom, shareBiodad: shareBiodad, mustDecide: true);
            }

            LinksDataSet.tblRosterGen1Row drRoster = _dsLinks.tblRosterGen1.FindByRelatedID(_drValue.ID);
            _r = CalculateR(_rFull, (Tristate)drRoster.SameGeneration);
        }