A Component is defined as an interface with no specific methods or properties.
I highly suggest you to implement your components as classes, since the systems will rely on those.
For example, you could define a position like this:
Entities are the elements, your systems will work with and have an unique identifier.
Since this library doesn’t want you to tell, how to generate your ids, the base class AbstractEntity is abstract.
This means your entity implementation should extend AbstractEntity.
An entity, is a Dispatcher, which means, you can register an EntityListener on it, to check whether a component has been added, removed, the components have been sorted or cleared.
System
Systems implement the actual behavior of your entities, based on which components they own.
For programming your own systems, you should implement the abstract class System.
This base class provides basic functionalities, such as
an updating flag, which indicates whether a system is still updating.
an active flag, which tells the engine to either run the system in the next update call or not.
an engine property, which will be set/unset, as soon as the system gets added/removed to/from an engine.
A system is also a Dispatcher, which means, you can react to any actions happening to a system, by registering a SystemListener.
Here is a minimal example of a system, which obtains a list of entities with the component type Position.
import{System,Aspect}from'@trixt0r/ecs';classMySystemextendsSystem{privateaspect: Aspect;constructor(){super(/* optional priority here */);}onAddedToEngine(engine: Engine): void{// get entities by component 'Position'this.aspect=Aspect.for(engine).all(Position);}asyncprocess(): void{constentities=this.aspect.entities;entities.forEach(entity=>{constposition=entity.components.get(Position);//... do your logic here});}}
Note that process can be async.
If your systems need to do asynchronous tasks, you can implement them as those.
Your engine can then run them as such.
This might be useful, if you do not have data which needs to be processed every frame.
In order to keep your focus on the actual system and not the boilerplate code around,
you can use the AbstractEntitySystem.
The class will help you by providing component types for directly defining an aspect for your system.
The above code would become:
import{System,Aspect}from'@trixt0r/ecs';classMySystemextendsAbstractEntitySystem<MyEntity>{constructor(){super(/* optional priority here */,[Position]);}processEntity(entity: MyEntity): void{constposition=entity.components.get(Position);//... do your logic here}}
Engine
An Engine ties systems and entities together.
It holds collections of both types, to which you can register listeners. But you could also register an EngineListener, to listen for actions happening inside an engine.
Here is a minimal example on how to initialize an engine and add systems and/or entities to it:
import{Engine,EngineMode}from'@trixt0r/ecs';// Init the engineconstengine=newEngine();engine.systems.add(newMySystem());engine.entities.add(newMyEntity());// anywhere in your business logic or main loopengine.run(delta);// if you want to perform your tasks asynchronouslyengine.run(delta,EngineMode.SUCCESSIVE);// Wait for a task to finish// or...engine.run(delta,EngineMode.PARALLEL);// Run all systems asynchronously in parallel
Support
If you find any odd behavior or other improvements, feel free to create issues.
Pull requests are also welcome!
Otherwise you can help me out by buying me a coffee.
VMinteq is considered as a state of the art reference in the context of chemical speciation computation. However, it is an old fashioned closed source Windows GUI application that cannot be integrated in other models.
The purpose of CHEMMISOL is to provide equivalent features in a flexible, performant, open source, cross platform and embeddable way.
The following table represents a non-exhaustive list of features supported by VMinteq (except for the “Solver algorithm”), and how they are currently supported by CHEMMISOL.
Even if CHEMMISOL already allows to solve equilibriums in complex chemical systems, a lot of features are still missing, and will probably never be included, depending on our own needs.
Even if the equilibrium solving algorithm of VMinteq seems to be based on the Newton method, the exact algorithm used is unclear. In consequence, the “solver algorithm” features cannot be compared directly with VMinteq.
[1] K. Meintjes and A. P. Morgan, “A methodology for solving chemical equilibrium systems,” Applied Mathematics and Computation, vol. 22, no. 4, pp. 333–361, Jun. 1987, doi:10.1016/0096-3003(87)90076-2.
Compilation and installation
Compile
The library can be compiled as a regular CMAKE project.
The library can be installed on the current system with:
cd build
cmake --install .
Depending on your OS and installation, you might need to run sudo cmake --install .
Specification of chemical systems
The definition of chemical systems in CHEMMISOL is based on the concept of components, chemical species and reactions.
Basically, to define a chemical system, it is required to:
Define a set of reactions.
Define components and their total quantities.
Components are the building blocks of reactions: the purpose of reactions is to specify how chemical components can combine to form complex chemical species.
Reactions
Chemical components basically represent canonical species that cannot be divided. A reaction must be specified as a set of reagents, associated to stoichiometric coefficients. By convention:
Reactants are specified with positive coefficients.
Products are specified with negative coefficients.
All reactants and products must correspond to components of the chemical system, except one reagent, that represents the produced species of the reaction.
Example 1
Reactions:
H2 <-> H + H
2 H2O <-> 4 H + O2
Components:
H
H2O (solvent)
The specification of this system is correct. The produced species of reaction 1 is then H2, and the produced species of reaction 2 is O2.
Example 2
Reactions:
H2 <-> H + H
2 H2O <-> 2 H2 + O2
Components:
H2
O2
The specification of this system is correct. The produced species of reaction 1 is then H, and the produced species of reaction 2 is H2O.
Example 3
Reactions:
H2 <-> H + H
2 H2O <-> 4 H + O2
Components:
H2
H2O (solvent)
The specification of this system is wrong, since two chemical species that are not components are identified in reaction 2: H and O2. In consequence, the produced species of reaction 2 cannot be properly identified.
Components and species
A chemical species is a concrete physical entity that lives in the chemical system and can interact with other species. Each chemical species is associated to a quantity (typically in mol), a concentration (typically in mol/l) and an activity (without unit, used in the computation of reaction quotients).
As seen in the reaction example above, chemical species can be defined in two ways:
Implicitly, as produced species of reactions.
Explicitly, by declaring components.
Indeed, each chemical component is automatically associated to a chemical species with the same name. However, the nature of a component is different from the nature of chemical species, since it represents the total quantity of species constituted from this component.
For example, let’s consider the following system:
Reactions:
H2O <-> OH- + H+
PO4 + 3H+ <-> H3PO4
Components:
H+
PO4
H2O (solvent)
Produced species are then OH- and H3PO4.
The total quantityN of the PO4 and H+ components are then defined as follows:
N(PO4) = n(PO4) + n(H3PO4)
N(H+) = n(H+) - n(OH-) + 3 * n(H3PO4)
where n denotes the quantity of each chemical species. Notice that n(PO4) and n(H+) denote the quantities of PO4 and H+ species, that are likely not equal to total quantities of PO4 and H+ components. See the ChemicalComponent documentation for more details about how the total quantities are computed.
In practice, the user input of the model represents the total quantity of each component. The actual quantity of each species is then determined by the solved equilibrium state of the chemical system.
Usage
Basic usage
The CHEMMISOL API aims to be as simple as possible, in order to facilitate its integration within other projects and models. Here is a basic usage example:
#include"chemmisol.h"usingnamespacechemmisol;intmain(int, char *[])
{
ChemicalSystem chemical_system;
// Defines the reaction H2O <-> OH- + H+ (log K = -13.997)
chemical_system.addReaction("OH-", -13.997, {
{"OH-", -1},
{"H+", -1},
{"H2O", 1}
});
// Defines the reaction Na+ + Cl- <-> NaCl (log K = -0.3)
chemical_system.addReaction("NaCl", -0.3, {
{"NaCl", -1},
{"Na+", AQUEOUS, 1}, // AQUEOUS specified here only for// demonstration purpose, since it should be// the default phase
{"Cl-", AQUEOUS, 1}
});
// Defines the reaction H2O + Na+ <-> NaOH + H+ (log K = -13.897)
chemical_system.addReaction("NaOH", -13.897, {
{"NaOH", -1},
{"H+", -1},
{"Na+", 1},
{"H2O", 1}
});
// Defines the Na+ component and sets its total concentration to 0.1 mol/l
chemical_system.addComponent("Na+", 0.1*mol/l);
// Defines the Cl- component and sets its total concentration to 0.1 mol/l
chemical_system.addComponent("Cl-", 0.1*mol/l);
// Defines the H2O component as a solvent
chemical_system.addSolvent("H2O");
// Automatically adds the H+ component and fixes the pH to 7
chemical_system.fixPH(7);
// Solves the equilibrium state
chemical_system.solveEquilibrium();
return0;
}
This basic example is available in the examples directory and can be run with:
cd build
./examples/basic_chemical_system/basic_chemical_system_example
Expected output:
[chemmisol-core] I Solving chemical equilibrium.
[chemmisol-core] I Init activities:
[chemmisol-core] I (C) Na+: 0.1
[chemmisol-core] I (C) Cl-: 0.1
[chemmisol-core] I (C) H2O: 1
[chemmisol-core] I (C) H+: 1e-07
[chemmisol-core] I OH-: 0
[chemmisol-core] I NaCl: 0
[chemmisol-core] I NaOH: 0
[chemmisol-core] I Solved activities:
[chemmisol-core] I (C) Na+: 0.0954352
[chemmisol-core] I (C) Cl-: 0.0954352
[chemmisol-core] I (C) H2O: 1
[chemmisol-core] I (C) H+: 1e-07
[chemmisol-core] I OH-: 1.00693e-07
[chemmisol-core] I NaCl: 0.00456476
[chemmisol-core] I NaOH: 1.20979e-08
Setting and fixing pH and quantities of other chemical components
The pH of the chemical system can be fixed with the fixPH() method.
However, it is also possible to initialize the pH of the system using the initPH() method. In this case, the pH is set as the total quantity of the H+ component (or any other user defined component eventually specified as argument by the user). The pH is then dynamically determined depending on the solved chemical equilibrium.
As fixing the pH is equivalent to fixing the concentration of H+, the concentration of any component can be fixed in CHEMMISOL, using the fixComponent() method.
The total quantity of a component can also be initially specified using the addComponent() method.
Create a new model that extends TheBatClaudio\EloquentMarkdown\Models\MarkdownModel:
useTheBatClaudio\EloquentMarkdown\Models\MarkdownModel;
class Page extends MarkdownModel
{
}
Get all markdown files
$pages = Page::all();
Get a markdown file by its id
Imagine to have a markdown file named homepage.md with the following content:
---
first_attribute: First attributesecond_attribute: Second attributethird_attribute: Third attribute
---
The time has come. You know it. In your mind. In your heart. In your soul. You tried to hold me back. But you can't,Bruce. You're weak. You're a shell. A rusty trap that cannot hold me. Let it go. Let me OUT.
You will get the file as Eloquent model using the find method:
$homepage = Page::find('homepage');
And you will find the following attributes:
echo$homepage->id; // homepageecho$homepage->file_name; // homepage.mdecho$homepage->file_path; // { YOUR STORAGE PATH }/homepage.mdecho$homepage->first_attribute; // First attributeecho$homepage->second_attribute; // Second attributeecho$homepage->third_attribute; // Third attributeecho$homepage->content; // The time has come. You know it [...]
Using Markdown with dates (e.g. YYYY-MM-DD-your-markdown.md)
Create a new model that extends TheBatClaudio\EloquentMarkdown\Models\MarkdownModel and uses TheBatClaudio\EloquentMarkdown\Models\Traits\WithDate trait:
useTheBatClaudio\EloquentMarkdown\Models\MarkdownModel;
useTheBatClaudio\EloquentMarkdown\Models\Traits\WithDate;
class Article extends MarkdownModel
{
use WithDate;
}
You will find two new attributes inside your model:
date: a Carbon instance with the date defined on your markdown file name (e.g. 2024-05-15 for 2024-05-15-your-markdown.md)
slug: the slug of your markdown (e.g. your-markdown for 2024-05-15-your-markdown.md)
Different path for different models
You can extend getContentPath inside your model to use different paths for different models:
useTheBatClaudio\EloquentMarkdown\Models\MarkdownModel;
useTheBatClaudio\EloquentMarkdown\Models\Traits\WithDate;
class Article extends MarkdownModel
{
use WithDate;
protectedstaticfunctiongetContentPath(): string
{
return'articles';
}
}
class Page extends MarkdownModel
{
protectedstaticfunctiongetContentPath(): string
{
return'pages';
}
}
SafeTalk is an AI-driven therapy simulation tool designed to train and evaluate therapists. By simulating patient
personalities and providing a structured environment for therapist-patient interactions, it helps improve therapeutic
skills in a risk-free setting.
The system utilizes language models like Ollama’s Llama 3.2 to simulate realistic therapy conversations, and integrates
a supervisor evaluation mechanism to assess therapist performance.
running make app will launch a streamlit application allowing you to chat with a patient.
Note (Mac Users)
If you choose to use the Docker ollama, run make docker-llama but be warned – on Mac there is still no
option for GPU support with Docker, so it will run on the CPU and things will be very slow.
Personally, I would just run the Mac Ollama distribution and have the server running locally
using your GPU.
If you’re using Windows… you’ll have to figure it out yourself 🙂
Features
Therapy Simulation: Simulate therapy sessions between a virtual patient and a therapist.
Customizable Patient Personas: Define different patient personalities based on predefined templates.
Therapist Evaluation: A supervisor module evaluates the therapist’s performance after each session based on set
criteria.
Installation
make venv
How It Works
The pipeline runs a therapy session where a virtual patient (e.g. Mike) interacts with a therapist.
The patient’s personality is driven by a prompt template that simulates some mental illness, which in practice would be
unknown to the therapist and part of them trying to understand the patient.
The therapist’s performance is then evaluated by a supervisor.
Key Components:
Patient Persona: The patient has a predefined personality and emotional state (e.g., shy, self-critical,
overwhelmed by stress). The patient’s responses are dynamically generated based on the therapist’s input.
Therapist: The therapist interacts with the patient based on the conversation, adjusting their responses to foster
a productive therapeutic session.
Supervisor: The supervisor evaluates the therapist’s responses based on predefined criteria (e.g., empathy,
effectiveness, engagement).
Example
To run the example (using the anxiety template), just run the make command below:
make app
Explanation of the Script:
Load Patient Prompt: A patient persona is loaded from a template (anxiety.template) that defines Mike’s
emotional state and personality traits.
Create LLM Model: I use OllamaLLM with the llama3.2 model to generate responses from both the patient and
therapist, but you can use whatever you want.
Start Therapy Session: The therapy session begins with the patient and therapist interacting. The session history
is tracked.
Supervisor Evaluation: After the session, the supervisor evaluates the therapist’s performance based on
predefined criteria from the supervisor.template.
Usage
You can create new templates for different patient types or therapeutic approaches by generating new template files. I
use the APA website to get case studies.
This project contains 3 parts to visualize your k8s graph.
Docker container is already available on DockerHub so you can skip
part 1. and 2. and just create the k8s deployment.
Node server, that polls the information from k8s api and creates
a graph using D3.
Dockerfile, that creates the container.
k8s yaml file, that will create a service and a deployment with two containers.
kubectl started with proxy, so the node server can
access the k8s api.
Node server, that renders the graph using D3.
Node server
Relevant files for the node server are server.js, k8s.html
and package.json.
The node server polls – by default – every second the k8s api and
extracts the relevant information to create the graph visualization
which is implemented in the html file.
The following list shows the values,
that can be configured via env variables:
masterSize: 30
minionSize: 30
podSize: 15
linkSizePodToMinion: 500
linkSizeMinionToMaster: 800
dummyNodes: 0 – Create dummy nodes for debugging purposes
Yeah, this is the Dockerfile that creates the docker container with
the node server. Docker container is published at DockerHub rilleralle/k8s-graph
K8s Yaml File
Yaml file creates one service and one deployment - with two container.
Service:
By default the service type is NodePort.
If you are running k8s on a cloud service like AWS or Google
you can also use aLoadBalancer.
Read more about Service Types.
Deployment:
Creates a deployment with two container.
kubectl container, that starts with proxy command so
the node server can access the k8s api to fetch the required
information to render the graph.
Node server container. Docker image is available on DockerHub docker pull rilleralle/k8s-graph
Set env variables to configure node server. See section Node server
Create deployment
$ kubectl apply -f k8s-graph.yaml
RBAC
With K8S 1.9.2 the default user does not have access to the API any more. Please create a service account that has read access for the endpoints nodes and pods. Use this account to execute the graph container.
You can also bypass the RBAC by making the default user a cluster-admin.
Please be aware, that this could be a secutiry issue!
calibredb command is passed to the running docker container with clutil utility.
If calibredb command requires library path to be specified, then library name (as specified in the LIBRARIES environment variable) should be used.
The clutil utility translates library name to the library path.
For example, to list the specified book fields in the library <library_name>, next command can be used:
sudo clutil calibredb list --library-path <library_name> -f id,authors,author_sort,title,series,series_index,publisher,tags
Create backup
sudo clutil backup <filename>
Backup file /var/backups/calibre/<filename>.tar.gz will be created.
Restore backup
sudo clutil restore <filename>
Command line (bash)
sudo clutil bash
Apache mod_proxy configuration
Calibre web server can be located with another web applications.
For example, mercurial, bugzilla, wiki etc can be run as docker containers on the same host.
In this case apache server can be used to redirect requests to different docker containers.
Specify libraries names (with colon as a delimiter) in /usr/sbin/calibre file:
docker run ... -e LIBRARIES="library-1:library-2:library-3" ...
Start calibre service:
sudo service calibre start
How to provide anonymous access to the libraries
Stop calibre service:
sudo service calibre stop
Specify container environment variable WITHAUTH in /usr/sbin/calibre file:
docker run ... -e WITHAUTH="false" ...
Start calibre service:
sudo service calibre start
Everyone can access the libraries, but no one can make changes.
To upload new books, or to change the book metadata, the container environment variable WITHAUTH should be true.
After the changes are made, the container environment variable WITHAUTH can be changed to false again.
How to clear book metadata
sudo clutil clearmetadata <library> <column_name>
This command will clean the specified <column_name> for all books in the specified <library>.
The valid column names are:
identifiers
languages
pubdate
publisher
timestamp
rating
How to remove books
To remove the book with id <id> from the library <library_name>, the next command can be used:
Calibre gives 777 permit to all folders in the libraries.
Calibre also gives execute permission to the log files.
To remove excessive permissions, just restart calibre service:
Through CloudFormation on AWS, create a VPC network environment with a single click, and deploy a Whisper model within it to run a UI based on Streamlit.
Project Includes:
ui.py: A Python application based on Streamlit, providing a simple Web interface to use the Whisper model for converting audio to text.
api.py: A FastAPI application, providing an API to query the result file from the S3 bucket.
whisper_sqs_message_processor.py: A Python consumer application to handle messages from the AWS SQS queue. The event message will be pushed to the SQS queue after files are uploaded to the S3 bucket.
whisper-prod.yaml: An AWS CloudFormation YAML file that automatically install the service.
Installation Guide:
Accept the user agreement for the following models (click through the links below and accept the terms):
Through CloudFormation on AWS, create a VPC network environment with a single click, and deploy a Whisper model within it to run a UI based on Streamlit.
Project Includes:
ui.py: A Python application based on Streamlit, providing a simple Web interface to use the Whisper model for converting audio to text.
api.py: A FastAPI application, providing an API to query the result file from the S3 bucket.
whisper_sqs_message_processor.py: A Python consumer application to handle messages from the AWS SQS queue. The event message will be pushed to the SQS queue after files are uploaded to the S3 bucket.
whisper-prod.yaml: An AWS CloudFormation YAML file that automatically install the service.
Installation Guide:
Accept the user agreement for the following models (click through the links below and accept the terms):
CPU Scheduling is a process of determining which process will own CPU for execution while another process is on hold.
The main task of CPU scheduling is to make sure that whenever the CPU remains idle, the OS at least select one of the processes available in the ready queue for execution.
The selection process will be carried out by the CPU scheduler.
It selects one of the processes in memory that are ready for execution.
Types of CPU scheduling Algorithm
There are mainly six types of process scheduling algorithms
First Come First Serve is the full form of FCFS. It is the easiest and most simple CPU scheduling algorithm. In this type of algorithm, the process which requests the CPU gets the CPU allocation first. This scheduling method can be managed with a FIFO queue.
As the process enters the ready queue, its PCB (Process Control Block) is linked with the tail of the queue. So, when CPU becomes free, it should be assigned to the process at the beginning of the queue.
Characteristics of FCFS method:
It offers non-preemptive and pre-emptive scheduling algorithm.
Jobs are always executed on a first-come, first-serve basis
It is easy to implement and use.
However, this method is poor in performance, and the general wait time is quite high.
Shortest Remaining Time
The full form of SRT is Shortest remaining time. It is also known as SJF preemptive scheduling. In this method, the process will be allocated to the task, which is closest to its completion. This method prevents a newer ready state process from holding the completion of an older process.
Characteristics of SRT scheduling method:
This method is mostly applied in batch environments where short jobs are required to be given preference.
This is not an ideal method to implement it in a shared system where the required CPU time is unknown.
Associate with each process as the length of its next CPU burst. So that operating system uses these lengths, which helps to schedule the process with the shortest possible time.
Priority Based Scheduling
Priority scheduling is a method of scheduling processes based on priority. In this method, the scheduler selects the tasks to work as per the priority.
Priority scheduling also helps OS to involve priority assignments.
The processes with higher priority should be carried out first, whereas jobs with equal priorities are carried out on a round-robin or FCFS basis. Priority can be decided based on memory requirements, time requirements, etc.
Round-Robin Scheduling
Round robin is the oldest, simplest scheduling algorithm. The name of this algorithm comes from the round-robin principle, where each person gets an equal share of something in turn. It is mostly used for scheduling algorithms in multitasking. This algorithm method helps for starvation free execution of processes.
Characteristics of Round-Robin Scheduling
Round robin is a hybrid model which is clock-driven
Time slice should be minimum, which is assigned for a specific task to be processed. However, it may vary for different processes.
It is a real time system which responds to the event within a specific time limit.
Shortest Job First
SJF is a full form of (Shortest job first) is a scheduling algorithm in which the process with the shortest execution time should be selected for execution next. This scheduling method can be preemptive or non-preemptive. It significantly reduces the average waiting time for other processes awaiting execution.
Characteristics of SJF Scheduling
It is associated with each job as a unit of time to complete.
In this method, when the CPU is available, the next process or job with the shortest completion time will be executed first.
It is Implemented with non-preemptive policy.
This algorithm method is useful for batch-type processing, where waiting for jobs to complete is not critical.
It improves job output by offering shorter jobs, which should be executed first, which mostly have a shorter turnaround time.
Multiple-Level Queues Scheduling
This algorithm separates the ready queue into various separate queues. In this method, processes are assigned to a queue based on a specific property of the process, like the process priority, size of the memory, etc.
However, this is not an independent scheduling OS algorithm as it needs to use other types of algorithms in order to schedule the jobs.
Characteristic of Multiple-Level Queues Scheduling:
Multiple queues should be maintained for processes with some characteristics.
Every queue may have its separate scheduling algorithms.
Priorities are given for each queue.
The Purpose of a Scheduling algorithm
Here are the reasons for using a scheduling algorithm:
The CPU uses scheduling to improve its efficiency.
It helps you to allocate resources among competing processes.
The maximum utilization of CPU can be obtained with multi-programming.
The processes which are to be executed are in ready queue.[1]