#include "PProjector.h"
#include "PChannel.h"
PProjector::PProjector() {
batch_pos = 0;
pid_param = makeDataBase()->GetParamInt("batch_pid");
if (pid_param < 0)
pid_param = makeDataBase()->MakeParamInt("batch_pid", "PID for batch");
link_param = makeDataBase()->GetParamInt("batch_position");
if (link_param < 0)
link_param = makeDataBase()->MakeParamInt("batch_position", "PID position for batch");
batch_particle_param = makeDataBase()->GetParamTObj("batch_particle");
w = makeStaticData()->GetBatchValue("_w");
if (batch_particle_param < 0)
batch_particle_param = makeDataBase()->MakeParamTObj("batch_particle", "PParticle storage for batch");
batch_value_param = makeDataBase()->GetParamDouble("batch_value");
stream_default_pos_param = makeDataBase()->GetParamInt(STREAM_DEFAULT_POS);
if (stream_default_pos_param < 0)
stream_default_pos_param = makeDataBase()->MakeParamInt(STREAM_DEFAULT_POS, "Default position");
stream_max_pos_param = makeDataBase()->GetParamInt(STREAM_MAX_POS);
if (stream_max_pos_param < 0)
stream_max_pos_param = makeDataBase()->MakeParamInt(STREAM_MAX_POS, "Max position in stream");
for (int i=0; i<PROJECTOR_MAX_BATCH; i++) {
hist3[i] = NULL;
hist2[i] = NULL;
hist1[i] = NULL;
fp_out[i] = NULL;
fp_in[i] = NULL;
key_pos_out[i] = 0;
key_pos_in[i] = 0;
}
batch_pos = 0;
force_weight = 1;
current_ascii_file = NULL;
fPriority = PPROJECTOR_PRIORITY;
proj_nr = makeStaticData()->GetBatchValue("_system_embedded_particle_projector");
for (int i=0; i<MAX_NUM_BRANCHES; i++) {
current_size_branches[i] = NULL;
particle_array_branches[i] = NULL;
}
}
PProjector::~PProjector() {
for (int i=0; i<batch_pos; i++)
delete batch[i];
}
Bool_t PProjector::AddCommand(const char *command) {
if (batch_pos == PROJECTOR_MAX_BATCH) {
Error("AddCommand", "PROJECTOR_MAX_BATCH reached");
return kFALSE;
}
batch[batch_pos] = new PBatch();
batch[batch_pos]->SetSizeBranches(size_branches);
batch[batch_pos]->SetKeysBranches(key_branches);
if (current_ascii_file) {
batch[batch_pos]->SetToolObjectTmp(current_ascii_file);
}
batch[batch_pos]->SetPosition(batch_pos, bulk_id);
if (!batch[batch_pos]->AddCommand(PUtils::NewString(command))) {
delete batch[batch_pos];
return kFALSE;
}
key = makeDataBase()->GetEntry("batch_objects");
if (batch[batch_pos]->Status()) {
if (*(proj_nr)) {
Error("AddCommand", "Embedded particle ([+]) used 2 times");
}
*(proj_nr) = bulk_id;
}
batch_pos++;
return kTRUE;
}
Bool_t PProjector::AddHistogram(TH3 *histo, const char *command, Int_t fillflag) {
if (!AddCommand(command)) return kFALSE;
hist3[batch_pos-1] = histo;
key = makeDataBase()->GetEntry("batch_objects");
key_x = makeDataBase()->GetEntry("_x");
key_y = makeDataBase()->GetEntry("_y");
key_z = makeDataBase()->GetEntry("_z");
if (key_x < 0) {
Error ("AddHistogram", "result _x not found");
return kFALSE;
}
if (key_y < 0) {
Error ("AddHistogram", "result _y not found");
return kFALSE;
}
if (key_z < 0) {
Error ("AddHistogram", "result _z not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_x, batch_value_param, &x)) {
Error ("AddHistogram", "Double _x not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_y, batch_value_param, &y)) {
Error ("AddHistogram", "Double _y not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_z, batch_value_param, &z)) {
Error ("AddHistogram", "Double _z not found");
return kFALSE;
}
if (batch[batch_pos-1]->IsReadonly())
fillflag = 0;
batch[batch_pos-1]->SetToolObject(histo);
fFillFlag[batch_pos-1] = fillflag;
return kTRUE;
}
Bool_t PProjector::AddHistogram(TH2 *histo, const char *command, Int_t fillflag) {
if (!AddCommand(command)) return kFALSE;
hist2[batch_pos-1] = histo;
key = makeDataBase()->GetEntry("batch_objects");
key_x = makeDataBase()->GetEntry("_x");
key_y = makeDataBase()->GetEntry("_y");
if (key_x < 0) {
Error ("AddHistogram", "result _x not found");
return kFALSE;
}
if (key_y < 0) {
Error ("AddHistogram", "result _y not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_x, batch_value_param, &x)) {
Error ("AddHistogram", "Double _x not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_y, batch_value_param, &y)) {
Error ("AddHistogram", "Double _y not found");
return kFALSE;
}
if (batch[batch_pos-1]->IsReadonly())
fillflag = 0;
batch[batch_pos-1]->SetToolObject(histo);
fFillFlag[batch_pos-1] = fillflag;
return kTRUE;
}
Bool_t PProjector::AddHistogram(TH1 *histo, const char *command, Int_t fillflag) {
if (!AddCommand(command)) return kFALSE;
hist1[batch_pos-1] = histo;
key = makeDataBase()->GetEntry("batch_objects");
key_x = makeDataBase()->GetEntry("_x");
if (key_x < 0) {
Error ("AddHistogram", "result _x not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_x, batch_value_param, &x)) {
Error ("AddHistogram", "Double _x not found");
return kFALSE;
}
if (batch[batch_pos-1]->IsReadonly())
fillflag = 0;
batch[batch_pos-1]->SetToolObject(histo);
fFillFlag[batch_pos-1] = fillflag;
return kTRUE;
}
Bool_t PProjector::AddTGraph(TGraph *graph, const char *command) {
if (!AddCommand(command)) return kFALSE;
key = makeDataBase()->GetEntry("batch_objects");
key_x = makeDataBase()->GetEntry("_x");
if (key_x < 0) {
Error ("AddTGraph", "result _x not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_x, batch_value_param, &x)) {
Error ("AddTGraph", "Double _x not found");
return kFALSE;
}
batch[batch_pos-1]->SetToolObject(graph);
return kTRUE;
}
Bool_t PProjector::AddTGraph2D(TGraph2D *graph, const char *command) {
if (!AddCommand(command)) return kFALSE;
key = makeDataBase()->GetEntry("batch_objects");
key_x = makeDataBase()->GetEntry("_x");
key_y = makeDataBase()->GetEntry("_y");
if (key_x < 0) {
Error ("AddTGraph2D", "result _x not found");
return kFALSE;
}
if (key_y < 0) {
Error ("AddTGraph2D", "result _y not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_x, batch_value_param, &x)) {
Error ("AddTGraph2D", "Double _x not found");
return kFALSE;
}
if (!makeDataBase()->GetParamDouble(key_y, batch_value_param, &y)) {
Error ("AddTGraph2D", "Double _y not found");
return kFALSE;
}
batch[batch_pos-1]->SetToolObject(graph);
return kTRUE;
}
Bool_t PProjector::AddOutputTNtuple(TNtuple *n, const char *command) {
if (!AddCommand(command)) {
return kFALSE;
}
fp_out[batch_pos-1] = n;
key = makeDataBase()->GetEntry("batch_objects");
TIter iter(fp_out[batch_pos-1]->GetListOfBranches());
while(TBranch *br = (TBranch *)iter.Next()) {
const char *name = br->GetName();
if (key_pos_out[batch_pos-1] == PROJECTOR_MAX_BRANCHES) {
Error("AddNTuple", "Too many branches in NTuple");
return kFALSE;
}
key_list_out[batch_pos-1][key_pos_out[batch_pos-1]] = makeDataBase()->GetEntry((char *) name);
if (key_list_out[batch_pos-1][key_pos_out[batch_pos-1]] < 0) {
Warning("AddOutputNTuple", "Branch %s found in NTuple but not defined as a batch value", name);
}
key_pos_out[batch_pos-1]++;
}
return kTRUE;
}
Bool_t PProjector::AddInputASCII(const char *filename, const char *command) {
FILE * file = fopen(filename, "r");
if (!file) {
Error("AddInputASCII", "Could not open %s",filename);
return kFALSE;
}
current_ascii_file = file;
if (!AddCommand(command)) {
return kFALSE;
}
batch[batch_pos-1]->SetToolObject(file);
fPriority = FILEINPUT_PRIORITY;
return kTRUE;
}
Bool_t PProjector::AddOutputASCII(const char *filename, const char *command) {
FILE * file = fopen(filename,"w");
if (!file) {
Error("AddOutputASCII", "Could not open %s", filename);
return kFALSE;
}
current_ascii_file = file;
if (!AddCommand(command)) {
return kFALSE;
}
batch[batch_pos-1]->SetToolObject(file);
return kTRUE;
}
Bool_t PProjector::AddInputTNtuple(TNtuple *n,const char *command) {
if (!AddCommand(command)) {
return kFALSE;
}
fp_in[batch_pos-1] = n;
num_events_in[batch_pos-1] = n->GetEntries();
num_events_in_c[batch_pos-1] = 0;
key = makeDataBase()->GetEntry("batch_objects");
TIter iter(fp_in[batch_pos-1]->GetListOfBranches());
while(TBranch *br = (TBranch *)iter.Next()) {
const char *name = br->GetName();
if (key_pos_in[batch_pos-1] == PROJECTOR_MAX_BRANCHES) {
Error("AddNTuple", "Too many branches in NTuple");
return kFALSE;
}
key_list_in[batch_pos-1][key_pos_in[batch_pos-1]] = makeDataBase()->GetEntry((char *) name);
if (key_list_in[batch_pos-1][key_pos_in[batch_pos-1]] < 0) {
key_list_in[batch_pos-1][key_pos_in[batch_pos-1]] = makeStaticData()->
MakeDirectoryEntry("batch_objects", NBATCH_NAME, LBATCH_NAME, name);
Info("AddInputTNtuple", "Created variable %s for the TNtuple branch", name);
}
Double_t *val;
if (!makeDataBase()->GetParamDouble(key_list_in[batch_pos-1][key_pos_in[batch_pos-1]], batch_value_param, &val)) {
Double_t *delme = new Double_t(0.);
makeDataBase()->SetParamDouble(key_list_in[batch_pos-1][key_pos_in[batch_pos-1]], "batch_value", delme);
}
n->SetBranchAddress(name, &(values_in[batch_pos-1][key_pos_in[batch_pos-1]]));
key_pos_in[batch_pos-1]++;
}
fPriority = FILEINPUT_PRIORITY;
return kTRUE;
}
Int_t PProjector::SetParticles(PParticle **mstack, int *, int *num, int, Int_t first_time) {
Int_t listkey=-1, *i_result, new_particles=0, counter_all=0, particle_key;
if (first_time) {
for (int i=0; i<*num; i++) {
particle_key = makeStaticData()->GetParticleKey(mstack[i]->ID());
if (makeDataBase()->GetParamInt(particle_key, stream_default_pos_param, &i_result)) {
(*i_result) = 0;
}
}
particle_key = makeStaticData()->GetParticleKey(0);
if (makeDataBase()->GetParamInt(particle_key, stream_default_pos_param, &i_result)) {
(*i_result) = 0;
}
for (int i=0; i<*num; i++) {
particle_key = makeStaticData()->GetParticleKey(mstack[i]->ID());
if (makeDataBase()->GetParamInt(particle_key, stream_max_pos_param, &i_result)) {
(*i_result) = 0;
}
}
particle_key = makeStaticData()->GetParticleKey(0);
if (makeDataBase()->GetParamInt(particle_key, stream_max_pos_param, &i_result)) {
(*i_result) = 0;
}
for (int i=0; i<*num; i++) {
if (mstack[i]->IsActive()) {
particle_key = makeStaticData()->GetParticleKey(mstack[i]->ID());
if (makeDataBase()->GetParamInt(particle_key, stream_max_pos_param, &i_result)) {
(*i_result)++;
} else {
Int_t *dummy = new Int_t(1);
makeDataBase()->SetParamInt(particle_key, STREAM_MAX_POS, dummy);
}
particle_key = makeStaticData()->GetParticleKey(0);
if (makeDataBase()->GetParamInt (particle_key, stream_max_pos_param, &i_result)) {
(*i_result)++;
} else {
Int_t *dummy = new Int_t(1);
makeDataBase()->SetParamInt(particle_key, STREAM_MAX_POS, dummy);
}
counter_all++;
}
mstack[i]->SetScatterClone(kFALSE);
}
}
while (makeDataBase()->MakeListIterator(key, NBATCH_NAME, LBATCH_NAME, &listkey)) {
if (makeDataBase()->GetParamInt (listkey, pid_param, &i_result)) {
Int_t pid = *i_result;
Int_t pos = -1;
if (makeDataBase()->GetParamInt(listkey, link_param, &i_result)) {
pos = *i_result-1;
}
if (pos >= 0) {
makeDataBase()->SetParamTObj(listkey, batch_particle_param, NULL);
} else if ((pos == -112) && first_time && (*(proj_nr) == bulk_id)) {
new_particles++;
if (new_particles == PROJECTOR_MAX_STACK) {
Warning("Modify", "PROJECTOR_MAX_STACK reached");
return kFALSE;
}
if (new_particles > stackpointer) {
stack[stackpointer] = new PParticle(0,0,0,0);
stackpointer++;
Info("SetParticles", "New particle created");
}
mstack[*num] = &(stack[new_particles-1]);
stack[new_particles-1].SetID(pid);
stack[new_particles-1].SetW(1.0);
makeDataBase()->SetParamTObj(listkey, batch_particle_param, &(stack[new_particles-1]));
(*num)++;
} else if (pos == -1) {
makeDataBase()->SetParamTObj(listkey, batch_particle_param, NULL);
Int_t particle_key = makeStaticData()->GetParticleKey(pid);
if (makeDataBase()->GetParamInt(particle_key, stream_default_pos_param, &i_result)) {
pos = (*i_result);
} else
pos = 0;
} else if (pos < -1000) {
Double_t *res;
if (makeDataBase()->GetParamDouble((-(pos+1))-1000, batch_value_param, &res)) {
pos = ((Int_t) *res)-1;
} else {
pos = -1000;
}
}
if (pos == -1000) {
Error("SetParticles", "Unkown particle position for %s", makeDataBase()->GetName(listkey));
}
for (int i=0; i<*num; i++) {
if (mstack[i]->IsActive()) {
if ((mstack[i]->ID() == pid) || (pid==0)) {
if (pos == 0) {
TObject *delme = (TObject *) mstack[i];
makeDataBase()->SetParamTObj(listkey, batch_particle_param, delme);
}
pos--;
}
}
}
}
}
return 0;
}
Bool_t PProjector::Modify(PParticle **mstack, int *decay_done, int * num, int stacksize) {
*w = current_weight;
SetParticles(mstack, decay_done, num, stacksize, 1);
Int_t startcommand = 0;
Int_t retval = kFALSE;
for (int i=0; i<batch_pos; i++) {
if (i<0) return -1;
retval = batch[i]->Execute(startcommand, retval);
startcommand = 0;
if (retval & kTRUE) {
current_weight = *w;
if (hist3[i] && fFillFlag[i]) {
if (hist3[i]->GetSumw2()->GetSize() || fFillFlag[i]==1)
hist3[i]->Fill((*x), (*y), (*z), current_weight);
else
hist3[i]->Fill((*x), (*y), (*z));
}
if (hist2[i] && fFillFlag[i]) {
if (hist2[i]->GetSumw2()->GetSize() || fFillFlag[i]==1)
hist2[i]->Fill((*x), (*y), current_weight);
else
hist2[i]->Fill((*x), (*y));
}
if (hist1[i] && fFillFlag[i]) {
if (hist1[i]->GetSumw2()->GetSize() || fFillFlag[i]==1)
hist1[i]->Fill((*x), current_weight);
else {
hist1[i]->Fill((*x));
}
}
if (fp_out[i]) {
Double_t *val;
for (int j=0; j<key_pos_out[i]; j++) {
if (key_list_out[i][j] > -1) {
if (makeDataBase()->GetParamDouble(key_list_out[i][j], batch_value_param, &val))
values[j] = (Float_t)(*val);
else values[j] = 0;
}
else values[j] = 0;
}
fp_out[i]->Fill(values);
}
if (fp_in[i]) {
if (num_events_in_c[i] == num_events_in[i]) {
Info("Modify", "NTuple <%s>: number of events reached", fp_in[i]->GetTitle());
return kFALSE;
}
fp_in[i]->GetEntry(num_events_in_c[i]);
Double_t *val;
for (int j=0; j<key_pos_in[i]; j++) {
if (key_list_in[i][j] > -1) {
if (makeDataBase()->GetParamDouble(key_list_in[i][j], batch_value_param, &val))
*val = values_in[i][j];
}
}
num_events_in_c[i]++;
}
}
int redo = 0;
int setparticle = 0;
if (retval & kGOTO) {
if (batch[i]->GetNewBulk() == bulk_id) {
setparticle = 1;
Int_t new_batch = batch[i]->GetNewBatch();
startcommand = batch[i]->GetNewCommand();
i = new_batch - 1;
} else {
Error("Modify", "Jumping with a GOTO over different Projector not yet implemented");
}
retval &= ~kGOTO;
}
if (retval & kPUSH) {
startcommand = batch[i]->GetOldCommand();
if ((*num) >= stacksize) {
Warning("Modify (kPUSH)", "Stack size too small, increase '_system_particle_stacksize'");
return kTRUE;
}
if (batch[i]->GetCurrentParticle()) {
*(mstack[*num]) = *(batch[i]->GetCurrentParticle());
(*num)++;
decay_done[*num]=0;
setparticle = 2;
} else {
Warning("Modify (kPUSH)", "Pushed particle not found");
}
redo = 1;
retval &= ~kPUSH;
}
if (retval & kPUSHBRANCH) {
startcommand = batch[i]->GetOldCommand();
if (batch[i]->GetBranch() > (*size_branches)) {
Warning("Modify (kPUSHBRANCH)", "Branch number %i not known", *size_branches);
return kTRUE;
}
if ( (*(current_size_branches[batch[i]->GetBranch()-1])) >= stacksize) {
Warning("Modify (kPUSHBRANCH)", "Stack size too small, increase '_system_particle_stacksize'");
return kTRUE;
}
if (batch[i]->GetCurrentParticle()) {
*((particle_array_branches[batch[i]->GetBranch()-1])
[*(current_size_branches[batch[i]->GetBranch()-1])] )
= *(batch[i]->GetCurrentParticle());
(*(current_size_branches[batch[i]->GetBranch()-1]))++;
} else {
Warning("Modify", "Pushed particle not found");
}
redo = 1;
retval &= ~kPUSHBRANCH;
}
if (retval & kFOREACHEND) {
setparticle = 1;
startcommand = 0;
retval &= ~kFOREACHEND;
retval &= ~kFOREACH;
}
if (retval & kUPDATE) {
setparticle = 1;
startcommand = batch[i]->GetOldCommand();
redo = 1;
retval &= ~kUPDATE;
}
if (retval & kEOF) {
Info("Modify", "EOF reached");
return kFALSE;
}
if (retval & kFOREACH) {
startcommand = batch[i]->GetOldCommand();
redo = 1;
setparticle = 1;
retval &= ~kFOREACHEND;
}
if (retval & kELSE) {
if (batch[i]->GetElsePosition()>-1 &&
batch[i]->GetCurrentPosition() < batch[i]->GetElsePosition() ) {
startcommand = batch[i]->GetElsePosition();
redo = 1;
}
}
if (setparticle == 1) SetParticles(mstack, decay_done, num, stacksize, 0);
if (setparticle == 2) SetParticles(mstack, decay_done, num, stacksize, 1);
if (redo) i -= 1;
retval &= ~kTRUE;
}
Int_t *i_result;
for (int i=0; i<*num; i++) {
Int_t particle_key = makeStaticData()->GetParticleKey(mstack[i]->ID());
if (makeDataBase()->GetParamInt (particle_key, stream_max_pos_param, &i_result)) {
(*i_result) = 0;
}
}
return kTRUE;
}
void PProjector::Print(const Option_t*) const {
for (int i=0; i<batch_pos; i++)
batch[i]->Print();
}
ClassImp(PProjector)