How to pass parameters to TSelector in Proof

I notice that in Proof, I can only specify the name of my TSelector in the gProof->Process command and I am not allowed to pass a pointer to the TSelector as when processing a chain.

gProof->Process(chain, “PhiRhoSelector”);

How to I pass parameters to my TSelector constructor? Or any other way other than having it read a file, which seems totally awkward.

Thanks in advance for your help,

Alex

Dear Alex,

Currently it is not possible to pass arguments as you do for macros.

What you can do is to put you arguments into an object (for example, as a TObjString string to be parsed inside, or your own simple argument class), add it to the input list via TProof::AddInput(TObject *myargs), and fetch it inside the selector from the fInput list.

Hope it helps,

Gerri

Hi Gerri,

Thanks for the info, but I still need another piece of information. I my root session, I have the following lines:

root [20] TObjString* jobname = new TObjString(“DDBar”);
root [21] TObjString* cut_def_file = new TObjString("/home/hep/smith/DTagVV/Ph$
root [22] TObjString* require_MCTag = new TObjString(“false”);
root [23] TObjString* require_NO_MCTag = new TObjString(“true”);
root [24] TObjString* require_DTag = new TObjString(“false”);
root [25] TObjString* fill_hists = new TObjString(“true”);
root [26] TObjString* fully_tagged_only = new TObjString(“false”);
root [27] TObjString* nononres = new TObjString(“true”);
root [28]
root [28] gProof->AddInput(jobname);
root [29] gProof->AddInput(cut_def_file);
root [30] gProof->AddInput(require_MCTag);
root [31] gProof->AddInput(require_NO_MCTag);
root [32] gProof->AddInput(require_DTag);
root [33] gProof->AddInput(fill_hists);
root [34] gProof->AddInput(fully_tagged_only);
root [35] gProof->AddInput(nononres);
root [36] gProof->Process(chain, “PhiRhoSelector”);

In my TSelector, in the Init() routine (I tried in the constructor and Begin() as well) I attempt to fetch the stuff in fInput (see below), but get nothing back. It is unclear to me how to set the values of fInput. Apparently, it does not happen automatically. I see the
declaration

virtual void SetInputList(TList *input) {fInput = input;}

in the .h file that comes from TSelector, but I don’t know WHERE or HOW to call this from my main calling script, since my TSelector is not even defined at that point.

Thanks,

Alex

TIter next_object(fInput);
TObject *this_object = 0;
TObjString *objstr = 0;
while ((this_object = next_object())) {

objstr =  (TObjString*)this_object;
cout << "Found object = " << this_object->GetName() << endl;


if (!strcmp(this_object->GetName(),"jobname")) {
  objstr =  (TObjString*)this_object;
  Name = objstr->GetString();
  cout << "Found jobname = " << Name << endl;}
  
if (!strcmp(this_object->GetName(),"cut_def_file")) {
  objstr =  (TObjString*)this_object;
  cut_def_file = objstr->GetString();
  cout << "Found cut_def_file = " << cut_def_file << endl;}
  
if (!strcmp(this_object->GetName(),"require_MCTag")) {
  objstr =  (TObjString*)this_object;
  require_MCTag = objstr->GetString().Contains("true");
  cout << "Found require_MCTag = " << require_MCTag << endl;}
  
if (!strcmp(this_object->GetName(),"require_NO_MCTag")) {
  objstr =  (TObjString*)this_object;
  require_NO_MCTag = objstr->GetString().Contains("true");
  cout << "Found require_NO_MCTag = " << require_NO_MCTag << endl;}
  
if (!strcmp(this_object->GetName(),"require_DTag")) {
  objstr =  (TObjString*)this_object;
  require_DTag = objstr->GetString().Contains("true");
  cout << "Found require_DTag = " << require_DTag << endl;}
  
if (!strcmp(this_object->GetName(),"fill_hists")) {
  objstr =  (TObjString*)this_object;
  fill_hists = objstr->GetString().Contains("true");
  cout << "Found fill_hists = " << fill_hists << endl;}
  
if (!strcmp(this_object->GetName(),"fully_tagged_only")) {
  objstr =  (TObjString*)this_object;
  fully_tagged_only = objstr->GetString().Contains("true");
  cout << "Found fully_tagged_only = " << fully_tagged_only << endl;}
  
if (!strcmp(this_object->GetName(),"nononres")) {
  objstr =  (TObjString*)this_object;
  nononres = objstr->GetString().Contains("true");
  cout << "Found nononres = " << nononres << endl;}

}

Dear Alex,

In the way you did it, this_object->GetName() returns the content of the argument, not its name, so it is normal that the second part of your checks does not do what you want.

However, I would have expected this

 cout << "Found object = " << this_object->GetName() << endl; 

to print the list of your variable content:

Found object = DDbar
Found object = cut_def_file
...

so I do not understand when you wrote that nothing came out.

Anyhow, in your case, I would suggest to use TNamed objects like this

gProof->AddInput(new TNamed("jobname","DDBar"));
gProof->AddInput(new TNamed("cut_def_file", "/home/hep/smith/DTagVV/Ph"));
gProof->AddInput(new TNamed("require_NO_MCTag");
gProof->AddInput(new TNamed("fill_hists");
gProof->AddInput(new TNamed("nononres");

Inside the selector, for example in Begin(), you can access the information like this


// jobname
TNamed *n = dynamic_cast<TNamed *>(fInput->FindObject("jobname"));
TString jobname = n ? n->GetTitle() : "";
Info("Begin","args: jobname: %s", jobname.Data());

// cut_def_file
n = dynamic_cast<TNamed *>(fInput->FindObject("cut_def_file"));
TString cut_def_file = n ? n->GetTitle() : "";
Info("Begin","args: cut_def_file: %s", cut_def_file.Data());

// Booleans
Bool_t require_MCTag = fInput->FindObject("require_MCTag") ? kTRUE : kFALSE;
Bool_t require_NO_MCTag = fInput->FindObject("require_NO_MCTag") ? kTRUE : kFALSE;
Bool_t require_DTag = fInput->FindObject("require_DTag") ? kTRUE : kFALSE;
Bool_t fill_hists = fInput->FindObject("fill_hists") ? kTRUE : kFALSE;
Bool_t fully_tagged_only = fInput->FindObject("fully_tagged_only") ? kTRUE : kFALSE;
Bool_t nononres = fInput->FindObject("nononres") ? kTRUE : kFALSE;

If you have more complicated structures you may consider defining a dedicated argument class. The class needs to be uploaded to the slaves. I can send en example, if you wish.

Hope it helps.

Gerri

Dear all,

I am currently facing this issue.

If you have more complicated structures you may consider defining a dedicated argument class. The class needs to be uploaded to the slaves. I can send en example, if you wish.

Could this example be provided?

Best,
Ana.

Hi Ana,

Attached is an example using standard maps as generic parameter containers.
After unpacking, you should run like this:

root [] .L MyParameters.h+

root [] .L testMyParms.C+
root [] testMyParms(master)

Let me know,
Gerri
params.tar.gz (2.47 KB)

1 Like

Thanks a lot,

Ana.

Hi everyone,

I have the same question after more than 7 Years. Is there with ROOT6 any new methods to pass parameters into the constructor of MySelector?

I defined MySelector Class and need to give a filename to some of the output based on the the file being processed by the selector. (I planned to send an argument using the Constructor but it’s not working). I was using fChain->Process("MySelector.C+(929)") but it just ignores the parameter.

Thank you,
A.

For the record,

Solved using TParameter.

In the Script:


   Int_t RunNumber = 666
   TProof *fProof = TProof::Open("workers=4");
   fProof->SetProgressDialog(false);
+  // Send a TParameter<Int_t> Object to MySelector
+  // Needed because of fProof use
+  fProof->SetParameter("RunNumber",RunNumber);

Within MySelector Class

+void MySelector::Begin(TTree *tree) {
+  
+  // When using PROOF, Begin() is called on the client only.
+  if (fInput->FindObject("RunNumber")) {
+    TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(fInput->FindObject("RunNumber"));
+    RunNumber = p->GetVal();
+  }
+  
 }

YMMV
A.

1 Like

Hi @ganis,

I am not able to run your example with ROOT 6.10/04 and PROOF-Lite, as I get the error

Error in <Streamer>: Cannot stream interpreted class.
Error in <Streamer>: Cannot stream interpreted class.
cling::DynamicLibraryManager::loadLibrary(): ProofParms_C.so: undefined symbol: _ZTI12MyParameters
/usr/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
ProofParms_C_ACLiC_dict.o: In function `ProofParms::Begin(TTree*)':
ProofParms_C_ACLiC_dict.cxx:(.text+0xf3): undefined reference to `typeinfo for MyParameters'
ProofParms_C_ACLiC_dict.o: In function `ProofParms::SlaveBegin(TTree*)':
ProofParms_C_ACLiC_dict.cxx:(.text+0x1c5): undefined reference to `typeinfo for MyParameters'
collect2: error: ld returned 1 exit status
Error in <TSelector::GetSelector>: The file ProofParms.C+ does not define a class named ProofParms.
Error in <TProofLite::CopyMacroToCache>: could not create a selector from ProofParms.C+

Do you have any advice? I need to pass a std::map to a TSelector’s input, and I was planning to do that by defining a custom class inheriting from TNamed.

Dear rene,
How do you run the macro?
Is this issuing

   root[] .x testMyParms.C("lite://")

in a ROOT shell?
G Ganis

yes, that command does not work