X Close

Open@UCL Blog

Home

Menu

Archive for the 'Open Source' Category

Open educational resources and copyright: what do you need to consider?

By Rafael, on 7 November 2024

This is the last article of our Copyright and Open Science series by Christine Daoutis, UCL Copyright Support Officer, which explored important aspects of copyright and its implications for open research and scholarship.

An Open Educational Resources logo featuring an open book with pages transforming into upward-pointing hands, set against a blue background.

Image caption. Jonathasmello, CC BY 3.0 , via Wikimedia Commons

In this post, we conclude our Copyright and Open Science series by focusing on open education. Broadly defined, open education is “a philosophy about how people should produce, share, and build on knowledge” (source: What is open education? Opensource.com). It refers to values, practices and resources that aim to make scholarship more accessible, equitable, sustainable, transparent and collaborative.

The UNESCO definition of OERs highlights the importance of freely accessible educational materials in advancing open education practices globally. This includes the creation and reuse of OERs—materials that are either out of copyright or licensed to allow reuse. However, open education extends beyond resources to include practices such as integrating open science into teaching, sharing educational practices, and co-creating resources with learners.

OERs include a wide range of materials, such as open textbooks, open access articles, lecture handouts, images, film, slides, lecture recordings, assessment resources, software and whole courses such as Massive Open Online Courses (MOOCS). By default, all these resources are protected by copyright. If you’re planning to create open educational resources, here’s some copyright advice.

Addressing copyright in OERs

1. Know who owns what. If you are creating or collaborating on a teaching resource, it is essential to clarify who holds the copyright. This could be you, the author; your employer, if the work was created in the course of employment; or the resource could be co-owned with others, including students or sponsors. To license a resource for reuse (for example, to make it available under a Creative Commons licence), you must own the copyright to the resource and/or agree such licensing with co-owners. ♦ Copyright ownership at UCL is addressed in the UCL IP Policy.

2. Make the resources openly available and reusable. Once you are certain that the resource is yours to license, consider making it openly available, under a licence that allows reuse. Open access repositories support the discovery and access of different types of materials, including OERs. UCL has a dedicated OER repository, which accepts materials created by its staff and students.

As for licensing: we have explained in a previous post how Creative Commons licences work; and you can read more on how CC licences support OERs on the Creative Commons wiki. Licensing under the most permissive of the licences, the Creative Commons Attribution licence (CC BY), supports the ‘five Rs’ of OERs: enabling others to “retain, revise, remix, reuse and redistribute the materials”. (David Wiley, Defining the “Open” in Open Content and Open Educational Resources, Improving Learning blog).

A cartoon of a smiling stick figure pushing a shopping trolley filled with objects labeled 'CC' (Creative Commons) and holding up a yellow 'CC'-labeled item. The figure is placing an object on a bookshelf with colorful books and 'creative' works.

Image caption: sOER Frank, CC BY 2.0, via Wikimedia Commons

3. Address any third-party materials. If the resource contains materials you don’t own the copyright to (such as third-party content), you have a few options:

  • Reuse works that are out of copyright (public domain) or openly licensed. These might include Creative Commons images and videos, open access articles, and OERs created by others. ♦ See UCL’s guidance on finding OERs and a reading list with links to many openly licensed resources.
  • Get permission from the copyright owner. If the material is not openly licensed, you might consider seeking permission to reuse it. Be clear about how the resource containing the material will be shared (i.e., as an OER). Third-party materials included in an OER should be shared under their own copyright terms (e.g., their reuse may be more restricted than the rest of the resource) and this should be communicated when sharing.
  • Rely on a copyright exception. In some cases, instead of getting permission you may decide to rely on a copyright exception, notably the quotation exception in UK copyright law. Using exceptions requires judgement. You’ll need to determine whether the use of the material is ‘fair dealing’: does the purpose justify the use? Does it affect the copyright owner’s market? Overall, is it “fair” to all parties involved? Be aware that copyright exceptions vary by country, which is important when making a resource globally available. The Code of Best Practices in Fair Use for Open Educational Resources explores these approaches further, putting forward a framework that could be applied internationally.

Putting the copyright advice to practice: examples from UCL’s copyright online tutorials.

The screenshot shows the UCL Copyright Essentials 2023-2024 module page. On the right side, there's an image of stormtroopers marching in formation. The content discusses the use and adaptation of images under Creative Commons licenses. Below the stormtroopers, there are links to additional copyright resources. The layout is clean and educational, providing information on legal considerations for using and modifying copyrighted materials with appropriate licensing. On the left side, the course menu outlines the entire module and includes links to further reading.

Screenshot from UCL’s Copyright Essentials tutorial, which includes a photo by Michael Neel from Knoxville, TN, USA, CC BY 2.0, via Wikimedia Commons.

While creating UCL’s Copyright Essentials and Copyright and your Teaching, two online tutorials introducing copyright, the UCL Copyright support team drew on its own advice. Specifically:

  • Copyright ownership and attribution were addressed. Copyright Essentials is an adaptation of an original resource, which was also openly licensed. Attribution to all original authors was included.
  • Both tutorials are publicly available online, allowing anyone to access and complete them. They are also licensed for reuse under the Creative Commons Attribution licence, permitting others to adapt and redistribute the materials with appropriate attribution.
  • Third-party materials mostly included openly licensed images and links to lawfully shared videos and documents. However, for some materials, we opted to rely on copyright exceptions, which involved a degree of interpretation and risk. This was highlighted in the tutorials, inviting learners to reflect on the use of exceptions.

It should be noted that using proprietary e-learning tools (like Articulate Rise) to develop the tutorials restricts reuse. While the shared resources can be accessed, they cannot be downloaded or edited. Authors wishing to adapt the resources have the option to recreate the materials under the licence terms or contact us for an editable copy. Ideally, these resources should be created with open-source tools, but there’s a trade-off between the advantages of user-friendly, accessible proprietary tools and these limitations.

For more advice on copyright and OERs please contact copyright@ucl.ac.uk.


Read more from the Copyright and Open Science Series:

Celebrating Open Science & Scholarship: Highlights from the Second Annual Awards Ceremony!

By Rafael, on 1 November 2024

As part of our Open Access Week celebrations, we were delighted to host the second annual Open Science & Scholarship Awards presentation. This event gave us the opportunity to gather in person, congratulate the awardees, and celebrate their achievements after announcing the winners a few weeks ago.

The event began with certificate presentations, followed by a showcase of the award-winning projects.

A group of six awardees for the UCL Open Science Awards 2024 stands side by side in a room, smiling and holding framed certificates. They are (from left to right) Joseph Cook, Emily Gardner, Divya Balain, Sophie Ka Ling Lau, Eirini-Christina Saloniki, and William Lammons. A large screen is visible on the left, and the group is visibly happy for celebrating their achievements. First, Enny van Beest and Célian Bimbard, who received an honourable mention in the Open Source Software/Analytical Tools category, shared their project UnitMatch. Designed to track neurons across extensive Neuropixel Recordings, this software accelerates the analysis of large datasets, proving a valuable resource for researchers handling high volumes of neural data.

Next, winners of the Student category, Sophie Ka Ling Lau and Divya Balain, presented Diverse Voices, a website emerging from their project on the impact of COVID-19 on East London communities. Sophie and Divya, both Master’s students from UCL’s Departments of Brain Sciences and Life Sciences, respectively, created this collaborative platform to share insights gained from their research.

In the Advocating for Open Science & Community Building category, Joseph Cook shared his work with the UCL Citizen Science Academy, housed within the Institute for Global Prosperity. The Academy empowers citizens to participate in research projects, offering a structured learning programme and a certificate that recognises their contributions and learning.

The Professional Services Staff category award went to the Understanding Disability Project, presented by Eirini-Christina Saloniki and William Lammons. This project combines lived experiences with broad representation to document perspectives of people living with disabilities across North Thames, aiming for a comprehensive view that highlights the unique challenges they face.

Finally, in the Open Publishing category, Emily Gardner discussed her work with the NCL Mutation Database. This essential resource supports Batten Disease research and therapeutic development, with Emily’s work ensuring metadata accuracy and database reliability for researchers.

In the Open-Source Software category, we also recognised Alessandro Felder and the BrainGlobe Initiative, a collaborative project focused on creating open-access tools that support neuroscientific research worldwide. Although Alessandro couldn’t attend the ceremony, we were proud to recognise this initiative’s impressive accomplishments. Founded in 2020 to advance the handling and analysis of neuroimaging data, the BrainGlobe tools have been downloaded over 2.7 million times around the world!

After the presentations, the audience had a chance to network and enjoy refreshments provided by UCL Press, the event’s generous sponsor.

We would like to extend a special thank you to our other honorable mention recipients: Beth Downe, Gabrielle Pengyu Shao, Deborah Padfield, Dr. Adam Parker, Hengrui Zhang, Mathilde Ripart, Justyna Petke, Claire Waddington, and Fan Cheng. Representing a range of departments, teams, and centres across UCL – from the Slade School of Fine Art to the Dementia Research Centre – we were thrilled to celebrate your work and dedication to advancing open science across disciplines. Thank you for being part of this event!

The full group of awardees and recipients of honourable mentions stands indoors in the Haldane Room at UCL beside a large screen displaying "Welcome to UCL's Open Science & Scholarship Awards." The group includes Joseph Cook, Emily Gardner, Divya Balain, Sophie Ka Ling Lau, Eirini-Christina Saloniki, and William Lammons. They are smiling in a mix of formal and casual attire, celebrating their achievements.Our heartfelt thanks go to UCL Press for their support, the Office for Open Science & Scholarship team for organising the awards, and Sandy Schumann and Jessie Baldwin, UKRN local network leads, for managing the submission and peer review process. Special thanks go to Paul Ayris, Head of the UCL Office for Open Science & Scholarship, and David Shanks, UCL’s Institutional Lead for Reproducibility, for their continued support of these awards.

Watch this space for the next Open Science and Scholarship Awards!

Open Source Software Design for Academia

By Kirsty, on 27 August 2024

Guest post by Julie Fabre, PhD candidate in Systems Neuroscience at UCL. 

As a neuroscientist who has designed several open source software projects, I’ve experienced firsthand both the power and pitfalls of the process. Many researchers, myself included, have learned to code on the job, and there’s often a significant gap between writing functional code and designing robust software systems. This gap becomes especially apparent when developing tools for the scientific community, where reliability, usability, and maintainability are crucial.

My journey in open source software development has led to the creation of several tools that have gained traction in the neuroscience community. One such project is bombcell: a software designed to assess the quality of recorded neural units. This tool replaces what was once a laborious manual process and is now used in over 30 labs worldwide. Additionally, I’ve developed other smaller toolboxes for neuroscience:

These efforts were recognized last year when I received an honourable mention in the UCL Open Science and Scholarship Awards.

In this post, I’ll share insights gained from these experiences. I’ll cover, with some simplified examples from my toolboxes:

  1. Core design principles
  2. Open source best practices for academia

Disclaimer: I am not claiming to be an expert. Don’t view this as a definitive guide, but rather as a conversation starter.


Follow Julie’s lead: Whether you’re directly involved in open source software development or any other aspect of open science and scholarship, or if you simply know someone who has made important contributions, consider applying yourself or nominating a colleague for this year’s UCL Open Science and Scholarship Awards to gain recognition for outstanding work!


Part 1: Core Design Principles

As researchers, we often focus on getting our code to work, but good software design goes beyond just functionality. In order to maintain and build upon your software, following a few principles from the get go will elevate software from “it works” to “it’s a joy to use, maintain and contribute to”.

1. Complexity is the enemy

A primary goal of good software design is to reduce complexity. One effective way to simplify complex functions with many parameters is to use configuration objects. This approach not only reduces parameter clutter but also makes functions more flexible and maintainable. Additionally, breaking down large functions into smaller, more manageable pieces can significantly reduce overall complexity.

Example: Simplifying a data analysis function

For instance, in bombcell we run many different quality metrics, and each quality metric is associated with several other parameters. In the main function, instead of inputting all the different parameters independently:

[qMetric, unitType] = runAllQualityMetrics(plotDetails, plotGlobal, verbose, reExtractRaw, saveAsTSV, removeDuplicateSpikes, duplicateSpikeWindow_s, detrendWaveform, nRawSpikesToExtract, spikeWidth, computeSpatialDecay, probeType, waveformBaselineNoiseWindow, tauR_values, tauC, computeTimeChunks, deltaTimeChunks, presenceRatioBinSize, driftBinSize, ephys_sample_rate, nChannelsIsoDist, normalizeSpDecay, (... many many more parameters ...), rawData, savePath);

they are all stored in a ‘param’ object that is passed onto the function:

[qMetric, unitType] = runAllQualityMetrics(param, rawData, savePath);

This approach reduces parameter clutter and makes the function more flexible and maintainable.

 2. Design for change

Research software often needs to adapt to new hypotheses or methodologies. When writing a function, ask yourself “what additional functionalities might I need in the future?” and design your code accordingly. Implementing modular designs allows for easy modification and extension as research requirements evolve. Consider using dependency injection to make components more flexible and testable. This approach separates the creation of objects from their usage, making it easier to swap out implementations or add new features without affecting existing code.

Example: Modular design for a data processing pipeline

Instead of a monolithic script:

function runAllQualityMetrics(param, rawData, savePath)
% Hundreds of lines of code doing many different things
(...)
end

Create a modular pipeline that separates each quality metric into a different function:

function qMetric = runAllQualityMetrics(param, rawData, savePath)
nUnits = length(rawData);
for iUnit = 1:nUnits
% step 1: calculate percentage spikes missing
qMetric.percSpikesMissing(iUnit) = bc.qm.percSpikesMissing(param, rawData);
% step 2: calculate fraction refractory period violations
qMetric.fractionRPviolations(iUnit) = bc.qm.fractionRPviolations(param, rawData);
% step 3: calculate presence ratio
qMetric.presenceRatio(iUnit) = bc.qm.presenceRatio(param, rawData);
(...)
% step n: calculate distance metrics
qMetric.distanceMetric(iUnit) = bc.qm.getDistanceMetric(param, rawData);
end
bc.qm.saveQMetrics(qMetric, savePath)
end

This structure allows for easy modification of individual steps or addition of new steps without affecting the entire pipeline.

In addition, this structure allows us to define new parameters easily that can then modify the behavior of the subfunctions. For instance we can add different methods (such as adding the ‘gaussian’ option below) without changing how any of the functions are called!

param.percSpikesMissingMethod = 'gaussian';
qMetric.percSpikesMissing(iUnit) = bc.qm.percSpikesMissing(param, rawData);

and then, inside the function:

function percSpikesMissing = percSpikesMissing(param, rawData);
if param.percSpikesMissingMethod == 'gaussian'
(...)
else
(...)
end
end

3. Hide complexity

Expose only what’s necessary to use a module or function, hiding the complex implementation details. Use abstraction layers to separate interface from implementation, providing clear and concise public APIs while keeping complex logic private. This approach not only makes your software easier to use but also allows you to refactor and optimize internal implementations without affecting users of your code.

Example: Complex algorithm with a simple interface

For instance, in bombcell there are many parameters. When we run the main script that calls all quality metrics, we also want to ensure all parameters are present and are in a correct format.

function qMetric = runAllQualityMetrics(param, rawData, savePath)
% Complex input validation that is hidden to the user
param_complete = bc.qm.checkParameterFields(param);

% Core function that calcvulates all quality metrics
nUnits = length(rawData);

for iUnit = 1:nUnits
% steps 1 to n
(...)
end

end

Users of this function don’t need to know about the input validation or other complex calculations. They just need to provide input and options.

4. Write clear code

Clear code reduces the need for extensive documentation and makes your software more accessible to collaborators. Use descriptive and consistent variable names throughout your codebase. When dealing with specific quantities, consider adding units to variable names (e.g., ‘time_ms’ for milliseconds) to improve clarity. You can add comments to explain non-obvious logic and to add general outlines of the steps in your code. Following consistent coding style and formatting guidelines across your project also contributes to overall clarity.

Example: Improving clarity in a data processing function

Instead of an entirely mysterious function

function [ns, sr] = ns(st, t)
ns = numel(st);
sr = ns/t;

Add more descriptive variable and function names and add function headers:

function [nSpikes, spikeRate] = numberSpikes(theseSpikeTimes, totalTime_s)
% Count the number of spikes for the current unit
% ------
% Inputs
% ------
% theseSpikeTimes: [nSpikesforThisUnit × 1 double vector] of time in seconds of each of the unit's spikes.
% totalTime_s: [double] of the total recording time, in seconds.
% ------
% Outputs
% ------
% nSpikes: [double] number of spikes for current unit.
% spikeRate_s : [double] spiking rare for current unit, in seconds.
% ------
nSpikes = numel(theseSpikeTimes);
spikeRate_s = nSpikes/totalTime_s;
end

5. Design for testing

Incorporate testing into your design process from the beginning. This not only catches bugs early but also encourages modular, well-defined components.

Example: Testable design for a data analysis function

For the simple ‘numberSpikes’ function we define above, we can have a few tests to cover various scenarios and edge cases to ensure the function works correctly. For instance, we can test a normal case with a few spikes and an empty spike times input.

function testNormalCase(testCase)
theseSpikeTimes = [0.1, 0.2, 0.3, 0.4, 0.5]; totalTime_s = 1;
[nSpikes, spikeRate] = numberSpikes(theseSpikeTimes, totalTime_s);
verifyEqual(testCase, nSpikes, 5, 'Number of spikes should be 5');
verifyEqual(testCase, spikeRate, 5, 'Spike rate should be 5 Hz');
end

function testEmptySpikeTimes(testCase)
theseSpikeTimes = [];
totalTime_s = 1;
[nSpikes, spikeRate] = numberSpikes(theseSpikeTimes, totalTime_s);
verifyEqual(testCase, nSpikes, 0, 'Number of spikes should be 0 for empty input');
verifyEqual(testCase, spikeRate, 0, 'Spike rate should be 0 for empty input');
end

This design allows for easy unit testing of individual components of the analysis pipeline.

Part 2: Open Source Best Practices for Academia

While using version control and having a README, documentation, license, and contribution guidelines are essential, I have found that these practices have the most impact:

Example Scripts and Toy Data

I have found that the most useful thing you can provide with your software are example scripts, and even better, provide toy data that loads in your example script. Users can then quickly test your software and see how to use it on their own data — and are then more likely to adopt it. If possible, package the example scripts in Jupyter notebooks/MATLAB live scripts (or equivalent) demonstrating key use cases. In bombcell, we provide a small dataset (Bombcell Toy Data on GitHub) and a MATLAB live script that runs bombcell on this small toy dataset (Getting Started with Bombcell on GitHub). 

Issue-Driven Improvement

To manage user feedback effectively, enforce the use of an issue tracker (like GitHub Issues) for all communications. This approach ensures that other users can benefit from conversations and reduces repetitive work. When addressing questions or bugs, consider if there are ways to improve documentation or add safeguards to prevent similar issues in the future. This iterative process leads to more robust and intuitive software.

Citing

Make your software citable quickly. Before (or instead) of publishing, you can generate a citable DOI using software like Zenodo. Consider also publishing in the Journal of Open Source Software (JOSS) for light peer review. Clearly outline how users should cite your software in their publications to ensure proper recognition of your work.

Conclusion

These practices can help create popular, user-friendly, and robust academic software. Remember that good software design is an iterative process, and continuously seeking feedback and improving your codebase (and sometimes entirely rewriting/refactoring parts) will lead to more robust code.

To go deeper into principles of software design, I highly recommend reading “A Philosophy of Software Design” by John Ousterhout or “The Good Research Code Handbook” by Patrick J. Mineault.

Get involved! 

alt=""The UCL Office for Open Science and Scholarship invites you to contribute to the open science and scholarship movement. Join our mailing list, and follow us on X, formerly Twitter and LinkedIn, to stay connected for updates, events, and opportunities.