Phoenix is a highly modular and API driven experiment independent event display that uses three.js for processing and presenting detector geometry and event data. Because of its modular nature, Phoenix can easily be adapted for and extended to work with any experiment.
The phoenix-ui-components
package provides a set of modern UI Angular components that are linked with the event display and can perform useful operations like applying cuts, saving/loading state, applying clipping etc.
If you already have an application you want to use the event display with, you can move to the Setting up the event display section.
To start, you will need Node.js and npm (which comes with Node.js).
Then, install Angular.
npm install -g @angular/cli
Now, using the Angular CLI, create a new Angular app.
ng new event-display-app --style scss --routing true --interactive false
Make sure the newly created app works.
cd event-display-app
ng serve --open
Now that you have an app set up. Install the phoenix-ui-components
package to use the Phoenix components in your app.
npm install phoenix-ui-components
Add the the Bootstrap stylesheet to the src/index.html
file of your app.
<head>
...
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
Go to the src/styles.scss
file of your app and import the global Phoenix styles.
@import 'phoenix-ui-components/theming';
Download these assets (icons and images used by the Phoenix UI components) and put them in the src/assets
directory of your app.
With this, the app is ready and we can move onto setting up the event display in this app.
With the app now set up. Install the phoenix-event-display
package in the app.
npm install phoenix-event-display
The next step would be to create an Angular component so that we can use the event display.
For this, navigate to the src/app
directory of your app in the terminal and use the Angular CLI to generate a component.
ng generate component main-display
This will create a main-display
folder with the component source files.
Now, open the main-display.component.html
file and use the Phoenix UI components to set up the UI.
<app-nav></app-nav>
<!-- UI menu at the bottom -->
<app-ui-menu></app-ui-menu>
<app-experiment-info experiment="atlas" experimentTagline="ATLAS Experiment at CERN"></app-experiment-info>
<!-- Phoenix menu at the top right -->
<app-phoenix-menu [rootNode]="phoenixMenuRoot"></app-phoenix-menu>
<div id="eventDisplay"></div>
The [rootNode]="phoenixMenuRoot"
specified here for the Phoenix menu will be a defined in main-display.component.ts
.
One can easily customize the app-ui-menu. There are 2 main ways :
- just adding buttons at the end of it by inserting the corresponding components with the
app-ui-menu
declaration :
<app-ui-menu>
<app-cycle-events [interval]="5000"></app-cycle-events>
</app-ui-menu>
will add a button to cycle through events every 5s at the end of the menu bar
- redefine the manu bar completely using
app-ui-menu-wrapper
instead ofapp-ui-menu
:
<app-ui-menu-wrapper>
<app-event-selector></app-event-selector>
<app-cycle-events [interval]="5000"></app-cycle-events>
</app-ui-menu-wrapper>
This defines a very restricted menu with only the event selector and the event cycling button
Finally, open the main-display.component.ts
file and initialize the Phoenix event display using the intermediate Angular EventDisplayService
.
import { Component, OnInit } from '@angular/core';
import {EventDisplayService, PhoenixUIModule} from 'phoenix-ui-components';
import { Configuration, PhoenixLoader, PresetView, ClippingSetting, PhoenixMenuNode } from 'phoenix-event-display';
@Component({
selector: 'app-main-display',
standalone: true,
imports: [
PhoenixUIModule
],
templateUrl: './main-display.component.html',
styleUrl: './main-display.component.scss'
})
export class MainDisplayComponent implements OnInit {
/** The root Phoenix menu node. */
phoenixMenuRoot = new PhoenixMenuNode("Phoenix Menu");
constructor(private eventDisplay: EventDisplayService) { }
ngOnInit() {
// Create the event display configuration
const configuration: Configuration = {
eventDataLoader: new PhoenixLoader(),
presetViews: [
// simple preset views, looking at point 0,0,0 and with no clipping
new PresetView('Left View', [0, 0, -12000], [0, 0, 0], 'left-cube'),
new PresetView('Center View', [-500, 12000, 0], [0, 0, 0], 'top-cube'),
// more fancy view, looking at point 0,0,5000 and with some clipping
new PresetView('Right View', [0, 0, 12000], [0, 0, 5000], 'right-cube', ClippingSetting.On, 90, 90)
],
// default view with x, y, z of the camera and then x, y, z of the point it looks at
defaultView: [4000, 0, 4000, 0, 0 ,0],
phoenixMenuRoot: this.phoenixMenuRoot,
// Event data to load by default
defaultEventFile: {
// (Assuming the file exists in the `src/assets` directory of the app)
eventFile: 'assets/jive_xml_event_data.xml',
eventType: 'jivexml'
},
}
// Initialize the event display
this.eventDisplay.init(configuration);
// Load detector geometry (assuming the file exists in the `src/assets` directory of the app)
this.eventDisplay.loadGLTFGeometry('assets/detector.gltf', 'Detector');
}
}
(!) It is assumed that you use your data and detector geometry instead of links provided in
eventFile
and loadGLTFGeometry
above. For testing purposes, you may take geometry and events at:
Once the experiment component is created, you will need to set up a route so it can be served through a URL.
The app we generated already has some data. So delete the existing app content and replace it with a router outlet.
Go to src/app/app.component.html
and replace all content with this code:
<router-outlet></router-outlet>
Now, navigate to src/app/app.routes.ts
and add the routing for the experiment component we created.
import { Routes } from '@angular/router';
import {MainDisplayComponent} from "./main-display/main-display.component";
export const routes: Routes = [
{ path: '', component: MainDisplayComponent }
];
This will serve the experiment component through the base URL /
of the server.
Finally, you can start the app with npm start
and navigate to http://localhost:4200
where you will see the experiment component in action.
Phoenix event display may delay the updates of the Angular framework. Your
application should have the same version of Angular as phoenix-ui-components
package
You may check "dependencies" section of
phoenix-ui-components package.json here
then copy the correct version to your package.json and run npm install
.
What is happening? One of the javascript dependencies may try to build some C++ code on your machine. For this it uses node-gyp, which in turn, uses your machine compiler and installed libraries. This may cause some errors.
-
On Windows, you may experience
npm error gyp ERR
while trying to runnpm install phoenix-ui-components
. In general, you need to install and make available modern python version and MS C++ redistributable.
The later might be installed standalone or as a bundle of VS Community edition. More in this SO answer -
On linux machines you may need libgl and gcc building tools to be installed. E.g. on ubuntu:
sudo apt-get install -y build-essential libgl1-mesa-dev
The provided setup should work while one runs ng serve
or its alias npm start
.
There is another common command ng build
or npm run build
same as npm run watch
.
The later commands my not run falling with multiple errors around require("...")
.
One of the options of fixing it is using custom webpack builder configuration in
angular.json file. You may look here as an example
and adjust it for your project