Index: trunk/SophyaPI/PIext/pawexecut.cc
===================================================================
--- trunk/SophyaPI/PIext/pawexecut.cc	(revision 1035)
+++ trunk/SophyaPI/PIext/pawexecut.cc	(revision 1054)
@@ -6,5 +6,4 @@
 
 #include "strutil.h"
-#include "histos.h"
 #include "histos.h"
 #include "histos2.h"
@@ -76,13 +75,20 @@
 
 kw = "h/cadd";
-usage = "Add a constant to an histogramme";
+usage = "Add a constant to an histogram";
 usage += "\n h/cadd val";
-usage += "\n  Related commands: h/cmult";  
+usage += "\n  Related commands: h/cmult h/oper";  
 piac->RegisterCommand(kw,usage,this,hgrp);
 
 kw = "h/cmult";
-usage = "Multiply an histogramme by a constant";
+usage = "Multiply an histogram by a constant";
 usage += "\n h/cmult val";
-usage += "\n  Related commands: h/cadd";  
+usage += "\n  Related commands: h/cadd h/oper";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/oper";
+usage = "Operation on histograms";
+usage += "\n h/oper @ h1 h2 hres";
+usage += "\n        hres = h1 @ h2   with @ = (+,-,*,/)";
+usage += "\n  Related commands: h/cadd h/cmult";  
 piac->RegisterCommand(kw,usage,this,hgrp);
 
@@ -125,4 +131,6 @@
 } else if(kw == "h/cmult") {
   h_cmult(tokens); return(0);
+} else if(kw == "h/oper") {
+  h_oper(tokens); return(0);
 } else if(kw == "h/plot/2d") {
   h_plot_2d(tokens); return(0);
@@ -359,4 +367,137 @@
 else cout<<"PAWExecutor::h_cmult Error: "<<tokens[0]
          <<" not an Histo/HProf/Histo2D"<<endl;
+}
+
+/* methode */
+void PAWExecutor::h_oper(vector<string>& tokens)
+// Equivalent h/oper/add sub,mul,div de paw
+// Operation entre 2 histogrammes
+// h/oper @ h1 h2 hres
+// hres = h1 @ h2    with @ = (+,-,*,/)
+{
+cout<<"*** WARNING *** Not Tested, Do Not Use (cmv) !"<<endl;
+cerr<<"*** WARNING *** Not Tested, Do Not Use (cmv) !"<<endl;
+if(tokens.size()<4)
+  {cout<<"Usage: n/oper @ h1 h2 hres with @=(+,-,*,/)"<<endl;
+   return;}
+
+// Decode arguments
+const char * oper = tokens[0].c_str();
+if( oper[0]!='+' && oper[0]!='-' && oper[0]!='*' && oper[0]!='/' )
+  {cout<<"PAWExecutor::h_oper Error: unknow operation "<<oper<<endl;
+  return;}
+string h1name = tokens[1];
+string h2name = tokens[2];
+string h3name = tokens[3];
+
+// Get objects
+NamedObjMgr omg;
+AnyDataObj* mobjh1 = omg.GetObj(h1name);
+AnyDataObj* mobjh2 = omg.GetObj(h2name);
+if( mobjh1==NULL || mobjh2==NULL )
+  {cout<<"PAWExecutor::h_oper Error: unknow object(s) "<<h1name<<" or "<<h2name<<endl;
+  return;}
+AnyDataObj* mobjh3 = omg.GetObj(h3name);
+
+// Operations on HProf, only + is working
+if( dynamic_cast<HProf*>(mobjh1) != NULL ) {
+  if( oper[0]!='+' )
+    { cout<<"PAWExecutor::h_oper Error: operation "<<oper
+          <<" not implemented for HProf"<<endl; return;}
+  if( dynamic_cast<HProf*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2 "
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  HProf* h1 =(HProf*) mobjh1;
+  HProf* h2 =(HProf*) mobjh2;
+  if( h1->NBins() != h2->NBins() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NBins()<<" "<<h2->NBins()<<endl; return;}
+  HProf* h3 = NULL;
+  if( mobjh3 == NULL ) {  // l'objet n'existe pas, on le cree
+    h3 = new HProf(*h1); h3->Zero(); omg.AddObj(h3,h3name);
+  } else {                // l'objet existe
+    h3 = dynamic_cast<HProf*>(mobjh3);
+    if(h3 == NULL)  // ce n'est pas un HProf
+      {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3 "
+           <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl;
+      return;}
+    if(h1->NBins() != h3->NBins())
+      {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+           <<h1->NBins()<<" "<<h3->NBins()<<endl; return;}
+    h3->Zero();
+    *h3 = *h1 + *h2;
+    h3->UpdateHisto();
+  }
+
+// Operations on Histo
+} else if( dynamic_cast<Histo*>(mobjh1) != NULL ) {
+  if( dynamic_cast<Histo*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2 "
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  Histo* h1 =(Histo*) mobjh1;
+  Histo* h2 =(Histo*) mobjh2;
+  if( h1->NBins() != h2->NBins() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NBins()<<" "<<h2->NBins()<<endl; return;}
+  Histo* h3 = NULL;
+  if( mobjh3 == NULL ) {  // l'objet n'existe pas, on le cree
+    h3 = new Histo(*h1); h3->Zero(); omg.AddObj(h3,h3name);
+  } else {                // l'objet existe
+    h3 = dynamic_cast<Histo*>(mobjh3);
+    if(h3 == NULL)  // ce n'est pas un Histo
+      {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3 "
+           <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl;
+      return;}
+    if(h1->NBins() != h3->NBins())
+      {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+           <<h1->NBins()<<" "<<h3->NBins()<<endl; return;}
+    h3->Zero();
+    if( oper[0]=='+')      *h3 = *h1 + *h2;
+    else if( oper[0]=='-') *h3 = *h1 - *h2;
+    else if( oper[0]=='*') *h3 = *h1 * *h2;
+    else if( oper[0]=='/') *h3 = *h1 / *h2;
+  }
+
+// Operations on Histo2D
+} else if( dynamic_cast<Histo2D*>(mobjh1) != NULL ) {
+  if( dynamic_cast<Histo2D*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2 "
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  Histo2D* h1 =(Histo2D*) mobjh1;
+  Histo2D* h2 =(Histo2D*) mobjh2;
+  if( h1->NBinX() != h2->NBinX() || h1->NBinY() != h2->NBinY() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NBinX()<<","<<h1->NBinY()<<"   "
+         <<h2->NBinX()<<","<<h2->NBinY()<<endl; return;}
+  Histo2D* h3 = NULL;
+  if( mobjh3 == NULL ) {  // l'objet n'existe pas, on le cree
+    h3 = new Histo2D(*h1); h3->Zero(); omg.AddObj(h3,h3name);
+  } else {                // l'objet existe
+    h3 = dynamic_cast<Histo2D*>(mobjh3);
+    if(h3 == NULL)  // ce n'est pas un Histo2D
+      {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3 "
+           <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl;
+      return;}
+    if( h1->NBinX() != h3->NBinX() || h1->NBinY() != h3->NBinY() )
+      {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+           <<h1->NBinX()<<","<<h1->NBinY()<<"   "
+           <<h3->NBinX()<<","<<h3->NBinY()<<endl; return;}
+    h3->Zero();
+    if( oper[0]=='+')      *h3 = *h1 + *h2;
+    else if( oper[0]=='-') *h3 = *h1 - *h2;
+    else if( oper[0]=='*') *h3 = *h1 * *h2;
+    else if( oper[0]=='/') *h3 = *h1 / *h2;
+  }
+
+// Doesn't work for other objects
+} else {
+  cout<<"PAWExecutor::h_oper Error: not implemented for "<<typeid(*mobjh1).name()<<endl;
+  return;
+}
+
+return;
 }
 
