예제 #1
0
void AMLoopAction3::internalOnCurrentActionProgressChanged(double numerator, double denominator)
{
	if(internalAllActionsHaveExpectedDuration()) {
		double totalNumerator = 0, totalDenominator = 0;
		for(int i=0, cc=subActionCount(); i<cc; i++) {
			AMAction3* action = subActionAt(i);

			double expectedSecs = action->info()->expectedDuration();
			totalDenominator += expectedSecs*loopCount();
			int timesFinished = currentIteration_;
			if(i < currentSubActionIndex_)
				timesFinished++;
			totalNumerator += expectedSecs*timesFinished;

			if(i == currentSubActionIndex())	// if it's the current action, we have some partial progress.
				totalNumerator += numerator/denominator * expectedSecs;
		}
		setProgress(totalNumerator, totalDenominator);
		setExpectedDuration(totalDenominator);
	}
	// Otherwise, assume every subaction makes up an equal unit ('1') of the total amount of work. Our denominator will be the number of sub-actions * the number of loops, and our numerator will be the sub-actions we've completed (plus the current sub-action's fraction done).
	else {
		double totalDenominator = subActionCount()*loopCount();
		double totalNumerator = subActionCount()*currentIteration_;	// add the completed full loops
		totalNumerator += currentSubActionIndex_;	// add the actions done in this loop
		totalNumerator += numerator/denominator;	// add the fraction done for the current action.
		setProgress(totalNumerator, totalDenominator);
		setExpectedDuration(runningTime()*totalDenominator/totalNumerator);
	}
}
예제 #2
0
void AMAppController::updateScanEditorModelItem()
{
	// Get the action, or if it's in a list, the current running action.
	AMAction3 *currentAction = AMActionRunner3::workflow()->currentAction();
	AMScanAction *action = 0;

	if (currentAction && !currentAction->hasChildren())
		action = qobject_cast<AMScanAction *>(currentAction);

	else if (currentAction && currentAction->hasChildren()){

		AMListAction3 *listAction = qobject_cast<AMListAction3 *>(currentAction);

		if (listAction)
			action = qobject_cast<AMScanAction *>(listAction->currentSubAction());
	}

	// Do something with it if the action is valid.
	if (action && (action->state() == AMAction3::Running || action->inFinalState())){

		AMGenericScanEditor *editor = editorFromScan(action->controller()->scan());

		if (!editor)
			return;

		QString stateString;

		switch(action->state()){

		case AMAction3::Running:
			stateString = "running";
			break;

		case AMAction3::Succeeded:
			stateString = "succeeded";
			break;

		case AMAction3::Failed:
			stateString = "failed";
			break;

		case AMAction3::Cancelled:
			stateString = "cancelled";
			break;

		default:
			stateString = "default";
			break;
		}

		AMScanEditorModelItem *item = (AMScanEditorModelItem *)(mw_->windowPaneModel()->itemFromIndex(mw_->windowPaneModel()->indexForPane(editor)));

		if (item)
			item->scanActionStateChanged(stateString, editor == mw_->currentPane());
	}
}
예제 #3
0
void AMLoopAction3::internalCleanupAction(AMAction3 *action)
{
	AMAction3 *cleanupAction = action ? action : currentSubAction_;

	internalDisconnectAction(cleanupAction);
	// delete it later (since we might still be executing inside the action's functions).
	cleanupAction->scheduleForDeletion();
	//cleanupAction->deleteLater();

	if (!action)
		currentSubAction_ = 0;
}
예제 #4
0
void CLSSIS3820Scaler::measureDarkCurrent(int secondsDwell)
{
	AMAction3 *action = createMeasureDarkCurrentAction(secondsDwell);

	if (action) {
		connect( action, SIGNAL(cancelled()), action, SLOT(deleteLater()) );
		connect( action, SIGNAL(failed()), action, SLOT(deleteLater()) );
		connect( action, SIGNAL(succeeded()), action, SLOT(deleteLater()) );

		action->start();
	}
}
void CLSSIS3820ScalerDarkCurrentMeasurementAction::startImplementation()
{
	// Must have a valid, connected scaler.

	CLSSIS3820Scaler *scaler = CLSBeamline::clsBeamline()->scaler();

	if (! (scaler && scaler->isConnected()) ) {
		QString message = QString("There was an error measuring scaler dark current. The scaler is invalid or not connected.");
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_INVALID_SCALER, message);
		setFailed(message);
	}

	// Must have a valid dwell time.

	double secondsDwell = scalerDarkCurrentMeasurementActionInfo()->dwellTime();

	if (!validDwellTime(secondsDwell)) {
		QString message = QString("There was an error measuring scaler dark current. The dwell time provided (%1 s) is invalid.").arg(secondsDwell);
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_INVALID_DWELL_TIME, message);
		setFailed(message);
	}

	// Update pre-measurement settings, to be restored once measurement is complete.

	measurementInitialization();

	// Create measurement action.

	AMAction3 *measurementAction = createMeasurementAction(secondsDwell);

	// Make connections and start action.

	if (measurementAction) {

		startedMapper_->setMapping(measurementAction, measurementAction);
		failedMapper_->setMapping(measurementAction, measurementAction);
		succeededMapper_->setMapping(measurementAction, measurementAction);

		connect( measurementAction, SIGNAL(started()), startedMapper_, SLOT(map()) );
		connect( measurementAction, SIGNAL(failed()), failedMapper_, SLOT(map()) );
		connect( measurementAction, SIGNAL(succeeded()), succeededMapper_, SLOT(map()) );

		measurementAction->start();

	} else {

		QString message = QString("There was an error measuring scaler dark current. An invalid measurement action was generated.");
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_INVALID_ACTION, message);
		setFailed(message);
	}
}
예제 #6
0
AMAction3 * AMListAction3::takeSubActionAt(int index)
{
	if(state() != Constructed) {
		AMErrorMon::debug(this, AMLISTACTION3_CANNOT_REMOVE_SUBACTION_ONCE_RUNNING, "Cannot remove sub-actions once the action is already running.");
		return 0;
	}

	if(index <0 || index >= subActions_.count())
		return 0;

	emit subActionAboutToBeRemoved(index);
	AMAction3* action = subActions_.takeAt(index);
	action->setParentAction(0);
	emit subActionRemoved(index);

	return action;
}
QWidget * AMActionRunnerQueueItemDelegate3::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
	Q_UNUSED(option)

	const AMActionRunnerQueueModel3* model = qobject_cast<const AMActionRunnerQueueModel3*>(index.model());
	if(!model)
		return 0;

	AMAction3* action = model->actionAtIndex(index);
	if(!action)
		return 0;

	QWidget* rv = AMActionRegistry3::s()->createEditorForInfo(action->info());
	if(rv) {
		rv->setParent(parent);
		rv->setFocusPolicy(Qt::StrongFocus);
		rv->setBackgroundRole(QPalette::Window);
		rv->setAutoFillBackground(true);
	}

	return rv;
}
예제 #8
0
AMControl::FailureExplanation CLSMAXvMotor::calibrate(double oldValue, double newValue)
{
	// Check that this motor is connected and able to be calibrated before proceeding.

	if (!isConnected()) {
		AMErrorMon::alert(this, CLSMAXVMOTOR_NOT_CONNECTED, QString("Failed to calibrate %1: motor is not connected.").arg(name()));
		return AMControl::NotConnectedFailure;
	}

	if (!canCalibrate()) {
		AMErrorMon::alert(this, CLSMAXVMOTOR_CANNOT_CALIBRATE, QString("Failed to calibrate %1: motor cannot currently be calibrated.").arg(name()));
		return AMControl::OtherFailure;
	}

	// Proceed with creating calibration action.

	AMAction3 *action = createCalibrationAction(oldValue, newValue);

	// Check that a valid calibration action was generated.
	// If an invalid calibration action was generated, abort the calibration.

	if (!action) {
		AMErrorMon::alert(this, CLSMAXVMOTOR_INVALID_CALIBRATION_ACTION, QString("Did not calibrate %1: invalid calibration action generated.").arg(name()));
		return AMControl::LimitFailure;
	}

	// Proceed with initializing the calibration action.
	// Connect it's final-state signals to its deleteLater() slot to prevent memory leak.

	connect( action, SIGNAL(cancelled()), action, SLOT(deleteLater()) );
	connect( action, SIGNAL(failed()), action, SLOT(deleteLater()) );
	connect( action, SIGNAL(succeeded()), action, SLOT(deleteLater()) );

	// Run action.

	action->start();

	return AMControl::NoFailure;
}
예제 #9
0
void VESPERSBeamSelectorView::changeBeam(int id)
{
	AMAction3 *action = 0;

	switch(id){

	case 0:
		action = VESPERSBeamline::vespers()->createBeamChangeAction(VESPERS::Pink);
		break;

	case 1:
		action = VESPERSBeamline::vespers()->createBeamChangeAction(VESPERS::TenPercent);
		break;

	case 2:
		action = VESPERSBeamline::vespers()->createBeamChangeAction(VESPERS::OnePointSixPercent);
		break;

	case 3:
		action = VESPERSBeamline::vespers()->createBeamChangeAction(VESPERS::Si);
		break;
	}

	if (!action)
		return;

	progressBar_->setRange(0, 0);
	progressBar_->show();
	connect(action, SIGNAL(cancelled()), this, SLOT(onBeamChangeCompleted()));
	connect(action, SIGNAL(failed()), this, SLOT(onBeamChangeCompleted()));
	connect(action, SIGNAL(succeeded()), this, SLOT(onBeamChangeCompleted()));
	connect(action, SIGNAL(cancelled()), action, SLOT(deleteLater()));
	connect(action, SIGNAL(failed()), action, SLOT(deleteLater()));
	connect(action, SIGNAL(succeeded()), action, SLOT(deleteLater()));
	action->start();
}
AMAction3 * SGMHexapodTransformedAxis::createWaitForCompletionActions()
{
    AMListAction3* waitActions = new AMListAction3(new AMListActionInfo3("Waiting for coordinated move",
            "Waiting for coordinated move"),
            AMListAction3::Sequential);

    waitActions->addSubAction(AMActionSupport::buildControlWaitAction(trajectoryStartControl_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance));

    AMListAction3 *recorderActions = new AMListAction3(new AMListActionInfo3("Waiting for data recorders to monitor", "Waiting for data recorders to monitor"), AMListAction3::Parallel);
    // Read action for the detector emulators for data recorders. These detectors are set to AMDetectorDefinitions::WaitRead, which will mean they will only read once they monitor.
    AMAction3 *hexapodXRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodXRecorder")->createReadAction();
    hexapodXRecorderDetectorReadAction->setGenerateScanActionMessage(true);
    recorderActions->addSubAction(hexapodXRecorderDetectorReadAction);
    AMAction3 *hexapodYRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodYRecorder")->createReadAction();
    hexapodYRecorderDetectorReadAction->setGenerateScanActionMessage(true);
    recorderActions->addSubAction(hexapodYRecorderDetectorReadAction);
    AMAction3 *hexapodZRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodZRecorder")->createReadAction();
    hexapodZRecorderDetectorReadAction->setGenerateScanActionMessage(true);
    recorderActions->addSubAction(hexapodZRecorderDetectorReadAction);
    AMAction3 *hexapodTimeRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodTimeRecorder")->createReadAction();
    hexapodTimeRecorderDetectorReadAction->setGenerateScanActionMessage(true);
    recorderActions->addSubAction(hexapodTimeRecorderDetectorReadAction);


    AMListAction3 *positionWaitActions = new AMListAction3(new AMListActionInfo3("Waiting for hexapod positions", "Waiting for hexapod positions"), AMListAction3::Parallel);
    // We need to add 1.5 seconds to the delta time, as the data recorder is slow
    AMAction3* positionWaitAction = AMActionSupport::buildControlWaitAction(this, lastEndPoint_, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance);

    /*
    AMAction3* statusXWaitAction = AMActionSupport::buildControlWaitAction(globalXAxisStatus_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance);
    AMAction3* statusYWaitAction = AMActionSupport::buildControlWaitAction(globalYAxisStatus_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance);
    AMAction3* statusZWaitAction = AMActionSupport::buildControlWaitAction(globalZAxisStatus_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance);
    */

    positionWaitActions->addSubAction(positionWaitAction);
    /*
    positionWaitActions->addSubAction(statusXWaitAction);
    positionWaitActions->addSubAction(statusYWaitAction);
    positionWaitActions->addSubAction(statusZWaitAction);
    */
    /*
    waitActions->addSubAction(positionWaitAction);
    waitActions->addSubAction(statusXWaitAction);
    waitActions->addSubAction(statusYWaitAction);
    waitActions->addSubAction(statusZWaitAction);
    */

    AMListAction3 *centralParallelActions = new AMListAction3(new AMListActionInfo3("Parallel List of Recorder and Position Waits", "Parallel List of Recorder and Position Waits"), AMListAction3::Parallel);
    centralParallelActions->addSubAction(recorderActions);
    centralParallelActions->addSubAction(positionWaitActions);

    waitActions->addSubAction(centralParallelActions);

    // Return the data recorder to the off state (we need a clean up actions function adding to the AMControl API)
    waitActions->addSubAction(AMActionSupport::buildControlMoveAction(dataRecorderStatus_, 0));
    waitActions->addSubAction(AMActionSupport::buildControlWaitAction(dataRecorderStatus_, 0, 2.0, AMControlWaitActionInfo::MatchWithinTolerance));
    waitActions->addSubAction(AMActionSupport::buildControlMoveAction(systemVelocity_, lastSavedVelocity_));
    waitActions->addSubAction(AMActionSupport::buildControlWaitAction(systemVelocity_, lastSavedVelocity_, 2.0, AMControlWaitActionInfo::MatchWithinTolerance));

    return waitActions;
}