// PDecayManager Class Header
//
//  Author:   Volker Hejny
//  Written:  27.08.99
//  Revised:  21.06.00 MK
//  Revised:  21.03.05 R. Holzmann
//
// This header file contains 
//   template class PNextList
//   template class PStack
//   class PReactionList
//   class PDecayManager
//
// While all these classes are global, the first three originally
// planned as to be private to PDecayChannel. Due to some (maybe
// trivial) problems with nested classes using rootcint, they were
// put in a global scope.
// --------------------------------------------------------------------------

#ifndef _PDECAYLIST_H_
#define _PDECAYLIST_H_

#include "TObject.h"
class TTree;
class TClonesArray;
class PReaction;
class PChannel;
class PParticle;
class TPythia6;

#include "PDistributionManager.h"
#include "PReaction.h"
#include "PBulkInterface.h"
#include "PProjector.h"

// the following templates and the class PReactionList are
// private members of PDecayManager, but I due to problems using
// ClassImp() and ClassDef() with nested classes, they are
// not derived from TObject. The members are all public for better 
// use inside PDecayManager.

// template PNextList:
// implements a linked list of pointers(!) to object T. A delete does 
// not imply a delete of the object T itself. If this is wanted -> use
// member function Delete().
template<class T>
class PNextList {
 public:
    T         *Curr;	    			// Pointer to object T
    PNextList *Next;				// Pointer to next list node
  
    PNextList()  : Curr(NULL), Next(NULL) {};
    PNextList(T *t) : Curr(t), Next(NULL) {};
    ~PNextList() { if (Next) delete Next; };

    void Add(T *t) {
	if (!Curr) 
	    Curr = t;			// if node still empty
	else if (!Next) 
	    Next = new PNextList<T>(t); // if node has no successor
	else 
	    Next->Add(t);				
    }
  
    void Delete() {				// delete all T objects
	delete Curr;	
	if (Next) 
	    Next->Delete();
    }
}; 
// end of template PNextList

// template PStack:
// implements a last-in-first-out standard stack via a single linked 
// list. Additionally the number of objects is counted.
template<class T>
class PStack {
 public:
    PNextList<T> *top;				// Pointer to top node
    Int_t         Count;
  
    PStack() : top(NULL), Count(0) {};
    ~PStack() { delete top; };			// delete the nodes, not
                                                // the object itself
    void Push(T* t) {
	PNextList<T> *temp = new PNextList<T>(t);   // new node with object T
	temp->Next = top;                           // position before top node
	top = temp;                                 // make new node the top node
	Count++;
    }
  
    T *Pop() {
	if (!top) return NULL;
	T *t = top->Curr;				// this object is to be returned
	PNextList<T> *t2 = top;			// store top to delete
	top = top->Next;                            
	t2->Next = NULL;                            // unlink
	delete t2;                                   
	Count--;
	return t;
    }

    // Clone doubles the whole stack. Either an empty stack is
    // used (giving UseThis as an argument) or a new stack is
    // produced.  
    PStack<T> *Clone(PStack<T> *UseThis = NULL) {
	PStack<T> *t1;
	if (UseThis) 
	    t1 = UseThis;
	else  	 
	    t1 = new PStack();
	if (!top) 
	    return t1;			// return an empty stack
	t1->Push(top->Curr);			// push top node object
	PNextList<T> *t2 = top;
	while (t2->Next) {				// add all node in t2 to t1
	    t2 = t2->Next;
	    t1->top->Add(t2->Curr);
	}
	t1->Count = Count;				// synchronize Count
	return t1;
    }
};
// end of template PStack

// class PReactionList:
// implements two connected stacks of PChannel to organize the
// already processed decay channels and the work to do. 
// The variable ReactionWeight contains the overall weight of
// this specific channel.
class PReactionList {
 public:
    PStack<PChannel> *Finished;
    PStack<PChannel> *ToDo;
    Double_t          ReactionWeight;
    Int_t	      ID;
    static Int_t      maxID;
  
    PReactionList() {
	Finished       = new PStack<PChannel>;
	ToDo           = new PStack<PChannel>;
	ReactionWeight = 1.;
	ID             = ++maxID;
    };

    ~PReactionList() {
	delete Finished;
	delete ToDo;
    }

    PReactionList *Clone() {
	PReactionList *newRL = new PReactionList;
	Finished->Clone(newRL->Finished);
	ToDo->Clone(newRL->ToDo);
	newRL->ReactionWeight = ReactionWeight;
	return newRL;
    }
};
// end of class PReactionList

// class PDecayManager:
// PDecayManager manages the decay modes of all available particles
// in Pluto and builds all possible decay chains from one starting
// particle.
// The list of decay modes is empty by default. The user has to take
// care about the filling of these list.

class PDecayManager : public TObject {

 private:

    Int_t       verbose;		// verbose flag (0/1)
    Double_t    CurrentWeight;		// weight of currently active reaction
    Int_t       CurrentReactionNumber;	// serial number of currently active reaction
  
    PNextList<PParticle>   *UsedParticles;	// collection of used particles to delete them later on
    PNextList<PParticle*>  *UsedParticleArrays; // same for particle arrays
    PNextList<PChannel>	   *UsedChannels;       // same for used channels
						 
    PNextList<PReactionList> *ReactionList;       // collection of all possible decay branches
    PNextList<PReactionList> *CurrentReactionListPointer; // pointer to the currently active decay branch
    PChannel        **ListForReaction;     // used for PReaction
    PReaction        *CurrentReaction;     // pointer to currently used PReaction
    Int_t             NumberOfReactions;   // nb of reactions in ReactionList

    Int_t             decaychannel_param;  // param for all known particle decay modes
    Bool_t            fHGeant;             // set if PLUTO runs in HGeant
    void*             userSelection;       // selection function 
    Int_t             nTrigCond;           // trigger multiplicity

    Bool_t            fWriteIndex;         // write parent indices out, if set

    TPythia6         *fPythia;            // pointer to Pythia object
 

    // ContructPChannel is used internally to construct a new PChannel from
    // parent particle *p and the decay channel *c1 and store it in the
    // ToDo stack of PReactionList *RL.
    // If CopyFlag is set, the particle *p is copied before using. This
    // is necessary for the top channel.
    void ConstructPChannel(PParticle *p, PDecayChannel *c1, 
			   PReactionList *RL, Int_t CopyFlag=0);
  
    // utility function for PrintReactionList
    void PrintReactionListEntry(PReactionList*, ostream &os) const;
    void PrintChain(PParticle *p, PChannel **l, Int_t c, ostream &os) const;

    // wrapper for PList.getName() to avoid error for composed 
    // particles
    using TObject::GetName;
    const char *GetName(Int_t id) const;
    Int_t maxFileSize;
    Float_t tauMax;

    PDistributionManager *pdist;

    int fileoutput_pos;
    PFileOutput *files[MAX_FILEOUTPUT];


    int bulkdecay_pos, pro_bulkdecay_pos;
    
    PBulkInterface *bulk[MAX_BULKDECAY];
    PBulkInterface *pro_bulk[MAX_BULKDECAY];
    PProjector *current_projector;



 public:
  
    PDecayManager();
    ~PDecayManager();

    void SetVerbose(Int_t v = 1);			// set verbose on/off 
  
    // add/assign/get a specific decay channel to one particle either by
    // particle id, by an instance of PParticle or just by name 
    void AddChannel(Int_t id,      PDecayChannel *n);
    void AddChannel(PParticle *p,  PDecayChannel *n);       
    void AddChannel(const char *p, PDecayChannel *n);       
    PDecayChannel *GetChannel(Int_t id) const;
    PDecayChannel *GetChannel(PParticle *p) const;    
    PDecayChannel *GetChannel(char *n) const;    
  
    // set the default decay channel for this particle (according to PDG)
    void SetDefault(Int_t id,      Int_t recursive=0);
    void SetDefault(PParticle *p,  Int_t recursive=0);       
    void SetDefault(const char *p, Int_t recursive=0);       

    // clear the channel
    void Clear(Int_t id);
    void Clear(PParticle *p);       
    void MyClear(char *);

    void Clear(const Option_t *delme=NULL) {
	if (delme) MyClear((char*) delme);
    };
    
       

    // by specifying one start particle InitReaction does look for all
    // possible decay chains and lists them in ReactionList. The initial
    // decay channel can be given either by a special decay channel or,
    // if it is a standard particle, the standard decay channel can be used.
    void InitReaction(PParticle *start, PDecayChannel *c1 = NULL);
  
    // GetNextReaction calls the constructor of PReaction for the next
    // reaction in ReactionList. The given parameters are forwarded
    // to the constructor. If wf is set, the weight stored in the reaction 
    // list is transfered to the initial particle; each reaction is simulated
    // with the same nb. of events, product particles have a proper weight set.
    // The second form is obsolete (and implies wf=0)
    PReaction *GetNextReaction(int wf, const char *name, int f0=0, int f1=0, 
			       int f2=0, int f3=0, TTree *tt=NULL);
    PReaction *GetNextReaction(const char *name, int f0=0, int f1=0, int f2=0, 
			       int f3=0, TTree *tt=NULL);
  
    // loop does a loop over all possible reaction channels and write
    // the output in a file name.root. The arguments are the same as
    // in GetNextReaction.
    Int_t Loop(int num, int wf, const char* name, int f0=0, 
	       int f1=0, int f2=0, int f3=0, int rf=0);
    Int_t loop(int num, int wf, const char* name, int f0=0, 
	       int f1=0, int f2=0, int f3=0, int rf=0) {
	return Loop(num, wf, name, f0, f1, f2, f3, rf);
    }

    // GetCurrentWeight provides the weight factor of the actual
    // reaction
    Double_t GetCurrentWeight();
  
    // prints out the decay channel list
    void Print(const Option_t *delme=NULL) const {
	if (delme && strlen(delme)) {
	    MyPrint((char*) delme);
	}
	else MyPrint();
    };

    void MyPrint() const;

    // print out information for one specific particle
    void Print(Int_t id) const;
    void Print(PParticle *p) const;
    void MyPrint(char *name) const;

    void SetHGeant(Int_t fH) {
	fHGeant = fH;
    }
    void SetUserSelection(void *f) {
	userSelection = f;
    }
    void SetUserSelection(Int_t (*f)(PParticle*)) {
	userSelection = (void*)f;
    }
    void SetTrigCond(Int_t n) {
	nTrigCond = n;
    }

    // visualize the decay chains
    void PrintReactionList() const;
  
    void SetPythia(TPythia6 *p) {
	fPythia = p;
    }
    void SetMaxFileSize(Int_t bytes) {
	maxFileSize = bytes;
    }
    void SetDecayAll(Float_t tau=1.) {
	tauMax = tau;
    }

    void DisableHelicityAngle(void) {
	pdist->Disable("helicity_angles");
    }
    PDistributionManager *GetDistributionManager(void) {
	return makeDistributionManager();
    }

    void SetWriteIndex(Bool_t flag) {
	fWriteIndex = flag;
    }

    Bool_t AddFileOutput(PFileOutput *file) {
	if (fileoutput_pos == MAX_FILEOUTPUT ) {
	    Warning("AddFileOutput", "MAX_FILEOUTPUT reached");
	    return kFALSE;
	}
	files[fileoutput_pos++] = file;
	return kTRUE;
    }

    //These interfaces are analogue to PReaction:
    Bool_t AddBulk(PBulkInterface *mybulk);
    Bool_t AddPrologueBulk(PBulkInterface *mybulk); //Bulk IO before any decay

    Bool_t Do(const char *command) {
	return GetCurrentProjector()->AddCommand(command);
    }
    Bool_t Do(TH1F *f, char *command) {
	return GetCurrentProjector()->AddHistogram(f, command);
    }
    Bool_t Do(TH2F *f, char *command) {
	return GetCurrentProjector()->AddHistogram(f, command);
    }
    Bool_t Output(TNtuple *f, char *command = (char *)"") {
	return GetCurrentProjector()->AddOutputTNtuple(f, command);
    }
    Bool_t Input(TNtuple *f) {
	return GetCurrentProjector()->AddInputTNtuple(f);
    }
    PProjector *GetCurrentProjector(void) {
	if (!bulkdecay_pos) {
	    current_projector = new PProjector();
	    AddBulk(current_projector);
	} else {
	    if (strcmp("PProjector", bulk[bulkdecay_pos-1]->GetName()) == 0) {
		current_projector = (PProjector *) bulk[bulkdecay_pos-1];
	    } else {
		current_projector = new PProjector();
		AddBulk(current_projector);
	    }
	}
	return current_projector;
    }

    ClassDef(PDecayManager,0)//Pluto Decay Manager Class

}; // end of class PDecayManager

#endif // _PDECAYLIST_H_









 PDecayManager.h:1
 PDecayManager.h:2
 PDecayManager.h:3
 PDecayManager.h:4
 PDecayManager.h:5
 PDecayManager.h:6
 PDecayManager.h:7
 PDecayManager.h:8
 PDecayManager.h:9
 PDecayManager.h:10
 PDecayManager.h:11
 PDecayManager.h:12
 PDecayManager.h:13
 PDecayManager.h:14
 PDecayManager.h:15
 PDecayManager.h:16
 PDecayManager.h:17
 PDecayManager.h:18
 PDecayManager.h:19
 PDecayManager.h:20
 PDecayManager.h:21
 PDecayManager.h:22
 PDecayManager.h:23
 PDecayManager.h:24
 PDecayManager.h:25
 PDecayManager.h:26
 PDecayManager.h:27
 PDecayManager.h:28
 PDecayManager.h:29
 PDecayManager.h:30
 PDecayManager.h:31
 PDecayManager.h:32
 PDecayManager.h:33
 PDecayManager.h:34
 PDecayManager.h:35
 PDecayManager.h:36
 PDecayManager.h:37
 PDecayManager.h:38
 PDecayManager.h:39
 PDecayManager.h:40
 PDecayManager.h:41
 PDecayManager.h:42
 PDecayManager.h:43
 PDecayManager.h:44
 PDecayManager.h:45
 PDecayManager.h:46
 PDecayManager.h:47
 PDecayManager.h:48
 PDecayManager.h:49
 PDecayManager.h:50
 PDecayManager.h:51
 PDecayManager.h:52
 PDecayManager.h:53
 PDecayManager.h:54
 PDecayManager.h:55
 PDecayManager.h:56
 PDecayManager.h:57
 PDecayManager.h:58
 PDecayManager.h:59
 PDecayManager.h:60
 PDecayManager.h:61
 PDecayManager.h:62
 PDecayManager.h:63
 PDecayManager.h:64
 PDecayManager.h:65
 PDecayManager.h:66
 PDecayManager.h:67
 PDecayManager.h:68
 PDecayManager.h:69
 PDecayManager.h:70
 PDecayManager.h:71
 PDecayManager.h:72
 PDecayManager.h:73
 PDecayManager.h:74
 PDecayManager.h:75
 PDecayManager.h:76
 PDecayManager.h:77
 PDecayManager.h:78
 PDecayManager.h:79
 PDecayManager.h:80
 PDecayManager.h:81
 PDecayManager.h:82
 PDecayManager.h:83
 PDecayManager.h:84
 PDecayManager.h:85
 PDecayManager.h:86
 PDecayManager.h:87
 PDecayManager.h:88
 PDecayManager.h:89
 PDecayManager.h:90
 PDecayManager.h:91
 PDecayManager.h:92
 PDecayManager.h:93
 PDecayManager.h:94
 PDecayManager.h:95
 PDecayManager.h:96
 PDecayManager.h:97
 PDecayManager.h:98
 PDecayManager.h:99
 PDecayManager.h:100
 PDecayManager.h:101
 PDecayManager.h:102
 PDecayManager.h:103
 PDecayManager.h:104
 PDecayManager.h:105
 PDecayManager.h:106
 PDecayManager.h:107
 PDecayManager.h:108
 PDecayManager.h:109
 PDecayManager.h:110
 PDecayManager.h:111
 PDecayManager.h:112
 PDecayManager.h:113
 PDecayManager.h:114
 PDecayManager.h:115
 PDecayManager.h:116
 PDecayManager.h:117
 PDecayManager.h:118
 PDecayManager.h:119
 PDecayManager.h:120
 PDecayManager.h:121
 PDecayManager.h:122
 PDecayManager.h:123
 PDecayManager.h:124
 PDecayManager.h:125
 PDecayManager.h:126
 PDecayManager.h:127
 PDecayManager.h:128
 PDecayManager.h:129
 PDecayManager.h:130
 PDecayManager.h:131
 PDecayManager.h:132
 PDecayManager.h:133
 PDecayManager.h:134
 PDecayManager.h:135
 PDecayManager.h:136
 PDecayManager.h:137
 PDecayManager.h:138
 PDecayManager.h:139
 PDecayManager.h:140
 PDecayManager.h:141
 PDecayManager.h:142
 PDecayManager.h:143
 PDecayManager.h:144
 PDecayManager.h:145
 PDecayManager.h:146
 PDecayManager.h:147
 PDecayManager.h:148
 PDecayManager.h:149
 PDecayManager.h:150
 PDecayManager.h:151
 PDecayManager.h:152
 PDecayManager.h:153
 PDecayManager.h:154
 PDecayManager.h:155
 PDecayManager.h:156
 PDecayManager.h:157
 PDecayManager.h:158
 PDecayManager.h:159
 PDecayManager.h:160
 PDecayManager.h:161
 PDecayManager.h:162
 PDecayManager.h:163
 PDecayManager.h:164
 PDecayManager.h:165
 PDecayManager.h:166
 PDecayManager.h:167
 PDecayManager.h:168
 PDecayManager.h:169
 PDecayManager.h:170
 PDecayManager.h:171
 PDecayManager.h:172
 PDecayManager.h:173
 PDecayManager.h:174
 PDecayManager.h:175
 PDecayManager.h:176
 PDecayManager.h:177
 PDecayManager.h:178
 PDecayManager.h:179
 PDecayManager.h:180
 PDecayManager.h:181
 PDecayManager.h:182
 PDecayManager.h:183
 PDecayManager.h:184
 PDecayManager.h:185
 PDecayManager.h:186
 PDecayManager.h:187
 PDecayManager.h:188
 PDecayManager.h:189
 PDecayManager.h:190
 PDecayManager.h:191
 PDecayManager.h:192
 PDecayManager.h:193
 PDecayManager.h:194
 PDecayManager.h:195
 PDecayManager.h:196
 PDecayManager.h:197
 PDecayManager.h:198
 PDecayManager.h:199
 PDecayManager.h:200
 PDecayManager.h:201
 PDecayManager.h:202
 PDecayManager.h:203
 PDecayManager.h:204
 PDecayManager.h:205
 PDecayManager.h:206
 PDecayManager.h:207
 PDecayManager.h:208
 PDecayManager.h:209
 PDecayManager.h:210
 PDecayManager.h:211
 PDecayManager.h:212
 PDecayManager.h:213
 PDecayManager.h:214
 PDecayManager.h:215
 PDecayManager.h:216
 PDecayManager.h:217
 PDecayManager.h:218
 PDecayManager.h:219
 PDecayManager.h:220
 PDecayManager.h:221
 PDecayManager.h:222
 PDecayManager.h:223
 PDecayManager.h:224
 PDecayManager.h:225
 PDecayManager.h:226
 PDecayManager.h:227
 PDecayManager.h:228
 PDecayManager.h:229
 PDecayManager.h:230
 PDecayManager.h:231
 PDecayManager.h:232
 PDecayManager.h:233
 PDecayManager.h:234
 PDecayManager.h:235
 PDecayManager.h:236
 PDecayManager.h:237
 PDecayManager.h:238
 PDecayManager.h:239
 PDecayManager.h:240
 PDecayManager.h:241
 PDecayManager.h:242
 PDecayManager.h:243
 PDecayManager.h:244
 PDecayManager.h:245
 PDecayManager.h:246
 PDecayManager.h:247
 PDecayManager.h:248
 PDecayManager.h:249
 PDecayManager.h:250
 PDecayManager.h:251
 PDecayManager.h:252
 PDecayManager.h:253
 PDecayManager.h:254
 PDecayManager.h:255
 PDecayManager.h:256
 PDecayManager.h:257
 PDecayManager.h:258
 PDecayManager.h:259
 PDecayManager.h:260
 PDecayManager.h:261
 PDecayManager.h:262
 PDecayManager.h:263
 PDecayManager.h:264
 PDecayManager.h:265
 PDecayManager.h:266
 PDecayManager.h:267
 PDecayManager.h:268
 PDecayManager.h:269
 PDecayManager.h:270
 PDecayManager.h:271
 PDecayManager.h:272
 PDecayManager.h:273
 PDecayManager.h:274
 PDecayManager.h:275
 PDecayManager.h:276
 PDecayManager.h:277
 PDecayManager.h:278
 PDecayManager.h:279
 PDecayManager.h:280
 PDecayManager.h:281
 PDecayManager.h:282
 PDecayManager.h:283
 PDecayManager.h:284
 PDecayManager.h:285
 PDecayManager.h:286
 PDecayManager.h:287
 PDecayManager.h:288
 PDecayManager.h:289
 PDecayManager.h:290
 PDecayManager.h:291
 PDecayManager.h:292
 PDecayManager.h:293
 PDecayManager.h:294
 PDecayManager.h:295
 PDecayManager.h:296
 PDecayManager.h:297
 PDecayManager.h:298
 PDecayManager.h:299
 PDecayManager.h:300
 PDecayManager.h:301
 PDecayManager.h:302
 PDecayManager.h:303
 PDecayManager.h:304
 PDecayManager.h:305
 PDecayManager.h:306
 PDecayManager.h:307
 PDecayManager.h:308
 PDecayManager.h:309
 PDecayManager.h:310
 PDecayManager.h:311
 PDecayManager.h:312
 PDecayManager.h:313
 PDecayManager.h:314
 PDecayManager.h:315
 PDecayManager.h:316
 PDecayManager.h:317
 PDecayManager.h:318
 PDecayManager.h:319
 PDecayManager.h:320
 PDecayManager.h:321
 PDecayManager.h:322
 PDecayManager.h:323
 PDecayManager.h:324
 PDecayManager.h:325
 PDecayManager.h:326
 PDecayManager.h:327
 PDecayManager.h:328
 PDecayManager.h:329
 PDecayManager.h:330
 PDecayManager.h:331
 PDecayManager.h:332
 PDecayManager.h:333
 PDecayManager.h:334
 PDecayManager.h:335
 PDecayManager.h:336
 PDecayManager.h:337
 PDecayManager.h:338
 PDecayManager.h:339
 PDecayManager.h:340
 PDecayManager.h:341
 PDecayManager.h:342
 PDecayManager.h:343
 PDecayManager.h:344
 PDecayManager.h:345
 PDecayManager.h:346
 PDecayManager.h:347
 PDecayManager.h:348
 PDecayManager.h:349
 PDecayManager.h:350
 PDecayManager.h:351
 PDecayManager.h:352
 PDecayManager.h:353
 PDecayManager.h:354
 PDecayManager.h:355
 PDecayManager.h:356
 PDecayManager.h:357
 PDecayManager.h:358
 PDecayManager.h:359
 PDecayManager.h:360
 PDecayManager.h:361
 PDecayManager.h:362
 PDecayManager.h:363
 PDecayManager.h:364
 PDecayManager.h:365
 PDecayManager.h:366
 PDecayManager.h:367
 PDecayManager.h:368
 PDecayManager.h:369
 PDecayManager.h:370
 PDecayManager.h:371
 PDecayManager.h:372
 PDecayManager.h:373
 PDecayManager.h:374
 PDecayManager.h:375
 PDecayManager.h:376
 PDecayManager.h:377
 PDecayManager.h:378
 PDecayManager.h:379
 PDecayManager.h:380
 PDecayManager.h:381
 PDecayManager.h:382
 PDecayManager.h:383
 PDecayManager.h:384
 PDecayManager.h:385
 PDecayManager.h:386
 PDecayManager.h:387
 PDecayManager.h:388
 PDecayManager.h:389
 PDecayManager.h:390
 PDecayManager.h:391
 PDecayManager.h:392
 PDecayManager.h:393
 PDecayManager.h:394
 PDecayManager.h:395
 PDecayManager.h:396
 PDecayManager.h:397
 PDecayManager.h:398
 PDecayManager.h:399
 PDecayManager.h:400