FastResponseMatrixTool.java
// @formatter:off
/*******************************************************************************
*
* This file is part of JMad.
*
* Copyright (c) 2008-2011, CERN. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
// @formatter:on
/**
*
*/
package cern.accsoft.steering.jmad.tools.response;
import Jama.Matrix;
import cern.accsoft.steering.jmad.domain.beam.Beam.Direction;
import cern.accsoft.steering.jmad.domain.ex.JMadModelException;
import cern.accsoft.steering.jmad.domain.machine.filter.NameFilter;
import cern.accsoft.steering.jmad.domain.optics.OpticPoint;
import cern.accsoft.steering.jmad.domain.types.enums.JMadPlane;
import cern.accsoft.steering.jmad.model.JMadModel;
import java.util.List;
import java.util.function.BiConsumer;
/**
* @author Kajetan Fuchsberger (kajetan.fuchsberger at cern.ch)
*/
public class FastResponseMatrixTool implements ResponseMatrixTool {
@Override
public Matrix calcResponseMatrix(JMadModel model, ResponseRequest request) throws JMadModelException {
List<String> monitorNames = request.getMonitorNames();
List<String> correctorNames = request.getCorrectorNames();
List<JMadPlane> monitorPlanes = request.getMonitorPlanes();
List<JMadPlane> correctorPlanes = request.getCorrectorPlanes();
Matrix matrix = new Matrix(monitorNames.size(), correctorNames.size());
for (int i = 0; i < monitorNames.size(); i++) {
String monitorName = monitorNames.get(i);
JMadPlane monitorPlane = monitorPlanes.get(i);
for (int j = 0; j < correctorNames.size(); j++) {
String strengthElementName = correctorNames.get(j);
JMadPlane correctorPlane = correctorPlanes.get(j);
if (!monitorPlane.equals(correctorPlane)) {
matrix.set(i, j, 0);
continue;
}
OpticPoint opticsMonitor = model.getOptics().getPointByName(monitorName);
OpticPoint opticsCorrector = model.getOptics().getPointByName(strengthElementName);
if (opticsMonitor == null) {
throw new JMadModelException("Could not find Monitor '" + monitorName + "' in model '"
+ model.getName() + "'. Perhaps you are using the wrong model?");
}
if (opticsCorrector == null) {
throw new JMadModelException("Could not find Corrector '" + strengthElementName + "' in model '"
+ model.getName() + "'. Perhaps you are using the wrong model?");
}
double betaMonitor;
double betaCorrector;
double phaseMonitor;
double phaseCorrector;
if (monitorPlane == JMadPlane.H) {
betaMonitor = opticsMonitor.getBetx();
betaCorrector = opticsCorrector.getBetx();
phaseMonitor = opticsMonitor.getMux();
phaseCorrector = opticsCorrector.getMux();
} else {
betaMonitor = opticsMonitor.getBety();
betaCorrector = opticsCorrector.getBety();
phaseMonitor = opticsMonitor.getMuy();
phaseCorrector = opticsCorrector.getMuy();
}
double value = 0;
/*
* when using beam2 (inverted beam) the phase decreases in beam direction!
*/
if (Direction.MINUS.equals(model.getActiveRange().getRangeDefinition().getSequenceDefinition()
.getBeam().getDirection())) {
phaseMonitor *= -1;
phaseCorrector *= -1;
}
/*
* XXX the following is at the moment only correct for transfer-lines! Not valid for closed orbits!
*/
if (phaseMonitor > phaseCorrector) {
value = Math.sqrt(betaMonitor * betaCorrector)
* Math.sin((phaseMonitor - phaseCorrector) * 2 * Math.PI);
}
/*
* inverting if it relates to a corrector that should be inverted by definition
*/
for (NameFilter filter : model.getActiveRange().getCorrectorInvertFilters()) {
if (filter.isConcerned(strengthElementName, correctorPlane)) {
value *= -1;
break;
}
}
/*
* inverting if it relates to a monitor that should be inverted by definition
*/
for (NameFilter filter : model.getActiveRange().getMonitorInvertFilters()) {
if (filter.isConcerned(monitorName, monitorPlane)) {
value *= -1;
break;
}
}
matrix.set(i, j, value);
}
}
return matrix;
}
@Override
public void addProgressListener(BiConsumer<ResponseRequest, Integer> listener) {
/* do not support progress listeners */
}
@Override
public void removeProgressListener(BiConsumer<ResponseRequest, Integer> listener) {
/* do not support progress listeners */
}
}