package uk.ac.ed.inf.biopepa.ui.wizards.export;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import uk.ac.ed.inf.biopepa.core.sba.ComponentRelationsInferer;
import uk.ac.ed.inf.biopepa.core.sba.LineStringBuilder;
import uk.ac.ed.inf.biopepa.ui.interfaces.BioPEPAModel;
import uk.ac.ed.inf.biopepa.ui.views.BioPEPACompRelationsView;
import uk.ac.ed.inf.biopepa.ui.wizards.timeseries.ReactionKnockoutPage;
public class CompRelationsWizard extends Wizard {
BioPEPAModel model;
private ExportPage exportPage;
private ReactionKnockoutPage reactionKnockoutPage;
public CompRelationsWizard(BioPEPAModel model) {
if(model == null)
throw new NullPointerException("Error; model does not exist.");
this.model = model;
setHelpAvailable(false);
setWindowTitle("Infer invariants for Bio-PEPA");
}
private class ExportPage extends WizardPage {
protected ExportPage(String pageName) {
super(pageName);
this.setTitle("Infer Component Relations");
this.setDescription("Infer the relations between components in the model");
}
private Button stateInvariantsCheck;
private Button activityInvariantsCheck;
// private Button uncoveredComponentsCheck;
public void createControl(Composite parent) {
// int textStyle = SWT.RIGHT | SWT.BORDER;
int labelStyle = SWT.SINGLE | SWT.LEFT;
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout());
setControl(composite);
/* Just a small label to say what to do */
Label tmpLabel = new Label(composite, labelStyle);
String labelText = "Inference of invariants, you should have\n" +
" the 'Invariants' view open; if not go to:\n " +
"Window -> Show View -> Other -> Analysis -> Invariants";
tmpLabel.setText(labelText);
tmpLabel.setLayoutData(createDefaultGridData());
stateInvariantsCheck = new Button (composite, SWT.CHECK);
stateInvariantsCheck.setText("Infer State Invariants");
stateInvariantsCheck.setSelection(true);
stateInvariantsCheck.addListener(SWT.Selection, checkBoxListener);
activityInvariantsCheck = new Button (composite, SWT.CHECK);
activityInvariantsCheck.setText("Infer Activity Invariants");
activityInvariantsCheck.setSelection(true);
activityInvariantsCheck.addListener(SWT.Selection, checkBoxListener);
}
/*
private ModifyListener modifyListener = new ModifyListener (){
public void modifyText(ModifyEvent arg0) {
validate ();
}
};
*/
private Listener checkBoxListener = new Listener() {
public void handleEvent(Event event) {
validate();
}
};
private void validate() {
this.setPageComplete(true);
this.setErrorMessage(null);
if (!stateInvariantsCheck.getSelection()
&& !activityInvariantsCheck.getSelection()){
this.setErrorMessage("Must infer at least one kind of invariant");
this.setPageComplete(false);
}
}
private GridData createDefaultGridData() {
/* ...with grabbing horizontal space */
return new GridData(SWT.FILL, SWT.CENTER, true, false);
}
}
public void addPages (){
exportPage = new ExportPage("Infer component relations with the model");
addPage (exportPage);
LineStringBuilder sb = new LineStringBuilder();
sb.appendLine("De-select each reaction you wish to be ignored");
sb.appendLine("for the purposes of component relation inference");
reactionKnockoutPage = new ReactionKnockoutPage(model) ;
reactionKnockoutPage.setHeaderHelp(sb.toString());
reactionKnockoutPage.setDefaultSelection(true);
addPage (reactionKnockoutPage) ;
}
//
// helpersMap = new CompRelMap ();
// hindersMap = new CompRelMap ();
//
// // Set up the initial maps
// for (SBAReaction reaction : reactions){
// String reactionName = reaction.getName();
// HashSet<String> helpeeSet = new HashSet<String>();
// HashSet<String> hinderedSet = new HashSet<String>();
// for (SBAReaction helpee : reactions){
// if (!helpee.getName().equals(reaction.getName())){
// if (reactionHelps(reaction, helpee)){
// helpeeSet.add(helpee.getName());
// }
// if (reactionHinders(reaction, helpee)){
// hinderedSet.add(helpee.getName());
// }
// }
// }
// helpersMap.put(reactionName, helpeeSet);
// hindersMap.put(reactionName, hinderedSet);
// }
//
// // Now we iterate through the maps for a limited number
// // of iterations
// int limit = 100;
// boolean changed = true;
// while (changed && limit-- > 0){
// changed = false;
// for (SBAReaction reaction : reactions){
// String reactionName = reaction.getName();
// HashSet<String> reactionHelps = helpersMap.get(reactionName);
// HashSet<String> reactionHinders = hindersMap.get(reactionName);
//
// // We cannot add directly to the 'newHelp' as we are iterating
// // through it as we will get a concurent modification exception.
// HashSet<String> newHelps = new HashSet<String>();
// HashSet<String> newHinders = new HashSet<String>();
//
// // For each helped reaction we work out the new set of
// // indirectly helped/hindered reactions
// for (String helped : reactionHelps){
// // If 'reaction' helps 'helped' and 'helped' helps
// // some reaction 'helpedByHelped' then 'reaction'
// // indirectly helps 'helpedByHelped'
// for (String helpedByHelped : helpersMap.get(helped)){
// if (/*!helpedByHelped.equals(reactionName) && */
// !reactionHelps.contains(helpedByHelped)){
// changed = true;
// newHelps.add(helpedByHelped);
// }
// }
// // Similarly if 'reaction' helps 'helped' and
// // 'helped' hinders 'hinderedByHelped' then indirectly
// // 'reaction' hinders 'hinderedByHelped'
// for (String hinderedByHelped : hindersMap.get(helped)){
// if (/* !hinderedByHelped.equals(reactionName) && */
// !reactionHinders.contains(hinderedByHelped)){
// changed = true;
// newHinders.add(hinderedByHelped);
// }
// }
// }
//
// // Similarly for each hindered reaction we work out the
// // new set of reactions which are hindered/helped as indirectly
// for (String hindered : reactionHinders){
// // If 'reaction' hinders 'hindered' and 'hindered'
// // helps 'helpedByHindered' then 'reaction' indirectly
// // hinders 'helpedByHindered'
// for (String helpedByHindered : helpersMap.get(hindered)){
// if (!helpedByHindered.equals(reactionName) &&
// !reactionHinders.contains(helpedByHindered)){
// changed = true;
// newHinders.add(helpedByHindered);
// }
// }
// // Similarly if 'reaction' hinders 'hindered' and
// // 'hindered' hinders 'hinderedByHindered' then indirectly
// // 'reaction' helps 'hinderedByHindered'
// // sort of double negative making a positive
// for (String hinderedByHindered : hindersMap.get(hindered)){
// if (!hinderedByHindered.equals(reactionName) &&
// !reactionHelps.contains(hinderedByHindered)){
// changed = true;
// newHelps.add(hinderedByHindered);
// }
// }
// }
//
// // Finally for this reaction add in all the new helps and
// // the new hinders
// reactionHelps.addAll(newHelps);
// reactionHinders.addAll(newHinders);
// }
// }
// if (limit <= 0) {
// System.out.println ("Limit iterations reached");
// }
//
// /*
// * Having worked out all the helps and hinders for each reaction
// * we now turn our attention to components we now calculate for
// * each reaction the set of components which it either helps or hinders.
// */
// for (SBAReaction reaction : reactions){
// String reactionName = reaction.getName();
// HashSet<String> reactionHelps = helpersMap.get(reactionName);
// HashSet<String> reactionHinders = hindersMap.get(reactionName);
//
// // For each reaction if it is helped by the current reaction 'reaction'
// // then all of the products (which are actually produced) are helped
// // by the current reaction 'reaction'
// // (Of course 'reaction' also helps all its own products)
// for (SBAReaction helpedReaction : reactions){
// String helpedName = helpedReaction.getName();
// if (reactionHelps.contains(helpedName) ||
// reactionName.equals(helpedName)){
// for (SBAComponentBehaviour product : helpedReaction.getProducts()){
// if (reactionProduces(helpedReaction, product)){
// reactionHelps.add(product.getName());
// }
// }
// } // end of if
// } // end of for
// // Similarly for the reaction's hindered, if a reaction is hindered
// // by the current reaction 'reaction' and it produces a given component
// // then 'reaction' hinders that component.
// // (Question: should 'reaction' hinder all its own reactants
// // (if they are consumed)?)
// for (SBAReaction hinderedReaction : reactions){
// String hinderedName = hinderedReaction.getName();
// if (reactionHinders.contains(hinderedName)){
// for (SBAComponentBehaviour product : hinderedReaction.getProducts()){
// if (reactionProduces(hinderedReaction, product)){
// reactionHinders.add(product.getName());
// }
// }
// } // end of if
// } // end for
// } // end of for (SBAReaction ..)
//
// /*
// * This has given us a mapping from reactions to components but what
// * we seek is a mapping from components to components.
// */
// // Unfortunately this is unusable, because of similar problems to
// // the initial component-component analysis. For now we are happy
// // with reaction-reaction and reaction-component mappings.
// /*
// for (ComponentNode comp : species) {
// String compName = comp.getName();
// HashSet<String> compHelps = new HashSet<String>();
// HashSet<String> compHinders = new HashSet<String>();
//
// for (SBAReaction reaction : reactions){
// if (rateAffected(reaction, compName)){
// String reactionName = reaction.getName();
// HashSet<String> reactionHelps = helpersMap.get(reactionName);
// HashSet<String> reactionHinders = hindersMap.get(reactionName);
//
// compHelps.add(reactionName);
// compHelps.addAll(reactionHelps);
// compHinders.addAll(reactionHinders);
// }
// } // end of for reaction : reactions
// helpersMap.put(compName, compHelps);
// hindersMap.put(compName, compHinders);
// } // end for comp : species
// */
// }
// }
@Override
public boolean performFinish() {
ComponentRelationsInferer inferer = new ComponentRelationsInferer(model.getSBAModel(),
reactionKnockoutPage.getSelectedReactions());
CompRelationsJob crjob = new CompRelationsJob("Component Relations Inference");
crjob.setCompRelationsInferer(inferer);
crjob.schedule();
return true;
}
private class CompRelationsJob extends Job {
public CompRelationsJob(String name) {
super(name);
}
private ComponentRelationsInferer inferer;
public void setCompRelationsInferer(ComponentRelationsInferer inferer){
this.inferer = inferer;
}
@Override
protected IStatus run(IProgressMonitor monitor) {
inferer.computeComponentRelations();
Runnable runnable = new Runnable() {
public void run() {
// String outputString = inferer.getOutputString();
// System.out.println(outputString);
BioPEPACompRelationsView invview =
BioPEPACompRelationsView.getDefault();
invview.setRelationsTree(inferer.getRelationsTree());
invview.refreshTree();
}
};
Display.getDefault().syncExec(runnable);
return Status.OK_STATUS;
}
}
public IResource getUnderlyingResource() {
return model.getUnderlyingResource();
}
}