{"id":22093447,"url":"https://github.com/kablag/ascall","last_synced_at":"2025-03-24T00:28:21.356Z","repository":{"id":77169368,"uuid":"179643783","full_name":"kablag/AScall","owner":"kablag","description":null,"archived":false,"fork":false,"pushed_at":"2020-03-14T09:31:02.000Z","size":15840,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-29T07:17:16.116Z","etag":null,"topics":["pcr","r","rdml","shiny"],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kablag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-04-05T08:20:58.000Z","updated_at":"2024-03-29T17:57:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"beb924df-82b4-46ed-88c0-b15320fbfc3f","html_url":"https://github.com/kablag/AScall","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kablag%2FAScall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kablag%2FAScall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kablag%2FAScall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kablag%2FAScall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kablag","download_url":"https://codeload.github.com/kablag/AScall/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245189745,"owners_count":20575031,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pcr","r","rdml","shiny"],"created_at":"2024-12-01T03:14:42.063Z","updated_at":"2025-03-24T00:28:21.296Z","avatar_url":"https://github.com/kablag.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AScall – automatic allele-specific qPCR analysis\n\n## Introduction\n\nAScall is a web tool providing automatic processing of allele specific real-time\nPCR experiments: variation conducted real-time whereis each allele is detected \nby independent reaction separated into individual wells. The positive outcome of\nthe reaction for a particular allele is judged by the increase in the \nfluorescent signal. This tool is written in R language with graphical user \ninterface based on *shiny* technology. In addition to general purpose R \npackages, our program uses a number of specific PCR-oriented packages: \n[chipPCR](https://cran.r-project.org/web/packages/chipPCR/index.html),\n[qPCR](https://cran.r-project.org/web/packages/qpcR/index.html),\n[RDML](https://cran.r-project.org/web/packages/RDML/index.html),\n[shinyMolBio](https://cran.r-project.org/web/packages/shinyMolBio/index.html).\nGUI use standard *shiny* elements, \n[shinyWidgets](https://cran.r-project.org/web/packages/shinyWidgets/index.html) for \nmultiply selectors - *pickerInput*, *shinyMolBio* for PCR plate - *pcrPlateInput*\nand PCR curves plot - *renderAmpCurves*.\n\n\u003e General note: some of operations are time consuming (e.g. curves preprocession).\nSo be patient!!! To avoid recalculations after each option change all setup is \napplied by clicking **Recalculate Results** button.\n\n### Installation\n\nCopy all files (or *init.R*, *generics.R*, *server.R* and *ui.R* for minimal \ninstallation) to any directory on your computer and \n[run](https://shiny.rstudio.com/articles/running.html) as usual *shiny*\napplication. All necessary packages will be installed during application run.\n\n### Workflow overview\n\nProcess of analysis can be described by several major steps:\n* data import from PCR machines via *RDML* format;\n* optional PCR curves preprocessing;\n* overall experiment quality control and individual sample control;\n* sample genotype calling. \n\n### Sample files\n\nSample files are available in\n[examples folder](https://github.com/kablag/AScall/tree/master/examples) of *AScall*.\nThese files are BioRad CFX *pcrd* format and *rdml* converted. Also there is\nmanual genotyping results file - *genotyping.xlsx*. Click button *Use Sample File*\nto load `01.rdml` file.\n\n## Data import\n\nYou can input one or more files in a format supported by the *RDML* package: \n**rdml**, **lc96p**, **xlsx**, **etc**. But *AScall* need correct sample naming \nto work as automatic genotype caller. Naming convention and export will be shown \nfor *BioRad CFX Manager 3.1* as example. Several files can be imported at once – \nin such case all subsequent analyses are carried out independently for each plate\nand one summary table with results is provided (control gene and preprocessing\nsettings will be the same for all plates!).\n\n### Plate setup\nCorrect plate setup is shown on the fig.1:\n\n![Figure 1. Plate Setup](ext/plate_setup.png)\n\nThere are several major elements:\n\n* All wells with one sample have to be **named equaly**. Marked with the red box **p181**\non the fig.1: despites the different names of targets - sample names are equal. \nSame rule for replicates - there should not be any indices!\n* Target names for not control genes have to contain **gene name** and **allele name** \nafter **underscore** - GENENAME_ALLELENAME pattern. Green box on the figure - \n**HER2_C** **and HER2_G** where **HER2** is the gene name and **C** or **G** are\nalleles. For indel targets use **+** sign (e.g. **UGT2b17_+**). Using indel \ntargets leads to alternate analysis: no amplification is deletion; amplification\nis insertion.\n* Control gene name have to be equal for all plates. Blue box **B2m**.\n* No template controls must have **NTC** sample type.\n* Target name without allele name called **marker**.\n* All wells with the same markers *AScall* interpretes as one **kit**. Orange box\non the fig.1.\n\n\n### Export data from BioRad CFX Manager\nAfter plate setup is done you can import data by **Export\u003eExport RDML File\u003eRDML v1.1**\nmenu (see fig.2).\n\n![Figure 2. Data export](ext/data_export.png)\n\n## PCR curves preprocessing\nThis is optional step and only needed when your use RAW data or want to recalculate \n**Cq** values with the independent method (fitting and Cq calculation).\nPreprocessing is conducted with the *chipPCR* and *qpcR* packages usage. You \nshould check **Preprocess Curves** to enable preprocessing and options (Fig.3).\n\n![Figure 3. AScall options](ext/options.png)\n\nAfter that several additional option **Background Region** appears. You can set \nsignal background region (linear part of the curves before exponentional growth)\nfor all curves using this slider (Click **Recalculate Results** to apply changes).\n\nProcessing consists of the following three steps:\n\n* Background subtraction\n\n```r\nchipPCR::CPP(fpoints$cyc, fpoints$fluor,\n             trans = TRUE,\n             bg.range = bgRange)$y.norm\n```\n* Model fitting\n\n```r\nqpcR::pcrfit(fpoints[, c(\"cyc\", \"fluor\")], \n       cyc = 1, fluo = 2,\n       model = get(modelType))\n```\n* Cq calculation\n\n```r\nqpcR::efficiency(fitted, plot = FALSE,\n           type = cqMethod)\n```\n\n## Genotype calling\n\n### Options\nAfter loading all data files **Recalculate Results** button appears and subsequent\nanalisys can be done. First of all you can fine tune several options (Fig.3):\n\n* __Control Marker__ - select any detected marker as *control marker* - reaction that\nhave to be positive in all samples.\n* __Cq ∆__ - maximum difference between **Cq** values of reactions replicates.\n* __Cq Threshold__ - max **Cq** values to be reaction treated as positive.\n* __RFU Threshold__ - minimum fluorescence signal to be reaction treated as \npositive.\n\n### Analysis and QC steps\n\n* Low RFU - all reactions with **RFU** lower than **RFU Threshold** are marked with \n`RFU_QC = \"Low\"` \n\n```r\nRFU_QC = ifelse(endPt \u003c input$rfuThr, \n                \"Low\", \"Ok\"))\n```\n* Mark amplification status - negative for reactions with `RFU_QC != \"Ok\"` and\n**Cq** higher than **Cq Threshold**\n\n```r\nampStatus_QC = ifelse(RFU_QC != \"Ok\" | cq \u003e input$cqThr, \n                     \"NoAmp\", \"Ok\")\n```\n* Replicate match check - all replicates have to be `ampStatus_QC = \"NoAmp\"` or \n(`ampStatus_QC = \"Ok\"` and difference between **Cq** values lower than **Cq ∆** option)\n\n```r\nmeanCq = mean(cq),\ndeltaCq = max(cq) - min(cq)\nreplicateMatch_QC = {\n    if ((all(ampStatus_QC == \"Ok\") \u0026\u0026 deltaCq[1] \u003c input$cqDelta) ||\n        all(ampStatus_QC != \"Ok\")) \"Ok\" else \"Fail\"\n```\n* ∆ between alleles - alleles **Cq** difference (and minus delta between \nctrlMarkerCqs to normalize samples) have to be lower than **Cq ∆** option.\n\n```r\ndTbl \u003c- dTbl %\u003e% \n        group_by(position) %\u003e% \n        mutate(\n          ctrlMarkerCq = cq[marker == input$ctrlMarker]\n        )\n      dTbl \u003c- dTbl %\u003e%\n        group_by(kit, marker, sample) %\u003e% \n        mutate(\n          allelesDeltaCqUnnorm = meanCq - min(meanCq),\n          allelesDeltaCq =  allelesDeltaCqUnnorm - \n            (ctrlMarkerCq - min(ctrlMarkerCq)),\n          allelesDeltaCq_QC = \n            ifelse(abs(allelesDeltaCq) \u003c input$cqDelta,\n                   \"Ok\", \"Fail\"))\n```\n* NTC no amplification - all NTC reactions in kit have to be \n`ampStatus_QC = \"NoAmp\"`\n\n```r\nnoAmpNTC_QC = \n  {\n    if (any(ampStatus_QC[sample.type == \"ntc\"] == \"Ok\"))\n        \"Fail\" else  \"Ok\"\n  }\n```                   \n* Control Marker QC - `ampStatus_QC = \"Ok\"` and `replicateMatch_QC = \"Ok\"` for \n**Control Marker** reactions\n\n```r\nctrlMarker_QC = \n  {\n    if (any(replicateMatch_QC[marker == input$ctrlMarker] != \"Ok\") ||\n       any(ampStatus_QC[marker == input$ctrlMarker] == \"NoAmp\"))\n            \"Fail\" else \"Ok\"\n  }\n```\n* Kit total QC - `noAmpNTC_QC != \"Ok\"` for all NTC \n\n```r\nkit_QC = \n  {\n    if (any(noAmpNTC_QC != \"Ok\"))\n      \"Fail\" else \"Ok\"\n  }\n```\n* Results Calc - calculates for all sample which are \n`kit_QC == \"Ok\" \u0026 replicateMatch_QC == \"Ok\" \u0026 ctrlMarker_QC == \"Ok\"`.\nThen result is a combination of alleles with `ampStatus_QC == \"Ok\"` or\ninsertion/deletion if `ampStatus_QC == \"Ok\"`/`ampStatus_QC != \"Ok\"` for\nindel markers.\n\n```r\ngenResult \u003c- function(okAlleles) {\n                       okAlleles \u003c-  unique(okAlleles)\n                       if (length(okAlleles) == 1) {\n                         okAlleles \u003c- c(okAlleles, okAlleles)\n                       }\n                       paste(okAlleles, collapse = \"/\")\n                     }\n                     \ngenIndelResult \u003c- function(ampStatus_QC) {\n        if (all(ampStatus_QC == \"Ok\")) {\n          \"Ins\"\n        } else if (all(ampStatus_QC != \"Ok\")) {\n          \"Del\"\n        } else {\n          \"Error\"\n        }\n      }\nresult = {\n       if (marker[1] != input$ctrlMarker) {\n         if (allele[1] == \"+\") {\n           genIndelResult(ampStatus_QC)\n         } else {\n           genResult(allele[ampStatus_QC == \"Ok\"])\n         }\n       } else {\n         \"\"\n       }\n     }\nresultZygosity =\n  sapply(result,\n         function(x) \n         {\n           if (x[1] == \"\")\n             \"\"\n           else\n             switch(\n               as.character(str_split(x,\n                                      \"/\")[[1]] %\u003e%\n                              unique() %\u003e% \n                              length()),\n               \"1\" = \"Homo\",\n               \"2\" = \"Hetero\",\n               \"Error\")\n         })\n```\n\n## Visualization\nThere are three main elements:\n\n* __Global filters__ - serve to filter kits, samples and markers for summary and\ndetails views (fig.4A).\n* __Summary view__ - global genotyping results for all PCR files.\n* __Details view__ - per file view of PCR curves and plate with QC results.\n\n![Figure 4. AScall GUI - summary view](ext/summary_view.png)\n\n### Global filters \n\nGlobal filters allow to select individual samples, markers or kits for viewing at\ndetails and summary (fig.4A).\n\n### Summary view\n\nThis view shows all genotyping results for all loaded files as bar plot and table.\n**Barplot** allows to overview results by markers: x-axis is marker and y-axis is\nnumber of samples grouped by genotypes of this marker (fig.4B). **Table** represents \ngenotyping results by samples (fig.4C).\n\n### Details view\n\n![Figure 5. AScall GUI - details view](ext/details_view.png)\n\nProvides access to additional per plate details about PCR curves and analysis.\nIt consists of:\n\n* __File selector__ - you can switch uploaded experiments by this elements (fig.5A).\n* __PCR curves__ - created by `shinyMolBio::renderAmpCurves()` function (fig.5B).\nCurves are colored by _marker_.\n* __PCR plate__ - created by `shinyMolBio::pcrPlateInput()` function (fig.5C).\nWells are color by _kit_; dotted wells contain NTC (see legend under plate).\nSelected wells have red border and light yellow background is for _on hover_ well \n(selection filters curves on __PCR curves__ plot and the _on hover_ curves are solid \nwhile the others are - transparent).  __On hover__ well provides additionalinfo \ninside black box.\n* __Details table__ - show information about every PCR curve including genotyping \nresults and QC (fig.5D).\n\n## Report\n\nAfter genotype analysis summary report can be generated by clicking **Report**\nbutton. *Xlsx* report consists of (fig.6):\n\n* Genotyping results table\n* Genotypes count plot\n* QC table\n* Analysis settings\n\nReport generation is carried out by *openxlsx* package.\n\n![Figure 6. Report](ext/report.png)\n\n# Appendix: QC results\n\n1. __RFU_QC__\n  * __Low__ - curve endpoint fluorescence signal is lower than __RFU Threshold__\n  * __Ok__\n2. __ampStatus_QC__\n  * __NoAmp__ - anmlification for this curve is not detected\n  * __Ok__\n3. __replicateMatch_QC__\n  * __Fail__ - *Cq* difference between replicates is bigger than __Cq ∆__ option\n  * __Ok__\n4. __allelesDeltaCq_QC__\n  * __Fail__ - *Cq* difference between alleles of one marker is bigger than __Cq ∆__ option\n  * __Ok__\n4. __noAmpNTC_QC__\n  * __Fail__ - any __NTC__ sample has positive amplification\n  * __Ok__\n5. __ctrlMarker_QC__\n  * __Fail__ - control marker does not have positive amplification in any well \n  * __Ok__","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkablag%2Fascall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkablag%2Fascall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkablag%2Fascall/lists"}