Пример #1
0
        public async Task <IActionResult> Login(string UserId, string Password)
        {
            Password = MD5Helpers.ComputeHash(Password);
            Account account = _accountService.GetLogin(UserId, Password);

            if (account?.Id > 0 && account?.Status == 0)
            {
                ClaimsIdentity identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim(ClaimTypes.Email, account.UserId, ClaimValueTypes.String));
                identity.AddClaim(new Claim(ClaimTypes.Name, account.UserName, ClaimValueTypes.String));
                await HttpContext.SignInAsync(new ClaimsPrincipal(identity), new AuthenticationProperties { ExpiresUtc = DateTime.UtcNow.AddHours(24) });

                return(RedirectToRoute("main"));
            }
            else
            {
                return(View());
            }
        }
Пример #2
0
        public Study ProcessData(XmlDocument d, DateTime?download_datetime)
        {
            Study s = new Study();

            // get date retrieved in object fetch
            // transfer to study and data object records

            List <StudyIdentifier>  study_identifiers  = new List <StudyIdentifier>();
            List <StudyTitle>       study_titles       = new List <StudyTitle>();
            List <StudyReference>   study_references   = new List <StudyReference>();
            List <StudyContributor> study_contributors = new List <StudyContributor>();
            List <StudyTopic>       study_topics       = new List <StudyTopic>();


            List <DataObject>     data_objects          = new List <DataObject>();
            List <ObjectDataset>  object_datasets       = new List <ObjectDataset>();
            List <ObjectTitle>    data_object_titles    = new List <ObjectTitle>();
            List <ObjectInstance> data_object_instances = new List <ObjectInstance>();

            StringHelpers sh = new StringHelpers(_logger);
            MD5Helpers    hh = new MD5Helpers();

            // First convert the XML document to a Linq XML Document.

            XDocument xDoc = XDocument.Load(new XmlNodeReader(d));

            // Obtain the main top level elements of the registry entry.
            // In most cases study will have already been registered in CGT.
            XElement r = xDoc.Root;

            string sid = GetElementAsString(r.Element("sd_sid"));

            s.sd_sid = sid;
            s.datetime_of_data_fetch = download_datetime;

            bool   is_yoda_only       = GetElementAsBool(r.Element("is_yoda_only"));
            string remote_url         = GetElementAsString(r.Element("remote_url"));
            string therapaeutic_area  = GetElementAsString(r.Element("therapaeutic_area"));
            string product_class      = GetElementAsString(r.Element("product_class"));
            string data_partner       = GetElementAsString(r.Element("data_partner"));
            string conditions_studied = GetElementAsString(r.Element("conditions_studied"));
            string last_revised_date  = GetElementAsString(r.Element("last_revised_date"));;

            string yoda_title = GetElementAsString(r.Element("yoda_title"));

            yoda_title      = sh.ReplaceApos(yoda_title);
            yoda_title      = sh.ReplaceTags(yoda_title);
            s.display_title = yoda_title;

            // display title derived from CTG during download, if possible
            string name_base_title = GetElementAsString(r.Element("name_base_title"));

            // this required for the moment until nct names improved
            name_base_title = sh.ReplaceApos(name_base_title);

            // In most cases the name_base will be the NCT title
            string name_base = string.IsNullOrEmpty(name_base_title) ? yoda_title : name_base_title;


            XElement st_titles = r.Element("study_titles");

            if (st_titles != null)
            {
                var titles = st_titles.Elements("Title");
                if (titles?.Any() == true)
                {
                    foreach (XElement t in titles)
                    {
                        string title_text    = sh.ReplaceApos(GetElementAsString(t.Element("title_text")));
                        int?   title_type_id = GetElementAsInt(t.Element("title_type_id"));
                        string title_type    = GetElementAsString(t.Element("title_type"));
                        bool   is_default    = GetElementAsBool(t.Element("is_default"));
                        string comments      = GetElementAsString(t.Element("comments"));
                        study_titles.Add(new StudyTitle(sid, title_text, title_type_id, title_type, is_default, comments));
                    }
                }
            }

            // brief description mostly as derived from CTG
            s.brief_description = GetElementAsString(r.Element("brief_description"));

            // temp for now until ctg descriptions are cleaner
            s.brief_description = sh.StringClean(s.brief_description);

            s.study_status_id = 21;
            s.study_status    = "Completed"; // assumption for entry onto web site

            // study type only really relevant for non registered studies (others will
            // have type identified in registered study entry
            // here, usuallypreviously obtained from the ctg or isrctn entry
            int?type_id = GetElementAsInt(r.Element("study_type_id"));

            s.study_type_id = type_id;
            switch (type_id)
            {
            case 11: s.study_type = "interventional"; break;

            case 12: s.study_type = "observational"; break;

            case 13: s.study_type = "observational patient registry"; break;

            case 14: s.study_type = "expanded access"; break;

            case 15: s.study_type = "funded programme"; break;

            case 16: s.study_type = "not yet known"; break;
            }


            string study_enrolment = GetElementAsString(r.Element("enrolment")).Trim();

            if (!string.IsNullOrEmpty(study_enrolment))
            {
                s.study_enrolment = study_enrolment;
            }

            string percent_female = GetElementAsString(r.Element("percent_female"));

            if (!string.IsNullOrEmpty(percent_female) && percent_female != "N/A")
            {
                if (percent_female.EndsWith("%"))
                {
                    percent_female = percent_female.Substring(0, percent_female.Length - 1);
                }

                if (Single.TryParse(percent_female, out float female_percentage))
                {
                    if (female_percentage == 0)
                    {
                        s.study_gender_elig_id = 910;
                        s.study_gender_elig    = "Male";
                    }
                    else if (female_percentage == 100)
                    {
                        s.study_gender_elig_id = 905;
                        s.study_gender_elig    = "Female";
                    }
                    else
                    {
                        s.study_gender_elig_id = 900;
                        s.study_gender_elig    = "All";
                    }
                }
            }
            else
            {
                s.study_gender_elig_id = 915;
                s.study_gender_elig    = "Not provided";
            }

            // transfer identifier data
            // Normally a protocol id will be the only addition (may be a duplicate of one already in the system)
            var study_idents = r.Element("study_identifiers")?.Elements("Identifier");

            if (study_idents?.Any() == true)
            {
                foreach (XElement i in study_idents)
                {
                    string identifier_value   = GetElementAsString(i.Element("identifier_value"));
                    int?   identifier_type_id = GetElementAsInt(i.Element("identifier_type_id"));
                    string identifier_type    = GetElementAsString(i.Element("identifier_type"));
                    int?   identifier_org_id  = GetElementAsInt(i.Element("identifier_org_id"));
                    string identifier_org     = sh.ReplaceApos(GetElementAsString(i.Element("identifier_org")));
                    study_identifiers.Add(new StudyIdentifier(sid, identifier_value, identifier_type_id, identifier_type,
                                                              identifier_org_id, identifier_org));
                }
            }


            // study contributors
            // only sponsor knowm, and only relevant for non registered studies (others will
            // have the sponsor identified in registered study entry).
            int?   sponsor_org_id; string sponsor_org;
            int?   sponsor_id = GetElementAsInt(r.Element("sponsor_id"));
            string sponsor    = GetElementAsString(r.Element("sponsor"));

            if (!string.IsNullOrEmpty(sponsor))
            {
                sponsor_org_id = sponsor_id;
                sponsor_org    = sh.TidyOrgName(sponsor, sid);
            }
            else
            {
                sponsor_org_id = null;
                sponsor_org    = "No organisation name provided in source data";
            }
            // If study registered elsewhere this wil be ignored during the aggregation
            study_contributors.Add(new StudyContributor(sid, 54, "Study Sponsor", sponsor_org_id, sponsor_org));


            // study topics
            string compound_generic_name = GetElementAsString(r.Element("compound_generic_name"));
            string compound_product_name = GetElementAsString(r.Element("compound_product_name"));

            if (!string.IsNullOrEmpty(compound_generic_name))
            {
                study_topics.Add(new StudyTopic(sid, 12, "chemical / agent", compound_generic_name));
            }

            if (!string.IsNullOrEmpty(compound_product_name))
            {
                string product_name = compound_product_name.Replace(((char)174).ToString(), "");    // drop reg mark
                product_name = product_name.Replace("   ", " ").Replace("  ", " ").Trim();

                // see if already exists
                bool add_product = true;
                foreach (StudyTopic t in study_topics)
                {
                    if (product_name.ToLower() == t.original_value.ToLower())
                    {
                        add_product = false;
                        break;
                    }
                }

                if (add_product)
                {
                    product_name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(product_name.ToLower());
                    study_topics.Add(new StudyTopic(sid, 12, "chemical / agent", product_name));
                }
            }

            if (!string.IsNullOrEmpty(conditions_studied))
            {
                study_topics.Add(new StudyTopic(sid, 13, "condition", conditions_studied));
            }

            // create study references (pmids)
            XElement refs = r.Element("study_references");

            if (refs != null)
            {
                var study_refs = refs.Elements("Reference");
                if (study_refs?.Any() == true)
                {
                    foreach (XElement sr in study_refs)
                    {
                        string pmid = GetElementAsString(sr.Element("pmid"));
                        string primary_citation_link = GetElementAsString(sr.Element("primary_citation_link"));
                        // normally only 1 if there is one there at all
                        study_references.Add(new StudyReference(sid, pmid, primary_citation_link, null, null));
                    }
                }
            }


            // data objects...

            // do the yoda web page itself first...
            string object_title         = "Yoda web page";
            string object_display_title = name_base + " :: " + "Yoda web page";

            // create hash Id for the data object
            string sd_oid = sid + " :: 38 :: " + object_title;

            data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, null, 23, "Text", 38, "Study Overview",
                                            101901, "Yoda", 12, download_datetime));
            data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 22,
                                                   "Study short name :: object type", true));
            data_object_instances.Add(new ObjectInstance(sd_oid, 101901, "Yoda",
                                                         remote_url, true, 35, "Web text"));

            // then for each supp doc...
            XElement sds = r.Element("supp_docs");

            if (sds != null)
            {
                var supp_docs = sds.Elements("SuppDoc");
                if (supp_docs?.Any() == true)
                {
                    foreach (XElement sd in supp_docs)
                    {
                        // get object_type
                        int    object_class_id = 0; string object_class = "";
                        int    object_type_id = 0; string object_type = "";
                        string doc_name = GetElementAsString(sd.Element("doc_name"));
                        string comment  = GetElementAsString(sd.Element("comment"));
                        string url      = GetElementAsString(sd.Element("url"));
                        object_title = doc_name;

                        switch (doc_name)
                        {
                        case "Collected Datasets":
                        {
                            object_type_id  = 80;
                            object_type     = "Individual participant data";
                            object_class_id = 14; object_class = "Datasets";
                            break;
                        }

                        case "Data Definition Specification":
                        {
                            object_type_id  = 31;
                            object_type     = "Data dictionary";
                            object_class_id = 23; object_class = "Text";
                            break;
                        }

                        case "Analysis Datasets":
                        {
                            object_type_id  = 51;
                            object_type     = "IPD final analysis datasets (full study population)";
                            object_class_id = 14; object_class = "Datasets";
                            break;
                        }

                        case "CSR Summary":
                        {
                            object_type_id  = 79;
                            object_type     = "CSR summary";
                            object_class_id = 23; object_class = "Text";
                            break;
                        }

                        case "Annotated Case Report Form":
                        {
                            object_type_id  = 30;
                            object_type     = "Annotated data collection forms";
                            object_class_id = 23; object_class = "Text";
                            break;
                        }

                        case "Statistical Analysis Plan":
                        {
                            object_type_id  = 22;
                            object_type     = "Statistical analysis plan";
                            object_class_id = 23; object_class = "Text";
                            break;
                        }

                        case "Protocol with Amendments":
                        {
                            object_type_id  = 11;
                            object_type     = "Study protocol";
                            object_class_id = 23; object_class = "Text";
                            break;
                        }

                        case "Clinical Study Report":
                        {
                            object_type_id  = 26;
                            object_type     = "Clinical study report";
                            object_class_id = 23; object_class = "Text";
                            break;
                        }
                        }

                        object_display_title = name_base + " :: " + object_type;
                        sd_oid = sid + " :: " + object_type_id.ToString() + " :: " + object_title;

                        if (comment == "Available now")
                        {
                            data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, null, object_class_id, object_class, object_type_id, object_type,
                                                            101901, "Yoda", 11, download_datetime));
                            data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 22, "Study short name :: object type", true));

                            // create instance as resource exists
                            // get file type from link if possible
                            int resource_type_id = 0; string resource_type = "";
                            if (url.ToLower().EndsWith(".pdf"))
                            {
                                resource_type_id = 11;
                                resource_type    = "PDF";
                            }
                            else if (url.ToLower().EndsWith(".xls"))
                            {
                                resource_type_id = 18;
                                resource_type    = "Excel Spreadsheet(s)";
                            }
                            else
                            {
                                resource_type_id = 0;
                                resource_type    = "Not yet known";
                            }
                            data_object_instances.Add(new ObjectInstance(sd_oid, 101901, "Yoda", url, true, resource_type_id, resource_type));
                        }
                        else
                        {
                            DateTime date_access_url_checked = new DateTime(2021, 7, 23);

                            string access_details = "The YODA Project will require that requestors provide basic information about the Principal Investigator, Key Personnel, and the ";
                            access_details += "project Research Proposal, including a scientific abstract and research methods.The YODA Project will review proposals to ensure that: ";
                            access_details += "1) the scientific purpose is clearly described; 2) the data requested will be used to enhance scientific and/or medical knowledge; and ";
                            access_details += "3) the proposed research can be reasonably addressed using the requested data.";

                            data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, null, object_class_id, object_class, object_type_id, object_type,
                                                            101901, "Yoda", 17, "Case by case download", access_details,
                                                            "https://yoda.yale.edu/how-request-data", date_access_url_checked, download_datetime));
                            data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 22, "Study short name :: object type", true));
                        }

                        // for datasets also add dataset properties - even if they are largely unknown
                        if (object_type_id == 80)
                        {
                            object_datasets.Add(new ObjectDataset(sd_oid, 0, "Not known", null,
                                                                  2, "De-identification applied",
                                                                  "Yoda states that “...researchers will be granted access to participant-level study data that are devoid of personally identifiable information; current best guidelines for de-identification of data will be used.”",
                                                                  0, "Not known", null));
                        }
                    }
                }
            }


            // add in the study properties
            s.identifiers  = study_identifiers;
            s.titles       = study_titles;
            s.references   = study_references;
            s.contributors = study_contributors;
            s.topics       = study_topics;

            s.data_objects     = data_objects;
            s.object_datasets  = object_datasets;
            s.object_titles    = data_object_titles;
            s.object_instances = data_object_instances;

            return(s);
        }
        public Study ProcessData(XmlDocument d, DateTime?download_datetime)
        {
            Study s = new Study();
            // get date retrieved in object fetch
            // transfer to study and data object records

            //List<StudyIdentifier> study_identifiers = new List<StudyIdentifier>();
            List <StudyTitle>       study_titles       = new List <StudyTitle>();
            List <StudyIdentifier>  study_identifiers  = new List <StudyIdentifier>();
            List <StudyReference>   study_references   = new List <StudyReference>();
            List <StudyContributor> study_contributors = new List <StudyContributor>();

            List <DataObject>     data_objects          = new List <DataObject>();
            List <ObjectDataset>  object_datasets       = new List <ObjectDataset>();
            List <ObjectTitle>    data_object_titles    = new List <ObjectTitle>();
            List <ObjectDate>     data_object_dates     = new List <ObjectDate>();
            List <ObjectInstance> data_object_instances = new List <ObjectInstance>();

            MD5Helpers    hh = new MD5Helpers();
            DateHelpers   dh = new DateHelpers();
            StringHelpers sh = new StringHelpers(_logger);

            char[] splitter = { '(' };

            // transfer features of main study object
            // In most cases study will have already been registered in CGT

            // First convert the XML document to a Linq XML Document.

            XDocument xDoc = XDocument.Load(new XmlNodeReader(d));

            // Obtain the main top level elements of the registry entry.

            XElement r = xDoc.Root;

            string sid = GetElementAsString(r.Element("sd_sid"));

            s.sd_sid = sid;
            s.datetime_of_data_fetch = download_datetime;

            // For the study, set up two titles, acronym and display title
            // NHLBI title not always exactly the same as the trial registry entry.

            string title = GetElementAsString(r.Element("title"));

            title = sh.ReplaceTags(title);
            title = sh.ReplaceApos(title);

            // study display title (= default title) always the biolincc one
            s.display_title = title;
            study_titles.Add(new StudyTitle(sid, title, 18, "Other scientific title", true, "From BioLINCC web page"));

            // but set up a 'name base' for data object names
            // which will be the CGT name if one exists as this is usually shorter
            // Only possible if the study is not one of those that are in a group,
            // collectively corresponding to a single NCT entry and public title,
            // and only for those where an nct entry exists (Some BioLincc studiues are not registered)

            string nct_name = GetElementAsString(r.Element("nct_base_name"));

            // this statement temporarily required until nct names improved
            nct_name = sh.ReplaceApos(nct_name);

            string name_base = "";
            bool   in_multiple_biolincc_group = GetElementAsBool(r.Element("in_multiple_biolincc_group"));

            if (!in_multiple_biolincc_group && !string.IsNullOrEmpty(nct_name))
            {
                name_base = nct_name;
            }
            else
            {
                name_base = title;
            }

            string acronym = GetElementAsString(r.Element("acronym"));

            if (!string.IsNullOrEmpty(acronym))
            {
                study_titles.Add(new StudyTitle(sid, acronym, 14, "Acronym or Abbreviation", false, "From BioLINCC web page"));
            }

            string brief_description = GetElementAsString(r.Element("brief_description"));

            s.brief_description = sh.StringClean(brief_description);


            s.study_type_id   = GetElementAsInt(r.Element("study_type_id"));
            s.study_type      = GetElementAsString(r.Element("study_type"));
            s.study_status_id = 21;
            s.study_status    = "Completed"; // assumption for entry onto web site

            // Gender eligibility is never provided for biolincc entries

            s.study_gender_elig_id = 915;
            s.study_gender_elig    = "Not provided";

            string study_period = GetElementAsString(r.Element("study_period"));

            study_period = study_period.Trim();
            if (study_period.Length > 3)
            {
                string first_four = study_period.Substring(0, 4);
                if (first_four == first_four.Trim())
                {
                    if (Int32.TryParse(first_four, out int start_year))
                    {
                        s.study_start_year = start_year;
                    }
                    else
                    {
                        // perhaps full month year - e.g. "December 2008..."
                        // Get first word
                        // Is it a month name? - if so, store the number
                        if (study_period.IndexOf(" ") != -1)
                        {
                            int    spacepos   = study_period.IndexOf(" ");
                            string month_name = study_period.Substring(0, spacepos);
                            if (Enum.TryParse <MonthsFull>(month_name, out MonthsFull month_enum))
                            {
                                // get value...
                                int start_month = (int)month_enum;

                                // ...and get next 4 characters - are they a year?
                                // if they are it is the start year
                                string next_four = study_period.Substring(spacepos + 1, 4);
                                if (Int32.TryParse(next_four, out start_year))
                                {
                                    s.study_start_month = start_month;
                                    s.study_start_year  = start_year;
                                }
                            }
                        }
                    }
                }
            }

            // Add study attribute records.
            string hbli_identifier = GetElementAsString(r.Element("accession_number"));

            // identifier type = NHBLI ID, id = 42, org = National Heart, Lung, and Blood Institute, id = 100167.
            study_identifiers.Add(new StudyIdentifier(sid, hbli_identifier, 42, "NHLBI ID", 100167, "National Heart, Lung, and Blood Institute (US)"));

            // If there is a NCT ID (there usually is...).
            var registry_ids = r.Element("registry_ids");

            if (registry_ids != null)
            {
                var ids = registry_ids.Elements("RegistryId");
                if (ids != null && ids.Count() > 0)
                {
                    foreach (XElement id in ids)
                    {
                        string nct_id = GetElementAsString(id.Element("nct_id"));
                        study_identifiers.Add(new StudyIdentifier(sid, nct_id, 11, "Trial Registry ID", 100120, "ClinicalTrials.gov"));
                    }
                }
            }

            int?   sponsor_id   = GetElementAsInt(r.Element("sponsor_id"));
            string sponsor_name = GetElementAsString(r.Element("sponsor_name"));

            if (sponsor_id != null)
            {
                study_contributors.Add(new StudyContributor(sid, 54, "Trial sponsor", sponsor_id, sponsor_name));
            }

            // Create data object records.

            // For the BioLincc web page, set up new data object, object title, object_instance and object dates

            // Get publication year if one exists
            int?pub_year = null;
            int?pyear    = GetElementAsInt(r.Element("publication_year"));

            if (pyear != null && pyear > 0)
            {
                pub_year = pyear;
            }

            string remote_url           = GetElementAsString(r.Element("remote_url"));
            string object_title         = "NHLBI web page";
            string object_display_title = name_base + " :: " + "NHLBI web page";

            // create hash Id for the data object
            string sd_oid = sid + " :: 38 :: " + object_title;

            data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, pub_year, 23, "Text", 38, "Study Overview",
                                            100167, "National Heart, Lung, and Blood Institute (US)", 12, download_datetime));

            data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 22,
                                                   "Study short name :: object type", true));

            data_object_instances.Add(new ObjectInstance(sd_oid, 101900, "BioLINCC",
                                                         remote_url, true, 35, "Web text"));

            // Add dates if available
            //SplitDate page_prepared = null;
            SplitDate last_revised = null;

            /*
             * // This date no longer available... (explicitly - last revised date may be available in header)
             * //string page_prepared_date = GetElementAsString(r.Element("page_prepared_date"));
             *
             *
             * if (!string.IsNullOrEmpty(page_prepared_date))
             * {
             *  page_prepared = dh.GetDatePartsFromISOString(page_prepared_date.Substring(0, 10));
             *  data_object_dates.Add(new ObjectDate(sd_oid, 12, "Available", page_prepared.year,
             *              page_prepared.month, page_prepared.day, page_prepared.date_string));
             * }
             */

            string last_revised_date = GetElementAsString(r.Element("last_revised_date"));

            if (!string.IsNullOrEmpty(last_revised_date))
            {
                // date datasets revised
                last_revised = dh.GetDatePartsFromISOString(last_revised_date.Substring(0, 10));

                // only add last revised date if it is later than date prepared date
                // For early trials run before BioLINCC waas set up this is not the case

                /*
                 * if ((last_revised.year * 400) + (last_revised.month * 32) + last_revised.day
                 *  >= (page_prepared.year * 400) + (page_prepared.month * 32) + page_prepared.day)
                 *
                 * {
                 *  data_object_dates.Add(new ObjectDate(sd_oid, 18, "Updated", last_revised.year,
                 *            last_revised.month, last_revised.day, last_revised.date_string));
                 * }
                 */
            }

            // If there is a study web site...
            string study_website = GetElementAsString(r.Element("study_website"));

            if (!string.IsNullOrEmpty(study_website))
            {
                object_title         = "Study web site";
                object_display_title = name_base + " :: " + "Study web site";
                sd_oid = sid + " :: 134 :: " + object_title;

                data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, null, 23, "Text", 134, "Website",
                                                sponsor_id, sponsor_name, 12, download_datetime));
                data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 22,
                                                       "Study short name :: object type", true));
                data_object_instances.Add(new ObjectInstance(sd_oid, sponsor_id, sponsor_name,
                                                             study_website, true, 35, "Web text"));
            }


            // create the data object relating to the dataset, instance not available, title possible...
            // may be a description of the data in 'Data Available...'
            // if so add a data object description....with a data object title

            string access_details = "Investigators wishing to request materials from studies ... must register (free) on the BioLINCC website. ";

            access_details += "Registered investigators may then request detailed searches and submit an application for data sets ";
            access_details += "and/or biospecimens. (from the BioLINCC website)";

            string de_identification = "All BioLINCC data and biospecimens are de-identified. Obvious subject identifiers ";

            de_identification += "and data collected solely for administrative purposes are redacted from datasets, ";
            de_identification += "and dates are recoded relative to a specific reference point. ";
            de_identification += "In addition recodes of selected low-frequency data values may be ";
            de_identification += "carried out to protect subject privacy and minimize re-identification risks (from the BioLINCC documentation).";

            string resources_available = GetElementAsString(r.Element("resources_available"));

            if (resources_available.ToLower().Contains("datasets"))
            {
                DateTime date_access_url_checked = new DateTime(2021, 7, 23);

                object_title         = "Individual participant data";
                object_display_title = name_base + " :: " + "Individual participant data";
                sd_oid = sid + " :: 80 :: " + object_title;

                data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, last_revised.year, 14, "Datasets",
                                                80, "Individual participant data", 100167, "National Heart, Lung, and Blood Institute (US)",
                                                17, "Case by case download", access_details,
                                                "https://biolincc.nhlbi.nih.gov/media/guidelines/handbook.pdf?link_time=2019-12-13_11:33:44.807479#page=15",
                                                date_access_url_checked, download_datetime));

                data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 22, "Study short name :: object type", true));
                data_object_dates.Add(new ObjectDate(sd_oid, 18, "Updated", last_revised.year, last_revised.month, last_revised.day, last_revised.date_string));

                // Datasets and consent restrictions
                string dataset_consent_restrictions = GetElementAsString(r.Element("dataset_consent_restrictions"));

                int    consent_type_id = 0;
                string consent_type    = null;
                string restrictions    = null;
                if (string.IsNullOrEmpty(dataset_consent_restrictions))
                {
                    consent_type_id = 0;
                    consent_type    = "Not known";
                }
                else if (dataset_consent_restrictions.ToLower() == "none" ||
                         dataset_consent_restrictions.ToLower() == "none.")
                {
                    consent_type_id = 2;
                    consent_type    = "No restriction";
                    restrictions    = "Explicitly states that there are no restrictions on use";
                }
                else
                {
                    consent_type_id = 6;
                    consent_type    = "Consent specified, not elsewhere categorised";
                    restrictions    = dataset_consent_restrictions;
                }

                // do dataset object separately
                object_datasets.Add(new ObjectDataset(sd_oid,
                                                      0, "Not known", null,
                                                      2, "De-identification applied", de_identification,
                                                      consent_type_id, consent_type, restrictions));
            }

            var primary_docs = r.Element("primary_docs");

            if (primary_docs != null)
            {
                var docs = primary_docs.Elements("PrimaryDoc");
                if (docs != null && docs.Count() > 0)
                {
                    foreach (XElement doc in docs)
                    {
                        string pubmed_id = GetElementAsString(doc.Element("pubmed_id"));
                        string url       = GetElementAsString(doc.Element("url"));
                        study_references.Add(new StudyReference(sid, pubmed_id, null, url, "primary"));;
                    }
                }
            }


            var resources = r.Element("resources");

            if (resources != null)
            {
                var docs = resources.Elements("Resource");
                if (docs != null && docs.Count() > 0)
                {
                    foreach (XElement doc in docs)
                    {
                        string doc_name       = GetElementAsString(doc.Element("doc_name"));
                        int?   object_type_id = GetElementAsInt(doc.Element("object_type_id"));
                        string object_type    = GetElementAsString(doc.Element("object_type"));
                        int?   access_type_id = GetElementAsInt(doc.Element("access_type_id"));
                        string url            = GetElementAsString(doc.Element("url"));
                        int?   doc_type_id    = GetElementAsInt(doc.Element("doc_type_id"));
                        string doc_type       = GetElementAsString(doc.Element("doc_type"));
                        string size           = GetElementAsString(doc.Element("size"));
                        string size_units     = GetElementAsString(doc.Element("size_units"));

                        // for parity and test expectations
                        if (size == "")
                        {
                            size = null;
                        }
                        if (size_units == "")
                        {
                            size_units = null;
                        }

                        object_title         = doc_name;
                        object_display_title = name_base + " :: " + doc_name;
                        sd_oid = sid + " :: " + object_type_id.ToString() + " :: " + object_title;

                        // N.B. 'pub_year' no longer known

                        data_objects.Add(new DataObject(sd_oid, sid, object_title, object_display_title, null, 23, "Text", object_type_id, object_type,
                                                        100167, "National Heart, Lung, and Blood Institute (US)", access_type_id, download_datetime));
                        data_object_titles.Add(new ObjectTitle(sd_oid, object_display_title, 21, "Study short name :: object name", true));
                        data_object_instances.Add(new ObjectInstance(sd_oid, 101900, "BioLINCC", url, true, doc_type_id, doc_type, size, size_units));
                    }
                }
            }


            var assoc_docs = r.Element("assoc_docs");

            if (assoc_docs != null)
            {
                var docs = assoc_docs.Elements("AssocDoc");
                if (docs != null && docs.Count() > 0)
                {
                    foreach (XElement doc in docs)
                    {
                        string pubmed_id     = GetElementAsString(doc.Element("pubmed_id"));
                        string display_title = sh.ReplaceApos(GetElementAsString(doc.Element("display_title")));
                        string link_id       = GetElementAsString(doc.Element("link_id"));
                        study_references.Add(new StudyReference(s.sd_sid, pubmed_id, display_title, link_id, "associated"));
                    }
                }
            }


            // check that the primary doc is not duplicated in the associated docs (it sometimes is)
            if (study_references.Count > 0)
            {
                foreach (StudyReference p in study_references)
                {
                    if (p.comments == "primary")
                    {
                        foreach (StudyReference a in study_references)
                        {
                            if (a.comments == "associated" && p.pmid == a.pmid)
                            {
                                // update the primary link
                                p.citation = a.citation;
                                p.doi      = a.doi;
                                // drop the redundant associated link
                                a.comments = "to go";
                                break;
                            }
                        }
                    }
                }
            }

            List <StudyReference> study_references2 = new List <StudyReference>();

            foreach (StudyReference a in study_references)
            {
                if (a.comments != "to go")
                {
                    study_references2.Add(a);
                }
            }


            // add in the study properties
            s.titles       = study_titles;
            s.identifiers  = study_identifiers;
            s.references   = study_references2;
            s.contributors = study_contributors;

            s.data_objects     = data_objects;
            s.object_datasets  = object_datasets;
            s.object_titles    = data_object_titles;
            s.object_dates     = data_object_dates;
            s.object_instances = data_object_instances;

            return(s);
        }