Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
aad5b50
track_utils performance improvement
FilomenoSanchez Apr 19, 2021
1bb6923
cmap_utils performance improvement
FilomenoSanchez Apr 19, 2021
cc85f9b
refactor code at heatmap_utils.py
FilomenoSanchez Apr 19, 2021
21684b0
refactor cmap density cache keys
FilomenoSanchez Apr 20, 2021
a12441a
add -density and -hydrophobicity tags to track selector
FilomenoSanchez Apr 21, 2021
feaac68
refactor track selector layout and add cmap diff selection to the lis…
FilomenoSanchez Apr 21, 2021
8419d5d
plot contact diff track
FilomenoSanchez Apr 21, 2021
102e1f0
pdb files are never sliced with L factor
FilomenoSanchez Apr 22, 2021
7e970e7
use amise to stimate bw for kde
FilomenoSanchez Apr 22, 2021
c59fdf8
use conkit to calculate amise bw (faster than numba)
FilomenoSanchez Apr 22, 2021
a6ab7ac
fix contact density tests
FilomenoSanchez Apr 23, 2021
18571f0
added more tests
FilomenoSanchez Apr 23, 2021
90a2854
fixed tests
FilomenoSanchez Apr 23, 2021
f977765
calculate rmsd
FilomenoSanchez Apr 23, 2021
7f8c535
append file type at begining of cmap
FilomenoSanchez Apr 26, 2021
2f6fda4
refactor cmap code
FilomenoSanchez Apr 26, 2021
5af3026
calculate rmsd between distograms
FilomenoSanchez Apr 26, 2021
1df088b
skip conkit density test if running on github actions
FilomenoSanchez Apr 26, 2021
ddf4a94
fix more tests
FilomenoSanchez Apr 26, 2021
ff91968
more broken tests
FilomenoSanchez Apr 26, 2021
dfd684c
final fix
FilomenoSanchez Apr 26, 2021
085e827
add smoothing functions
FilomenoSanchez Apr 27, 2021
3049a09
smooth diff track
FilomenoSanchez Apr 28, 2021
6cc8e20
update version number
FilomenoSanchez Apr 28, 2021
38334f6
fix typo
FilomenoSanchez Apr 29, 2021
70cde61
improved plot time performance
FilomenoSanchez Apr 29, 2021
cfb07c3
update README.md
FilomenoSanchez Apr 29, 2021
aa4dc39
update README.md
FilomenoSanchez Apr 29, 2021
17351ba
control session timeout from environment variable
FilomenoSanchez Apr 30, 2021
8e35564
minor changes
FilomenoSanchez May 2, 2021
1f66bb2
use numpy when creating heatmap
FilomenoSanchez May 3, 2021
2e3f993
add a3m format to the help page
FilomenoSanchez May 4, 2021
dacc591
minor change to the help page
FilomenoSanchez May 4, 2021
49b5d09
if looking for diff between distance predictions cache should not car…
FilomenoSanchez May 6, 2021
b32f488
rmsd scale from 0-5
FilomenoSanchez May 6, 2021
4462713
increase contrast hydrophobicity track
FilomenoSanchez May 6, 2021
a363725
small change to help page
FilomenoSanchez May 6, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
redis-version: 5
- name: Run tests.py
env:
THIS_IS_GH_ACTIONS: 1
KEYDB_URL: $ {{ secrets.KEYDB_URL }}
run: |
python tests.py
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ Changelog
=========


0.4.1
-----

Added
~~~~~
- Added contact diff track with smoothed values (MCC for contacts and RMSD for distograms)

Changed
~~~~~
- Increased contrast in sequence hydrophobicity color palettes
- Use AMISE to estimate bandwidth required to calculate contact density
- Updated track selector layout


0.4
-----

Expand Down
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,25 @@ Once you have installed `redis`, you will need to start the service by running:
$ sudo service redis start
```

You will also need to create a environment variable called `KEYDB_URL` with
the URL to connect to the redis server you just started on your machine:
Now you'll need to clone this repository, install the requirements and setup environment variables.
Please note that ConPlot requires at least `python 3.6`.

```bash
$ KEYDB_URL=redis://localhost:6379
$ git clone https://github.com/rigdenlab/conplot
$ cd conplot
$ python3.6 -m pip install -r requirements.txt
$ echo "KEYDB_URL=0://localhost:6379" > .env
$ echo "KEYDB_TIMEOUT=3600" >> .env
```

After this, all you need to do is clone this repository, install the requirements
and start the Flask development server on your machine. Please note that ConPlot
requires at least `python 3.6`.
With the last two commands you will also have created an `.env` file with a variable named
`KEYDB_URL` pointing to the redis server and a `KEYDB_TIMEOUT` variable with the session
timeout value. This is the time at which a session expires after inactivity. By default in
`www.conplot.org` this has a value of 3600 minutes, but if running locally you can set this
time to any other value. The only thing left to do is to start the Flask development
server on your machine:

```bash
$ git clone https://github.com/rigdenlab/conplot
$ cd conplot
$ python3.6 -m pip install -r requirements.txt
$ python3.6 app.py
```

Expand Down
7 changes: 4 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def serve_layout():
except (keydb.ConnectionError, TypeError, KeyError) as e:
app.logger.error('Redis connection error! {}'.format(e))
return layouts.RedisConnectionError()
session_id = session_utils.initiate_session(cache, app.logger)
session_id = session_utils.initiate_session(cache, app.logger, keydb_timeout)
return layouts.Base(session_id)


Expand All @@ -44,6 +44,7 @@ def serve_layout():
'requests_pathname_prefix': '/conplot/',
})
keydb_pool = keydb_utils.create_pool(os.environ.get('KEYDB_URL'))
keydb_timeout = os.environ.get('KEYDB_TIMEOUT')
app.layout = serve_layout


Expand Down Expand Up @@ -407,7 +408,7 @@ def javascript_exe_button(n_clicks, session_id):

elif 'new-session' in trigger['prop_id'] or session_utils.is_expired_session(session_id, cache, app.logger):
cache = keydb.KeyDB(connection_pool=keydb_pool)
new_session_id = session_utils.initiate_session(cache, app.logger)
new_session_id = session_utils.initiate_session(cache, app.logger, keydb_timeout)
return "location.reload();", no_update, new_session_id

else:
Expand Down Expand Up @@ -454,7 +455,7 @@ def create_ConPlot(plot_click, refresh_click, factor, contact_marker_size, track
if any([True for x in (factor, contact_marker_size, track_marker_size, track_separation) if x is None or x < 0]):
app.logger.info('Session {} invalid display control value detected'.format(session_id))
return no_update, components.InvalidInputModal(), no_update, no_update
elif superimpose and ('---' in cmap_selection or len(set(cmap_selection)) == 1):
elif superimpose and ('--- Empty ---' in cmap_selection or len(set(cmap_selection)) == 1):
return no_update, components.InvalidMapSelectionModal(), no_update, no_update

app.logger.info('Session {} creating conplot'.format(session_id))
Expand Down
1 change: 1 addition & 0 deletions components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class UserReadableTrackNames(Enum):
heatmap = 'Heatmap'
hydrophobicity = 'Hydrophobicity'
density = 'Contact density'
diff = 'Contact diff'


class EmailIssueReference(Enum):
Expand Down
47 changes: 21 additions & 26 deletions components/cards.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import cache_utils
import components
import dash_core_components as dcc
import dash_bootstrap_components as dbc
Expand Down Expand Up @@ -286,45 +287,47 @@ def DisplayControlCard(available_tracks=None, selected_tracks=None, selected_cma
html.H5("Active tracks", className="card-text", style={'text-align': "center"}),
html.Hr(),
html.Br(),
TrackSelectionCard('-4', selected_tracks[0], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('-4', available_tracks, selected_tracks[0]), outline=False),
html.Br(),
TrackSelectionCard('-3', selected_tracks[1], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('-3', available_tracks, selected_tracks[1]), outline=False),
html.Br(),
TrackSelectionCard('-2', selected_tracks[2], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('-2', available_tracks, selected_tracks[2]), outline=False),
html.Br(),
TrackSelectionCard('-1', selected_tracks[3], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('-1', available_tracks, selected_tracks[3]), outline=False),
html.Br(),
TrackSelectionCard(' 0', selected_tracks[4], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('0', available_tracks, selected_tracks[4]), outline=False),
html.Br(),
TrackSelectionCard('+1', selected_tracks[5], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('+1', available_tracks, selected_tracks[5]), outline=False),
html.Br(),
TrackSelectionCard('+2', selected_tracks[6], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('+2', available_tracks, selected_tracks[6]), outline=False),
html.Br(),
TrackSelectionCard('+3', selected_tracks[7], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('+3', available_tracks, selected_tracks[7]), outline=False),
html.Br(),
TrackSelectionCard('+4', selected_tracks[8], available_tracks=available_tracks),
dbc.Card(components.TrackLayoutSelector('+4', available_tracks, selected_tracks[8]), outline=False),
html.Br(),
html.Br(),
html.H5("Colour palettes", className="card-text", style={'text-align': "center"}),
html.Hr(),
html.Br(),
ColorPaletteSelectionCard('density', selected_palettes[0]),
html.Br(),
ColorPaletteSelectionCard('custom', selected_palettes[1]),
ColorPaletteSelectionCard('diff', selected_palettes[1]),
html.Br(),
ColorPaletteSelectionCard('heatmap', selected_palettes[2]),
ColorPaletteSelectionCard('custom', selected_palettes[2]),
html.Br(),
ColorPaletteSelectionCard('hydrophobicity', selected_palettes[3]),
ColorPaletteSelectionCard('heatmap', selected_palettes[3]),
html.Br(),
ColorPaletteSelectionCard('membranetopology', selected_palettes[4]),
ColorPaletteSelectionCard('hydrophobicity', selected_palettes[4]),
html.Br(),
ColorPaletteSelectionCard('msa', selected_palettes[5]),
ColorPaletteSelectionCard('membranetopology', selected_palettes[5]),
html.Br(),
ColorPaletteSelectionCard('conservation', selected_palettes[6]),
ColorPaletteSelectionCard('msa', selected_palettes[6]),
html.Br(),
ColorPaletteSelectionCard('disorder', selected_palettes[7]),
ColorPaletteSelectionCard('conservation', selected_palettes[7]),
html.Br(),
ColorPaletteSelectionCard('secondarystructure', selected_palettes[8]),
ColorPaletteSelectionCard('disorder', selected_palettes[8]),
html.Br(),
ColorPaletteSelectionCard('secondarystructure', selected_palettes[9]),
html.Br(),
])
]
Expand All @@ -334,14 +337,6 @@ def DisplayControlCard(available_tracks=None, selected_tracks=None, selected_cma
else:
raise ValueError('This should not occur! Please report.')


def TrackSelectionCard(track_idx, track_value, available_tracks):
track_options = [{'label': '---', 'value': '---'}]
track_options += [{'label': fname, 'value': fname} for fname in available_tracks]

return dbc.Card(components.TrackLayoutSelector(track_idx, track_options, track_value), outline=False)


def ColorPaletteSelectionCard(dataset, selected_palette):
available_palettes = []
for palette in color_palettes.DatasetColorPalettes.__getattr__(dataset).value:
Expand All @@ -351,7 +346,7 @@ def ColorPaletteSelectionCard(dataset, selected_palette):


def HalfSquareSelectionCard(square_idx, selection, available_cmaps):
cmap_options = [{'label': '---', 'value': '---'}]
cmap_options = [{'label': '--- Empty ---', 'value': '--- Empty ---'}]
cmap_options += [{'label': fname, 'value': fname} for fname in available_cmaps]

return dbc.Card(components.HalfSquareSelector(square_idx, cmap_options, selection), outline=False)
Expand Down
78 changes: 38 additions & 40 deletions components/listgrpoups.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,48 +191,38 @@ def AdjustPlotHelpList():
'series of input menus:',
html.Ul([
html.Li(['L/N selector: Change the values of ', html.I('N'),
' with this selector to choose how many contacts should be '
'included in the plot (L is the number of residues in the '
'protein sequence, residues are sorted by their probability '
'score). If you set ', html.I('N'),
' to 0, then all contacts in the file will be displayed. Please '
'note that only numerical values between 0 and 10 are recommended.']),
html.Li('Size selector: Change the size of the contact markers in the '
'plot. ConPlot will set a default value depending on the size of '
'the protein you are working with, but you can still change this '
'if you would like to make the markers smaller or bigger. Please '
' with this selector to choose how many contacts should be included in the plot (L is '
'the number of residues in the protein sequence, residues are sorted by their '
'probability score). If you set ', html.I('N'),
' to 0, then all contacts in the file will be displayed. Please note that only numerical '
'values between 0 and 10 are recommended. Additionally, please remember that contact '
'data shown for PDB files is unaltered by this selector.']),
html.Li('Size selector: Change the size of the contact markers in the plot. ConPlot will set a '
'default value depending on the size of the protein you are working with, but you can '
'still change this if you would like to make the markers smaller or bigger. Please '
'note that only numerical values between 1 and 15 are recommended.'),
html.Li(['Map A and Map B selectors: These two selectors let you choose '
'which contact data should be displayed on the plot. By '
'default, ', html.I('Map A'),
' refers to the top half triangle of the map, and ',
html.I('Map B'), ' to the lower one. If the ',
html.I('Superimpose Maps'),
' switch is activated, then the roles of these two dropdown '
'menus change: ', html.I('Map A'),
' is now used to select the reference map, which will be '
'compared with the secondary map selected with the ',
html.I('Map B'), ' selector.']),
html.Li(['Superimpose Maps Switch: As explained above, if this switch '
'is activated ', html.I('Map A'),
' will be used as a reference map to be compared with ',
html.I('Map B'),
'. In this mode, contacts will be coloured according to their '
'presence in the reference map and the secondary map. Contacts '
'that appear on both the reference and the secondary map will be '
'coloured in black -match-, those that only appear in the '
'reference in grey -absent-, and those that only appear in the '
'secondary map in red -mismatch-. Please note that you can only '
'use this mode if you select two different contact map files in ',
html.Li(['Map A and Map B selectors: These two selectors let you choose which contact data should '
'be displayed on the plot. By ' 'default, ', html.I('Map A'),
' refers to the top half triangle of the map, and ', html.I('Map B'),
' to the lower one. If the ', html.I('Superimpose Maps'),
' switch is activated, then these roles change: ', html.I('Map A'),
' is now used to select the reference map, which will be compared with the secondary map '
'selected with the ', html.I('Map B'), ' selector.']),
html.Li(['Superimpose Maps Switch: As explained above, if this switch is activated ',
html.I('Map A'), ' will be used as a reference map to be compared with ', html.I('Map B'),
'. In this mode, contacts will be coloured according to their presence in the reference '
'map and the secondary map. Contacts that appear on both the reference and the secondary '
'map will be coloured in black -match-, those that only appear in the reference in grey '
'-absent-, and those that only appear in the secondary map in red -mismatch-. Please '
'note that you can only use this mode if you select two different contact map files in ',
html.I('Map A'), ' and ', html.I('Map B'), ' selectors.']),
html.Li(['Create Heatmap Switch: If this switch is activated, a heatmap will be created with the '
'provided residue contact information. By default, if a contact map is uploaded, the '
'intensity of the colours in this heatmap will correspond with the confidence of each '
'contact. Alternatively, if a residue-residue distance prediction file has been uploaded '
'(', html.I('CASPRR_MODE2'),
' format), the heatmap will correspond with the predicted distances for '
'each residue pair oin this file. Please note that when this mode is active, the ',
html.I('L/N'), ' selector and the ', html.I('Size'),
'contact. Alternatively, if a residue-residue distance prediction file has been '
'uploaded, the heatmap will correspond with the predicted distances for each residue '
'pair oin this file. Please note that when this mode is active, the ', html.I('L/N'),
' selector and the ', html.I('Size'),
' selector will be disabled. You can read more about how to visualise residue-residue '
'distance predictions at ',
html.I('Tutorial 4. Residue-Residue distance predictions'), '.']),
Expand All @@ -242,9 +232,8 @@ def AdjustPlotHelpList():
'would normally be displayed.')
])],
style={"font-size": "110%", 'text-align': "justify"}),
html.Li(['Section 2: Adjust additional tracks. In this section you will find selectors '
'that will let you control aspects about how the additional tracks are being '
'displayed in the plot:',
html.Li(['Section 2: Adjust additional tracks. In this section you will find selectors that will let you '
'control aspects about how the additional tracks are being displayed in the plot:',
html.Ul([
html.Li('Size selector: Change the size of the tiles used to create the '
'tracks on the diagonal of the plot. By changing this value, '
Expand Down Expand Up @@ -326,6 +315,15 @@ def AdditionalFormatsHelpList():
html.A(html.U('here'), href=UrlIndex.CONSURF_CITATION.value),
'.'],
style={"font-size": "110%", 'text-align': "justify"}),
html.Li(['A3M file. This is a multiple sequence alignment file that should have been obtained using the '
'sequence of interest as a query. ConPlot will parse the file and calculate the MSA coverage along '
'the query sequence, normalise these values (1-10) and create a track where each residue '
'is coloured according to the number of sequences aligned in that particular position These '
'files are used in most contact prediction pipelines, and visualising the MSA coverage can help you '
'understand the quality of the information used to obtain your predictions. Several alignment tools '
'will create MSA files in this format, like for example HHBLITS, which you can use '
'online ', html.A(html.U('here'), href=UrlIndex.HHBLITS_URL.value), '.'],
style={"font-size": "110%", 'text-align': "justify"}),
html.Li(['CUSTOM file. These files are plain text files that can be created manually '
'by users to include additional tracks of information to the plot. These '
'files enable limitless personalisation of the contact map plot, as it '
Expand Down
Loading