////////////////////////////////////////////////////////
//  Pluto projector interface
//
//  The main idea of this class is to provide a very
//  simple, fast and easy-to-use analysis tool, which
//  make the writing of an analysis macro unnecessary.
//  It uses the Bulk interface and can be plugged into
//  the reaction before or after the decay
//
//  The syntax of the commands are based on the PBatch syntax,
//  for details look into the documentation of this class.
//
//  Commands for the batch can be added in 2 ways: Either
//  with AddCommand(char * command) or
//  in one step together with a histogram which will 
//  be filled after the command has been executed.
//
//  Input: The input for the commands must be particles
//  from the data stream in the fillowing format:
//  [pid,num] where pid is the pid-string (e.g. "pi0")
//  and num is the number of the particle (can be omitted if only
//  one particle of this type present)
//
//  Output: _x,_y as doubles. The latter one only for 2dim histograms.
//
//                    Author:  Ingo Froehlich
//                    Written: 14/02/2008
//                    Revised: 
//
////////////////////////////////////////////////////////



#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) {

    //adds a command line to batch
    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);  //Set absolute adress
    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;

    //get the result
    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;

    //get the result
    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;

    //get the result
    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;

    //get the result
    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;

    //get the result
    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;

    //get the result
    key = makeDataBase()->GetEntry("batch_objects");
    //Examine NTuple file and get the branches

    TIter iter(fp_out[batch_pos-1]->GetListOfBranches());
    while(TBranch *br = (TBranch *)iter.Next()) {
	const char *name = br->GetName();

	//Each branch should be correlated to the batch key
	
	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; //counted events

    //get the result
    key = makeDataBase()->GetEntry("batch_objects");
    //Examine NTuple file and get the branches

    TIter iter(fp_in[batch_pos-1]->GetListOfBranches());
    while(TBranch *br = (TBranch *)iter.Next()) {
	const char *name = br->GetName();

	//Each branch should be correlated to the batch key
	
	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);
	}

	//Check if double is existing
	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);
	}

	//Set the branch adress to the floats
	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) {
    //loop over batch object and see what I can do

    Int_t listkey=-1, *i_result, new_particles=0, counter_all=0, particle_key;

    if (first_time) {
 	for (int i=0; i<*num; i++) {
	    //cout << "FT:" << i << ":" << mstack[i]->ID() << endl;
 	    //Delete old default pos list
	    // Reset value on 1st call -> BUGBUG: can cause trouble when jumping over 2 projectors
 	    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); //DUMMY=all particles
	if (makeDataBase()->GetParamInt(particle_key, stream_default_pos_param, &i_result)) {
	    (*i_result) = 0;
	} 
	for (int i=0; i<*num; i++) {
 	    //Delete old max pos list
 	    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); //DUMMY=all particles
	if (makeDataBase()->GetParamInt(particle_key, stream_max_pos_param, &i_result)) {
	    (*i_result) = 0;
	} 
	for (int i=0; i<*num; i++) {
	    //Create max list
	    if (mstack[i]->IsActive()) { //count only active particles
		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); //DUMMY=all particles
		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); //disable making clones when copy constructor is called -> memory leak
	} 
	//cout << "counted max " << counter_all << endl;
    }//END first_time

    while (makeDataBase()->MakeListIterator(key, NBATCH_NAME, LBATCH_NAME, &listkey)) {
        //loop over all particles
	//cout << "key=" << listkey << endl;
	if (makeDataBase()->GetParamInt (listkey, pid_param, &i_result)) {
	    Int_t pid = *i_result;

	    //fill object
	    Int_t pos = -1;
	    if (makeDataBase()->GetParamInt(listkey, link_param, &i_result)) {
		pos = *i_result-1;
	    }
	    //cout << "key=" << listkey << " pos:" << pos << endl;
	    //First clear the entry to avoid the use of old objects
	    if (pos >= 0) {
		makeDataBase()->SetParamTObj(listkey, batch_particle_param, NULL);
	    } else if ((pos == -112) && first_time && (*(proj_nr) == bulk_id)) { 
		//stumbled over "+"
		//cout << "CALLED + in "<< bulk_id << endl;
		new_particles++;
		if (new_particles == PROJECTOR_MAX_STACK) {
		    Warning("Modify", "PROJECTOR_MAX_STACK reached");
		    return kFALSE;
		}
		if (new_particles > stackpointer) {
		    //create new pparticle
		    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) {
		//No pos, default 
		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) { //found link to variable
		//cout << "pos  is now:" << pos << edl;
		Double_t *res;
		if (makeDataBase()->GetParamDouble((-(pos+1))-1000, batch_value_param, &res)) {
		    //cout << "key: " << ((-(pos+1))-1000) << " res: " << *res << endl;
		    //makeDataBase()->ListEntries(-1,1,"*name,batch_value,*num_batch,*pid,*link");
		    pos = ((Int_t) *res)-1;
		} else {
		    pos = -1000;
		}
	    }

	    if (pos == -1000) {
		Error("SetParticles", "Unkown particle position for %s", makeDataBase()->GetName(listkey));
	    }

	    //cout << "pos  is now:" << pos << " for " << makeDataBase()->GetName(listkey) <<  endl;

	    for (int i=0; i<*num; i++) {
		//cout << mstack[i]->IsActive() << endl;
		if (mstack[i]->IsActive()) {
		    
		    //cout << "stack_pid:"<< mstack[i]->ID() << endl;
		    //mstack[i]->Print();
		    if ((mstack[i]->ID() == pid) || (pid==0)) { //0=DUMMY
			//cout << "match " << pid << " at " << pos << endl;
			if (pos == 0) {
			    TObject *delme =  (TObject *) mstack[i];
			    makeDataBase()->SetParamTObj(listkey, batch_particle_param, delme);
			    //makeDataBase()->ListEntries(listkey,1,"name,*pid,*batch_particle");
			} 
			pos--;
		    }
		}
	    }
	}	
    }
    return 0;
}

Bool_t PProjector::Modify(PParticle **mstack, int *decay_done, int * num, int stacksize) {
    //cout << "Modify " << endl;

    *w = current_weight;
    
    SetParticles(mstack, decay_done, num, stacksize, 1);
    //cout << "num:  " << *num << endl;
    //excuting batch
    Int_t startcommand = 0;
    Int_t retval = kFALSE;
    for (int i=0; i<batch_pos; i++) {

	//cout << "do now : " << i << endl;
	if (i<0) return -1;
	retval = batch[i]->Execute(startcommand, retval);
	//cout << "retval:" << retval << endl;
	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]) {
		//fill the ntuple
		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]) {
		//read the ntuple
		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) {
		//stay in the same PProjector
		setparticle = 1;
		//SetParticles(mstack, decay_done, num, stacksize, 0);  //reset particles for "formore"
		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();
	    //cout << startcommand << endl;
	    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;
		//SetParticles(mstack, decay_done, num, stacksize, 1);  //reset particles
	    } else {
		Warning("Modify (kPUSH)", "Pushed particle not found");
	    }
	    //i -= 1; //stay in same batch
	    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;
	    //SetParticles(mstack, decay_done, num, stacksize, 0);  //reset particles like for "formore"
	    startcommand = 0;
	    retval &= ~kFOREACHEND;
	    retval &= ~kFOREACH;
	} 
	if (retval & kUPDATE) {
	    setparticle = 1;
	    //SetParticles(mstack, decay_done, num, stacksize, 0);  //reset particles like for "formore"
	    startcommand = batch[i]->GetOldCommand();
	    redo = 1;
	    retval &= ~kUPDATE;
	} 
	if (retval & kEOF) {
	    Info("Modify", "EOF reached");
	    return kFALSE;
	} 
	if (retval & kFOREACH) {
	    startcommand = batch[i]->GetOldCommand();
	    //cout << "sc foreach " << startcommand << endl;
	    redo = 1;
	    setparticle = 1;
	    //SetParticles(mstack, decay_done, num, stacksize, 0);  //reset particles like for "formore"
	    retval &= ~kFOREACHEND;
	} 
	if (retval & kELSE) {
	    if (batch[i]->GetElsePosition()>-1 &&  //only if else is provided
		batch[i]->GetCurrentPosition() < batch[i]->GetElsePosition() ) { //avoid deadlocks
		startcommand = batch[i]->GetElsePosition();
		redo = 1;
		//i -= 1; //stay in same batch		
	    }
	}
	if (setparticle == 1) SetParticles(mstack, decay_done, num, stacksize, 0);
	if (setparticle == 2) SetParticles(mstack, decay_done, num, stacksize, 1);
	if (redo) i -= 1; //stay in same batch	

	retval &= ~kTRUE; //clean true flag for next loop
    }

    Int_t *i_result;
    //Before leaving clean the max_list again, because next time we could have a different configuration of PIDS
    for (int i=0; i<*num; i++) {
	//Delete old max pos list
	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)
 PProjector.cc:1
 PProjector.cc:2
 PProjector.cc:3
 PProjector.cc:4
 PProjector.cc:5
 PProjector.cc:6
 PProjector.cc:7
 PProjector.cc:8
 PProjector.cc:9
 PProjector.cc:10
 PProjector.cc:11
 PProjector.cc:12
 PProjector.cc:13
 PProjector.cc:14
 PProjector.cc:15
 PProjector.cc:16
 PProjector.cc:17
 PProjector.cc:18
 PProjector.cc:19
 PProjector.cc:20
 PProjector.cc:21
 PProjector.cc:22
 PProjector.cc:23
 PProjector.cc:24
 PProjector.cc:25
 PProjector.cc:26
 PProjector.cc:27
 PProjector.cc:28
 PProjector.cc:29
 PProjector.cc:30
 PProjector.cc:31
 PProjector.cc:32
 PProjector.cc:33
 PProjector.cc:34
 PProjector.cc:35
 PProjector.cc:36
 PProjector.cc:37
 PProjector.cc:38
 PProjector.cc:39
 PProjector.cc:40
 PProjector.cc:41
 PProjector.cc:42
 PProjector.cc:43
 PProjector.cc:44
 PProjector.cc:45
 PProjector.cc:46
 PProjector.cc:47
 PProjector.cc:48
 PProjector.cc:49
 PProjector.cc:50
 PProjector.cc:51
 PProjector.cc:52
 PProjector.cc:53
 PProjector.cc:54
 PProjector.cc:55
 PProjector.cc:56
 PProjector.cc:57
 PProjector.cc:58
 PProjector.cc:59
 PProjector.cc:60
 PProjector.cc:61
 PProjector.cc:62
 PProjector.cc:63
 PProjector.cc:64
 PProjector.cc:65
 PProjector.cc:66
 PProjector.cc:67
 PProjector.cc:68
 PProjector.cc:69
 PProjector.cc:70
 PProjector.cc:71
 PProjector.cc:72
 PProjector.cc:73
 PProjector.cc:74
 PProjector.cc:75
 PProjector.cc:76
 PProjector.cc:77
 PProjector.cc:78
 PProjector.cc:79
 PProjector.cc:80
 PProjector.cc:81
 PProjector.cc:82
 PProjector.cc:83
 PProjector.cc:84
 PProjector.cc:85
 PProjector.cc:86
 PProjector.cc:87
 PProjector.cc:88
 PProjector.cc:89
 PProjector.cc:90
 PProjector.cc:91
 PProjector.cc:92
 PProjector.cc:93
 PProjector.cc:94
 PProjector.cc:95
 PProjector.cc:96
 PProjector.cc:97
 PProjector.cc:98
 PProjector.cc:99
 PProjector.cc:100
 PProjector.cc:101
 PProjector.cc:102
 PProjector.cc:103
 PProjector.cc:104
 PProjector.cc:105
 PProjector.cc:106
 PProjector.cc:107
 PProjector.cc:108
 PProjector.cc:109
 PProjector.cc:110
 PProjector.cc:111
 PProjector.cc:112
 PProjector.cc:113
 PProjector.cc:114
 PProjector.cc:115
 PProjector.cc:116
 PProjector.cc:117
 PProjector.cc:118
 PProjector.cc:119
 PProjector.cc:120
 PProjector.cc:121
 PProjector.cc:122
 PProjector.cc:123
 PProjector.cc:124
 PProjector.cc:125
 PProjector.cc:126
 PProjector.cc:127
 PProjector.cc:128
 PProjector.cc:129
 PProjector.cc:130
 PProjector.cc:131
 PProjector.cc:132
 PProjector.cc:133
 PProjector.cc:134
 PProjector.cc:135
 PProjector.cc:136
 PProjector.cc:137
 PProjector.cc:138
 PProjector.cc:139
 PProjector.cc:140
 PProjector.cc:141
 PProjector.cc:142
 PProjector.cc:143
 PProjector.cc:144
 PProjector.cc:145
 PProjector.cc:146
 PProjector.cc:147
 PProjector.cc:148
 PProjector.cc:149
 PProjector.cc:150
 PProjector.cc:151
 PProjector.cc:152
 PProjector.cc:153
 PProjector.cc:154
 PProjector.cc:155
 PProjector.cc:156
 PProjector.cc:157
 PProjector.cc:158
 PProjector.cc:159
 PProjector.cc:160
 PProjector.cc:161
 PProjector.cc:162
 PProjector.cc:163
 PProjector.cc:164
 PProjector.cc:165
 PProjector.cc:166
 PProjector.cc:167
 PProjector.cc:168
 PProjector.cc:169
 PProjector.cc:170
 PProjector.cc:171
 PProjector.cc:172
 PProjector.cc:173
 PProjector.cc:174
 PProjector.cc:175
 PProjector.cc:176
 PProjector.cc:177
 PProjector.cc:178
 PProjector.cc:179
 PProjector.cc:180
 PProjector.cc:181
 PProjector.cc:182
 PProjector.cc:183
 PProjector.cc:184
 PProjector.cc:185
 PProjector.cc:186
 PProjector.cc:187
 PProjector.cc:188
 PProjector.cc:189
 PProjector.cc:190
 PProjector.cc:191
 PProjector.cc:192
 PProjector.cc:193
 PProjector.cc:194
 PProjector.cc:195
 PProjector.cc:196
 PProjector.cc:197
 PProjector.cc:198
 PProjector.cc:199
 PProjector.cc:200
 PProjector.cc:201
 PProjector.cc:202
 PProjector.cc:203
 PProjector.cc:204
 PProjector.cc:205
 PProjector.cc:206
 PProjector.cc:207
 PProjector.cc:208
 PProjector.cc:209
 PProjector.cc:210
 PProjector.cc:211
 PProjector.cc:212
 PProjector.cc:213
 PProjector.cc:214
 PProjector.cc:215
 PProjector.cc:216
 PProjector.cc:217
 PProjector.cc:218
 PProjector.cc:219
 PProjector.cc:220
 PProjector.cc:221
 PProjector.cc:222
 PProjector.cc:223
 PProjector.cc:224
 PProjector.cc:225
 PProjector.cc:226
 PProjector.cc:227
 PProjector.cc:228
 PProjector.cc:229
 PProjector.cc:230
 PProjector.cc:231
 PProjector.cc:232
 PProjector.cc:233
 PProjector.cc:234
 PProjector.cc:235
 PProjector.cc:236
 PProjector.cc:237
 PProjector.cc:238
 PProjector.cc:239
 PProjector.cc:240
 PProjector.cc:241
 PProjector.cc:242
 PProjector.cc:243
 PProjector.cc:244
 PProjector.cc:245
 PProjector.cc:246
 PProjector.cc:247
 PProjector.cc:248
 PProjector.cc:249
 PProjector.cc:250
 PProjector.cc:251
 PProjector.cc:252
 PProjector.cc:253
 PProjector.cc:254
 PProjector.cc:255
 PProjector.cc:256
 PProjector.cc:257
 PProjector.cc:258
 PProjector.cc:259
 PProjector.cc:260
 PProjector.cc:261
 PProjector.cc:262
 PProjector.cc:263
 PProjector.cc:264
 PProjector.cc:265
 PProjector.cc:266
 PProjector.cc:267
 PProjector.cc:268
 PProjector.cc:269
 PProjector.cc:270
 PProjector.cc:271
 PProjector.cc:272
 PProjector.cc:273
 PProjector.cc:274
 PProjector.cc:275
 PProjector.cc:276
 PProjector.cc:277
 PProjector.cc:278
 PProjector.cc:279
 PProjector.cc:280
 PProjector.cc:281
 PProjector.cc:282
 PProjector.cc:283
 PProjector.cc:284
 PProjector.cc:285
 PProjector.cc:286
 PProjector.cc:287
 PProjector.cc:288
 PProjector.cc:289
 PProjector.cc:290
 PProjector.cc:291
 PProjector.cc:292
 PProjector.cc:293
 PProjector.cc:294
 PProjector.cc:295
 PProjector.cc:296
 PProjector.cc:297
 PProjector.cc:298
 PProjector.cc:299
 PProjector.cc:300
 PProjector.cc:301
 PProjector.cc:302
 PProjector.cc:303
 PProjector.cc:304
 PProjector.cc:305
 PProjector.cc:306
 PProjector.cc:307
 PProjector.cc:308
 PProjector.cc:309
 PProjector.cc:310
 PProjector.cc:311
 PProjector.cc:312
 PProjector.cc:313
 PProjector.cc:314
 PProjector.cc:315
 PProjector.cc:316
 PProjector.cc:317
 PProjector.cc:318
 PProjector.cc:319
 PProjector.cc:320
 PProjector.cc:321
 PProjector.cc:322
 PProjector.cc:323
 PProjector.cc:324
 PProjector.cc:325
 PProjector.cc:326
 PProjector.cc:327
 PProjector.cc:328
 PProjector.cc:329
 PProjector.cc:330
 PProjector.cc:331
 PProjector.cc:332
 PProjector.cc:333
 PProjector.cc:334
 PProjector.cc:335
 PProjector.cc:336
 PProjector.cc:337
 PProjector.cc:338
 PProjector.cc:339
 PProjector.cc:340
 PProjector.cc:341
 PProjector.cc:342
 PProjector.cc:343
 PProjector.cc:344
 PProjector.cc:345
 PProjector.cc:346
 PProjector.cc:347
 PProjector.cc:348
 PProjector.cc:349
 PProjector.cc:350
 PProjector.cc:351
 PProjector.cc:352
 PProjector.cc:353
 PProjector.cc:354
 PProjector.cc:355
 PProjector.cc:356
 PProjector.cc:357
 PProjector.cc:358
 PProjector.cc:359
 PProjector.cc:360
 PProjector.cc:361
 PProjector.cc:362
 PProjector.cc:363
 PProjector.cc:364
 PProjector.cc:365
 PProjector.cc:366
 PProjector.cc:367
 PProjector.cc:368
 PProjector.cc:369
 PProjector.cc:370
 PProjector.cc:371
 PProjector.cc:372
 PProjector.cc:373
 PProjector.cc:374
 PProjector.cc:375
 PProjector.cc:376
 PProjector.cc:377
 PProjector.cc:378
 PProjector.cc:379
 PProjector.cc:380
 PProjector.cc:381
 PProjector.cc:382
 PProjector.cc:383
 PProjector.cc:384
 PProjector.cc:385
 PProjector.cc:386
 PProjector.cc:387
 PProjector.cc:388
 PProjector.cc:389
 PProjector.cc:390
 PProjector.cc:391
 PProjector.cc:392
 PProjector.cc:393
 PProjector.cc:394
 PProjector.cc:395
 PProjector.cc:396
 PProjector.cc:397
 PProjector.cc:398
 PProjector.cc:399
 PProjector.cc:400
 PProjector.cc:401
 PProjector.cc:402
 PProjector.cc:403
 PProjector.cc:404
 PProjector.cc:405
 PProjector.cc:406
 PProjector.cc:407
 PProjector.cc:408
 PProjector.cc:409
 PProjector.cc:410
 PProjector.cc:411
 PProjector.cc:412
 PProjector.cc:413
 PProjector.cc:414
 PProjector.cc:415
 PProjector.cc:416
 PProjector.cc:417
 PProjector.cc:418
 PProjector.cc:419
 PProjector.cc:420
 PProjector.cc:421
 PProjector.cc:422
 PProjector.cc:423
 PProjector.cc:424
 PProjector.cc:425
 PProjector.cc:426
 PProjector.cc:427
 PProjector.cc:428
 PProjector.cc:429
 PProjector.cc:430
 PProjector.cc:431
 PProjector.cc:432
 PProjector.cc:433
 PProjector.cc:434
 PProjector.cc:435
 PProjector.cc:436
 PProjector.cc:437
 PProjector.cc:438
 PProjector.cc:439
 PProjector.cc:440
 PProjector.cc:441
 PProjector.cc:442
 PProjector.cc:443
 PProjector.cc:444
 PProjector.cc:445
 PProjector.cc:446
 PProjector.cc:447
 PProjector.cc:448
 PProjector.cc:449
 PProjector.cc:450
 PProjector.cc:451
 PProjector.cc:452
 PProjector.cc:453
 PProjector.cc:454
 PProjector.cc:455
 PProjector.cc:456
 PProjector.cc:457
 PProjector.cc:458
 PProjector.cc:459
 PProjector.cc:460
 PProjector.cc:461
 PProjector.cc:462
 PProjector.cc:463
 PProjector.cc:464
 PProjector.cc:465
 PProjector.cc:466
 PProjector.cc:467
 PProjector.cc:468
 PProjector.cc:469
 PProjector.cc:470
 PProjector.cc:471
 PProjector.cc:472
 PProjector.cc:473
 PProjector.cc:474
 PProjector.cc:475
 PProjector.cc:476
 PProjector.cc:477
 PProjector.cc:478
 PProjector.cc:479
 PProjector.cc:480
 PProjector.cc:481
 PProjector.cc:482
 PProjector.cc:483
 PProjector.cc:484
 PProjector.cc:485
 PProjector.cc:486
 PProjector.cc:487
 PProjector.cc:488
 PProjector.cc:489
 PProjector.cc:490
 PProjector.cc:491
 PProjector.cc:492
 PProjector.cc:493
 PProjector.cc:494
 PProjector.cc:495
 PProjector.cc:496
 PProjector.cc:497
 PProjector.cc:498
 PProjector.cc:499
 PProjector.cc:500
 PProjector.cc:501
 PProjector.cc:502
 PProjector.cc:503
 PProjector.cc:504
 PProjector.cc:505
 PProjector.cc:506
 PProjector.cc:507
 PProjector.cc:508
 PProjector.cc:509
 PProjector.cc:510
 PProjector.cc:511
 PProjector.cc:512
 PProjector.cc:513
 PProjector.cc:514
 PProjector.cc:515
 PProjector.cc:516
 PProjector.cc:517
 PProjector.cc:518
 PProjector.cc:519
 PProjector.cc:520
 PProjector.cc:521
 PProjector.cc:522
 PProjector.cc:523
 PProjector.cc:524
 PProjector.cc:525
 PProjector.cc:526
 PProjector.cc:527
 PProjector.cc:528
 PProjector.cc:529
 PProjector.cc:530
 PProjector.cc:531
 PProjector.cc:532
 PProjector.cc:533
 PProjector.cc:534
 PProjector.cc:535
 PProjector.cc:536
 PProjector.cc:537
 PProjector.cc:538
 PProjector.cc:539
 PProjector.cc:540
 PProjector.cc:541
 PProjector.cc:542
 PProjector.cc:543
 PProjector.cc:544
 PProjector.cc:545
 PProjector.cc:546
 PProjector.cc:547
 PProjector.cc:548
 PProjector.cc:549
 PProjector.cc:550
 PProjector.cc:551
 PProjector.cc:552
 PProjector.cc:553
 PProjector.cc:554
 PProjector.cc:555
 PProjector.cc:556
 PProjector.cc:557
 PProjector.cc:558
 PProjector.cc:559
 PProjector.cc:560
 PProjector.cc:561
 PProjector.cc:562
 PProjector.cc:563
 PProjector.cc:564
 PProjector.cc:565
 PProjector.cc:566
 PProjector.cc:567
 PProjector.cc:568
 PProjector.cc:569
 PProjector.cc:570
 PProjector.cc:571
 PProjector.cc:572
 PProjector.cc:573
 PProjector.cc:574
 PProjector.cc:575
 PProjector.cc:576
 PProjector.cc:577
 PProjector.cc:578
 PProjector.cc:579
 PProjector.cc:580
 PProjector.cc:581
 PProjector.cc:582
 PProjector.cc:583
 PProjector.cc:584
 PProjector.cc:585
 PProjector.cc:586
 PProjector.cc:587
 PProjector.cc:588
 PProjector.cc:589
 PProjector.cc:590
 PProjector.cc:591
 PProjector.cc:592
 PProjector.cc:593
 PProjector.cc:594
 PProjector.cc:595
 PProjector.cc:596
 PProjector.cc:597
 PProjector.cc:598
 PProjector.cc:599
 PProjector.cc:600
 PProjector.cc:601
 PProjector.cc:602
 PProjector.cc:603
 PProjector.cc:604
 PProjector.cc:605
 PProjector.cc:606
 PProjector.cc:607
 PProjector.cc:608
 PProjector.cc:609
 PProjector.cc:610
 PProjector.cc:611
 PProjector.cc:612
 PProjector.cc:613
 PProjector.cc:614
 PProjector.cc:615
 PProjector.cc:616
 PProjector.cc:617
 PProjector.cc:618
 PProjector.cc:619
 PProjector.cc:620
 PProjector.cc:621
 PProjector.cc:622
 PProjector.cc:623
 PProjector.cc:624
 PProjector.cc:625
 PProjector.cc:626
 PProjector.cc:627
 PProjector.cc:628
 PProjector.cc:629
 PProjector.cc:630
 PProjector.cc:631
 PProjector.cc:632
 PProjector.cc:633
 PProjector.cc:634
 PProjector.cc:635
 PProjector.cc:636
 PProjector.cc:637
 PProjector.cc:638
 PProjector.cc:639
 PProjector.cc:640
 PProjector.cc:641
 PProjector.cc:642
 PProjector.cc:643
 PProjector.cc:644
 PProjector.cc:645
 PProjector.cc:646
 PProjector.cc:647
 PProjector.cc:648
 PProjector.cc:649
 PProjector.cc:650
 PProjector.cc:651
 PProjector.cc:652
 PProjector.cc:653
 PProjector.cc:654
 PProjector.cc:655
 PProjector.cc:656
 PProjector.cc:657
 PProjector.cc:658
 PProjector.cc:659
 PProjector.cc:660
 PProjector.cc:661
 PProjector.cc:662
 PProjector.cc:663
 PProjector.cc:664
 PProjector.cc:665
 PProjector.cc:666
 PProjector.cc:667
 PProjector.cc:668
 PProjector.cc:669
 PProjector.cc:670
 PProjector.cc:671
 PProjector.cc:672
 PProjector.cc:673
 PProjector.cc:674
 PProjector.cc:675
 PProjector.cc:676
 PProjector.cc:677
 PProjector.cc:678
 PProjector.cc:679
 PProjector.cc:680
 PProjector.cc:681
 PProjector.cc:682
 PProjector.cc:683
 PProjector.cc:684
 PProjector.cc:685
 PProjector.cc:686
 PProjector.cc:687
 PProjector.cc:688
 PProjector.cc:689
 PProjector.cc:690
 PProjector.cc:691
 PProjector.cc:692
 PProjector.cc:693
 PProjector.cc:694
 PProjector.cc:695
 PProjector.cc:696
 PProjector.cc:697
 PProjector.cc:698
 PProjector.cc:699
 PProjector.cc:700
 PProjector.cc:701
 PProjector.cc:702
 PProjector.cc:703
 PProjector.cc:704
 PProjector.cc:705
 PProjector.cc:706
 PProjector.cc:707
 PProjector.cc:708
 PProjector.cc:709
 PProjector.cc:710
 PProjector.cc:711
 PProjector.cc:712
 PProjector.cc:713
 PProjector.cc:714
 PProjector.cc:715
 PProjector.cc:716
 PProjector.cc:717
 PProjector.cc:718
 PProjector.cc:719
 PProjector.cc:720
 PProjector.cc:721
 PProjector.cc:722
 PProjector.cc:723
 PProjector.cc:724
 PProjector.cc:725
 PProjector.cc:726
 PProjector.cc:727
 PProjector.cc:728
 PProjector.cc:729
 PProjector.cc:730
 PProjector.cc:731