Virtual detectors and batch packs This macro makes a demo filter root file


{
    //Let us create a "virtual detector"

    //First, we create dummy root files
    //For a real detector, they can be derived e.g.
    //from a full GEANT simulation and re-opened
    //here from a ROOT file

    //Our dummy detector should have an acceptance
    //for electrons in forward directions
    //between 18 - 95 degrees. The efficiency
    //of electrons should be 80%,
    //in a momentum range below 100 MeV only 50,
    //and below 50 MeV no acceptance

    //Protons should have a flat acceptance of 90%
    //using a forward detector (a plane) in 
    //a distance of 2m downstream with 3x3m

    //Other particles are rejected

    //Remember, this is NOT HADES

    //This filter should come in 2 modi operandi:
    //1. For inclusive measurements (e+e-)
    //2. For exclusive measurements (ppe+e-)

    
    //Make a pseudo-Monto-Carlo simulation:
    //Generate particles between: 
    //mom = 0 ... 3000 MeV   (x)
    //cos(theta) = -1 ... 1  (y)
    //phi = 0 ... 360 deg    (z)

    //On purpose, we do not use the Pluto convention
    //to demonstrate the convertion inside the command list

    //In addition, we apply a 1% momentum resolution...
    //...just fixed, to keep it easy. Of course it is possible
    //to use matrices as well
    //This is controlled via "filter_smear_factor"

    //Create the efficiency matrices:
    TH3F *gen = 
	new TH3F ("gen", "Generated events", 30, 0, 1500, 20, -1, 1, 20, 0, 360);
    TH3F *eff_elec = 
	new TH3F ("eff_elec", "Efficiency matrix electrons", 30, 0, 1500, 20, -1, 1, 20, 0, 360);    
    TH3F *eff_protons = 
	new TH3F ("eff_protons", "Efficiency matrix protons", 30, 0, 1500, 20, -1, 1, 20, 0, 360);

    //Start the Monte-Carlo
    int nev = 1000000;
    for (int i=0; i<nev; i++) {
	Double_t mom = PUtils::sampleFlat()*3000;
	Double_t costheta = PUtils::sampleFlat()*2 - 1;
	Double_t phi = PUtils::sampleFlat()*360;
	
	gen->Fill(mom, costheta, phi);

	Double_t theta = acos(costheta)*180/TMath::Pi();

	//electrons
	if ((theta > 18) && (theta < 95)) {
	    Double_t rnd = PUtils::sampleFlat();
	    if ((mom > 100) && (rnd < 0.8))
		eff_elec->Fill(mom, costheta, phi);
	    else if ((mom > 50) && (rnd < 0.5))
		eff_elec->Fill(mom, costheta, phi);	    
	}

	//protons
	Double_t x = tan(acos(costheta)) * 2 * cos(phi*TMath::Pi()/180);
	Double_t y = tan(acos(costheta)) * 2 * sin(phi*TMath::Pi()/180);
	
	if ((fabs(x) < 1.5) && (fabs(y) < 1.5)) {
	    Double_t rnd = PUtils::sampleFlat();
	    if (rnd < 0.90)
		eff_protons->Fill(mom,costheta,phi);
	}
    }

    eff_elec->Divide(gen);
    eff_protons->Divide(gen);


    //Now we create the filter file
    TFile *f = new TFile("pluto_demo_filter.root", "RECREATE");

    //Commands with the keyword "_main" are called when the filter is attached
    PCommandList *p = new PCommandList("_main", "echo **** This is our demo filter, v1");
    
    //A little bit of hello information:
    p->AddCommand("echo ********************************************************************************");
    p->AddCommand("echo Usage:      This filter works in 2 modi:");
    p->AddCommand("echo Usage:      1.) inclusive:");
    p->AddCommand("echo Usage:          default");
    p->AddCommand("echo Usage:      2.) exclusive measurement:");
    p->AddCommand("echo Usage:          Add in your macro after filter attachment:");
    p->AddCommand("echo Usage:          makeDistributionManager()->Startup(\"_filter_exclusive=1\");");
    p->AddCommand("echo ********************************************************************************");
    p->AddCommand("echo Usage:      Momentum smearing is applied, you can change:");
    p->AddCommand("echo Usage:          makeDistributionManager()->Startup(\"_filter_smear_factor=....\");");
    p->AddCommand("echo ********************************************************************************");
    p->AddCommand("echo Debug mode:     makeDistributionManager()->Startup(\"_filter_debug=1\");");
    p->AddCommand("echo ********************************************************************************");
    //Generate variables
    p->AddCommand("_filter_debug=0");
    p->AddCommand("_filter_exclusive=0");
    p->AddCommand("_filter_smear_factor=1.");

    p->Write();

    //Commands with the keyword "_startup" are called when event loop is started
    //Here, it is used to add another warning
    PCommandList *s = 
	new PCommandList("_startup", 
			 "echo ********************************************************************************");
    
    s->AddCommand("echo This event loop uses the demo filter ");
    s->AddCommand("echo ********************************************************************************");
    s->Write();

    //Commands with the keyword "_loop" are called within event loop
    //Labels should be unique. Avoid common names
    PCommandList *l = new PCommandList("_loop");

    //The first thing we have to do is to calculate for each particle under test the axes values

    l->AddCommand("if (_filter_debug); echo **** New event called"); //do not forget the ";" after the if-statement
    l->AddCommand("_start: removed=0");                   //labels with colon
    l->AddCommand("_x = [e+]->P() * 1000.; ");  //Conversion of units
    l->AddCommand("_y = [e+]->CosTheta(); ");
    l->AddCommand("_z = (([e+]->Phi()) *180/TMath::Pi()); if (_z<0); _z = _z + 360");
    l->AddCommand(eff_elec,"eff_ep = Eval(); rnd =  sampleFlat(); if (rnd>eff_ep); [e+]->SetInActive(); removed=1");
    l->AddCommand("mom = [e+]->P(); newmom = sampleGaus(mom,0.01*mom*_filter_smear_factor);[e+]->SetMom(newmom)");
    l->AddCommand("if (_filter_debug && removed); echo e+: $_x, $_y, $_z eff: $eff_ep <removed>");
    l->AddCommand("if (_filter_debug && !removed); echo e+: $_x, $_y, $_z eff: $eff_ep");

    l->AddCommand("formore e+; goto _start");  // added 2 separate gotos for e+ and e- following a hint by V. Hejny

    l->AddCommand("_start2: removed=0");  
    l->AddCommand("_x = [e-]->P() * 1000.;");
    l->AddCommand("_y = [e-]->CosTheta(); ");
    l->AddCommand("_z = (([e-]->Phi()) *180/TMath::Pi()); if (_z<0); _z = _z + 360;");
    l->AddCommand(eff_elec,"eff_em = Eval(); rnd = sampleFlat(); if (rnd>eff_em); [e-]->SetInActive(); removed=1");
    l->AddCommand("mom = [e-]->P(); newmom = sampleGaus(mom,0.01*mom*_filter_smear_factor);[e-]->SetMom(newmom)");
    l->AddCommand("if (_filter_debug && removed); echo e-: $_x, $_y, $_z eff: $eff_em <removed>");
    l->AddCommand("if (_filter_debug && !removed); echo e-: $_x, $_y, $_z eff: $eff_em");

    l->AddCommand("formore e-; goto _start2");

    l->AddCommand("if (!_filter_exclusive); goto _end;");

    l->AddCommand("_start_proton_loop: removed=0");

    l->AddCommand("_x = [p]->P() * 1000.; ");
    l->AddCommand("_y = [p]->CosTheta(); ");
    l->AddCommand("_z = (([p]->Phi()) *180/TMath::Pi()); if (_z<0); _z = _z + 360;");
    //l->AddCommand("[p]->Print();");
    l->AddCommand(eff_protons,"eff_p = Eval(); rnd = sampleFlat(); if (rnd>eff_p); [p]->SetInActive(); removed=1");
    l->AddCommand("mom = [p]->P(); newmom = sampleGaus(mom,0.01*mom*_filter_smear_factor);[p]->SetMom(newmom)");
    // l->AddCommand("echo $mom , $newmom");
    //l->AddCommand("[p]->Print();");
    l->AddCommand("if (_filter_debug && removed); echo p: $_x, $_y, $_z eff: $eff_p <removed>");
    l->AddCommand("if (_filter_debug && !removed); echo p: $_x, $_y, $_z eff: $eff_p");

    l->AddCommand("formore p; goto _start_proton_loop");

    l->AddCommand("_end:");
    
    l->Write();
    eff_elec->Write();
    eff_protons->Write();

    f->Write();
}
 make_demo_pfilter.C:1
 make_demo_pfilter.C:2
 make_demo_pfilter.C:3
 make_demo_pfilter.C:4
 make_demo_pfilter.C:5
 make_demo_pfilter.C:6
 make_demo_pfilter.C:7
 make_demo_pfilter.C:8
 make_demo_pfilter.C:9
 make_demo_pfilter.C:10
 make_demo_pfilter.C:11
 make_demo_pfilter.C:12
 make_demo_pfilter.C:13
 make_demo_pfilter.C:14
 make_demo_pfilter.C:15
 make_demo_pfilter.C:16
 make_demo_pfilter.C:17
 make_demo_pfilter.C:18
 make_demo_pfilter.C:19
 make_demo_pfilter.C:20
 make_demo_pfilter.C:21
 make_demo_pfilter.C:22
 make_demo_pfilter.C:23
 make_demo_pfilter.C:24
 make_demo_pfilter.C:25
 make_demo_pfilter.C:26
 make_demo_pfilter.C:27
 make_demo_pfilter.C:28
 make_demo_pfilter.C:29
 make_demo_pfilter.C:30
 make_demo_pfilter.C:31
 make_demo_pfilter.C:32
 make_demo_pfilter.C:33
 make_demo_pfilter.C:34
 make_demo_pfilter.C:35
 make_demo_pfilter.C:36
 make_demo_pfilter.C:37
 make_demo_pfilter.C:38
 make_demo_pfilter.C:39
 make_demo_pfilter.C:40
 make_demo_pfilter.C:41
 make_demo_pfilter.C:42
 make_demo_pfilter.C:43
 make_demo_pfilter.C:44
 make_demo_pfilter.C:45
 make_demo_pfilter.C:46
 make_demo_pfilter.C:47
 make_demo_pfilter.C:48
 make_demo_pfilter.C:49
 make_demo_pfilter.C:50
 make_demo_pfilter.C:51
 make_demo_pfilter.C:52
 make_demo_pfilter.C:53
 make_demo_pfilter.C:54
 make_demo_pfilter.C:55
 make_demo_pfilter.C:56
 make_demo_pfilter.C:57
 make_demo_pfilter.C:58
 make_demo_pfilter.C:59
 make_demo_pfilter.C:60
 make_demo_pfilter.C:61
 make_demo_pfilter.C:62
 make_demo_pfilter.C:63
 make_demo_pfilter.C:64
 make_demo_pfilter.C:65
 make_demo_pfilter.C:66
 make_demo_pfilter.C:67
 make_demo_pfilter.C:68
 make_demo_pfilter.C:69
 make_demo_pfilter.C:70
 make_demo_pfilter.C:71
 make_demo_pfilter.C:72
 make_demo_pfilter.C:73
 make_demo_pfilter.C:74
 make_demo_pfilter.C:75
 make_demo_pfilter.C:76
 make_demo_pfilter.C:77
 make_demo_pfilter.C:78
 make_demo_pfilter.C:79
 make_demo_pfilter.C:80
 make_demo_pfilter.C:81
 make_demo_pfilter.C:82
 make_demo_pfilter.C:83
 make_demo_pfilter.C:84
 make_demo_pfilter.C:85
 make_demo_pfilter.C:86
 make_demo_pfilter.C:87
 make_demo_pfilter.C:88
 make_demo_pfilter.C:89
 make_demo_pfilter.C:90
 make_demo_pfilter.C:91
 make_demo_pfilter.C:92
 make_demo_pfilter.C:93
 make_demo_pfilter.C:94
 make_demo_pfilter.C:95
 make_demo_pfilter.C:96
 make_demo_pfilter.C:97
 make_demo_pfilter.C:98
 make_demo_pfilter.C:99
 make_demo_pfilter.C:100
 make_demo_pfilter.C:101
 make_demo_pfilter.C:102
 make_demo_pfilter.C:103
 make_demo_pfilter.C:104
 make_demo_pfilter.C:105
 make_demo_pfilter.C:106
 make_demo_pfilter.C:107
 make_demo_pfilter.C:108
 make_demo_pfilter.C:109
 make_demo_pfilter.C:110
 make_demo_pfilter.C:111
 make_demo_pfilter.C:112
 make_demo_pfilter.C:113
 make_demo_pfilter.C:114
 make_demo_pfilter.C:115
 make_demo_pfilter.C:116
 make_demo_pfilter.C:117
 make_demo_pfilter.C:118
 make_demo_pfilter.C:119
 make_demo_pfilter.C:120
 make_demo_pfilter.C:121
 make_demo_pfilter.C:122
 make_demo_pfilter.C:123
 make_demo_pfilter.C:124
 make_demo_pfilter.C:125
 make_demo_pfilter.C:126
 make_demo_pfilter.C:127
 make_demo_pfilter.C:128
 make_demo_pfilter.C:129
 make_demo_pfilter.C:130
 make_demo_pfilter.C:131
 make_demo_pfilter.C:132
 make_demo_pfilter.C:133
 make_demo_pfilter.C:134
 make_demo_pfilter.C:135
 make_demo_pfilter.C:136
 make_demo_pfilter.C:137
 make_demo_pfilter.C:138
 make_demo_pfilter.C:139
 make_demo_pfilter.C:140
 make_demo_pfilter.C:141
 make_demo_pfilter.C:142
 make_demo_pfilter.C:143
 make_demo_pfilter.C:144
 make_demo_pfilter.C:145
 make_demo_pfilter.C:146
 make_demo_pfilter.C:147
 make_demo_pfilter.C:148
 make_demo_pfilter.C:149
 make_demo_pfilter.C:150
 make_demo_pfilter.C:151
 make_demo_pfilter.C:152
 make_demo_pfilter.C:153
 make_demo_pfilter.C:154
 make_demo_pfilter.C:155
 make_demo_pfilter.C:156
 make_demo_pfilter.C:157
 make_demo_pfilter.C:158
 make_demo_pfilter.C:159
 make_demo_pfilter.C:160
 make_demo_pfilter.C:161
 make_demo_pfilter.C:162
 make_demo_pfilter.C:163
 make_demo_pfilter.C:164
 make_demo_pfilter.C:165
 make_demo_pfilter.C:166
 make_demo_pfilter.C:167
 make_demo_pfilter.C:168
 make_demo_pfilter.C:169
 make_demo_pfilter.C:170
 make_demo_pfilter.C:171
 make_demo_pfilter.C:172
 make_demo_pfilter.C:173
 make_demo_pfilter.C:174
 make_demo_pfilter.C:175
 make_demo_pfilter.C:176
 make_demo_pfilter.C:177
 make_demo_pfilter.C:178