/////////////////////////////////////////////////////////////////////
//  Pluto Dynamic Data Wrapper
//
//  Provides wrapper functions to deal with coupled channel
//  calculations
//
//
//                             Author:  IF
//                             Written: 23.7.2007
//                             Revised: 
//
//////////////////////////////////////////////////////////////////////

#include "PDynamicData.h"
#include "PStdData.h"
#include "PUtils.h"
#include "TString.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "PDefines.h"


PDynamicData &fDynamicData() {
    static PDynamicData *ans = new PDynamicData();
    return *ans;
}

PDynamicData *makeDynamicData() {
    return &fDynamicData();
}

PDynamicData::PDynamicData() {
    
    PDataBase *base = makeDataBase();
    i_result = NULL;
    c_result = NULL;
    d_result = NULL;
    t_result = NULL;
    num_pchannels = 0;

    pid_param   = base->GetParamInt("pid");
    name_param  = base->GetParamString("name");
    model_param = base->GetParamTObj("model");
    didx_param  = base->GetParamInt("didx");
    scfactor_param = base->GetParamDouble("scfactor");
    sccount_param = base->GetParamInt("sccount");

    pnmodes_param = base->GetParamInt ("pnmodes");
    link_param    = base->GetParamInt ("link");

    enhance_br_param = base->GetParamDouble ("enhance_br");

    Info("PDynamicData()", "(%s)", PRINT_CTOR);
}

Double_t PDynamicData::GetDecayPartialWidth(Double_t mass, Int_t didx) {
    //returns the partial decay width of the decay channel "didx"
    //for a given "mass"
    //If no primary channel model has been found
    //return the static width
    Double_t width;

    //Check for threshold
    if (makeStaticData()->GetDecayEmin(didx) > mass) return 0;

    PChannelModel *model = GetDecayModel(didx);
    if (!model) {
	Error("GetDecayPartialWidth", "Model not found for decay index %i", didx);
	return makeStaticData()->GetDecayPartialWidth(didx);
    }
    Double_t scfactor = GetDecaySCFactor(didx);
    if (model->GetWidth(mass, &width)) return (width*scfactor);
    return makeStaticData()->GetDecayPartialWidth(didx)*scfactor;
}

double PDynamicData::GetParticleTotalWidthSum(Double_t mass, Int_t id, Int_t flag) {
    // Total decay width by pid & invariant mass (GeV/c^2).
    //
    // For most purposes GetParticleTotalWidth may be used for the total width.
    // GetParticleTotalWidthSum should be used instead only for sampling BR's.
    // Due to roundoff error in the interpolation, Width() returns a value
    // that differs slightly from the sum of the partial widths Width1().
    // As a result, small branching ratios (e.g. electromagnetic processes)
    // may never be sampled if Width() is used. For this reason, if a BR is 
    // requested, it is best to calculate the total width explicitly by 
    // summing the partial widths for any given mass.
    // 
    // flag=1: take into account only hadronic decays

    static double mo    = 0.;
    static double wt;
    static int io       = 0;
    static int old_flag = 0;

    if (!makeStaticData()->IsParticleValid(id)) { // pid out of range
	Warning("GetParticleTotalWidthSum", "id %i out of range", id);
	return 0.;
    }

    int twidx = makeStaticData()->GetTWidx(id);
    if (!twidx) GetParticleDepth(id);  // initialize indices on first call

    if (twidx == -1) {
	mo = mass;
	io = id;
	return wt = makeStaticData()->GetParticleTotalWidth(id);
	// static total width
    }
    
    if (io != id) {                        // parent id changed since last call
	io = id;
	mo = 0.;
    }

    if (mo!=mass || flag!=old_flag) {     // mass changed since last call
	mo = mass;
	old_flag = flag;
	if (mass<PData::LMass(id) || mass>PData::UMass(id)) 
	    return 0.;    // out of range

	double g_tmp = 0.;         // reset sums

	//now loop over decay modes
	Int_t key = makeDataBase()->GetEntryInt("pid", id);
	Int_t *didx;
	Int_t listkey = -1;
	while (makeDataBase()->MakeListIterator
	       (key, "pnmodes", "link", &listkey)) {
	    makeDataBase()->GetParamInt(listkey, "didx", &didx); //small workaround
	    if (makeStaticData()->GetPWidx(*didx) == -1
		&& mass >= makeStaticData()->GetDecayEmin(*didx)) 
		// if mode is unknown but kinematically accessible...
		g_tmp +=
		    makeStaticData()->GetDecayBR(*didx)*
		    makeStaticData()->GetParticleTotalWidth(id);
	    // ...update with the current static BR
	    else if (flag == 0) 
		g_tmp += GetDecayPartialWidth(mass, *didx);         
	    else if (makeStaticData()->IsDecayHadronic(*didx))
		g_tmp += GetDecayPartialWidth(mass, *didx);  
	    // otherwise, decay width of known mode
	}
	wt = g_tmp;          
    }

    return wt;
}

double PDynamicData::GetDecayBR(int idx, double m) {
    // returns branching ratio by mode index and mass (GeV/c^2)

    PChannelModel *model = GetDecayModel(idx);
    if (!model) {	
	return makeStaticData()->GetDecayBR(idx);
    }
    Double_t br;
    Double_t tw = GetParticleTotalWidth(m, makeStaticData()->GetDecayParent(idx));
    if (model->GetBR(m, &br, tw)) return br;
    return makeStaticData()->GetDecayBR(idx);

// 	return (wt>0.) ? wp/wt : 0.;
//->return (wt>0.) ? PBR[idx]*PWidth[id]/wt : 0.; <- alternative
}

void PDynamicData::ListDecayBR(int id, double m) {
    // list branching ratios of particle id for mass m
    
    if (!makeStaticData()->IsParticleValid(id)) {  // pid out of range
	return;
    }
    printf("\n%s branchings for mass=%f GeV   [low|pole|up|w|w0]=[%f|%f|%f|%e|%e] GeV\n\n",
	   makeStaticData()->GetParticleName(id), PData::LMass(id),
	   makeStaticData()->GetParticleMass(id),
	   makeStaticData()->GetParticleMass(id), PData::UMass(id),
	   makeStaticData()->GetParticleTotalWidth(id), GetParticleTotalWidthSum(m,id));
    if (m<PData::LMass(id) || m>PData::UMass(id)) { // mass out of range
	Warning("ListDecayBR", "mass out of range");
	return;
    }

    //now loop over decay modes
    Int_t key = makeDataBase()->GetEntryInt("pid", id);
    Int_t listkey = -1;
    int i = 1;

    double sum = 0;

    while (makeDataBase()->MakeListIterator
	   (key, "pnmodes", "link", &listkey)) {
	int   pos = makeStaticData()->GetDecayIdxByKey(listkey);
	double br = GetDecayBR(pos,m);  // compare with BR of current mode
	sum += br;
	double pw = GetDecayPartialWidth(m, pos);
	printf("%d: idx=%d sw=%2d  width=%e GeV    br=%f %%  (Width1()=%e)\n",
	       i, pos, makeStaticData()->GetPWidx(pos),
	       makeStaticData()->GetDecayPartialWidth(pos),
	       100.*br, pw);
	i++;
    }
    printf("\nTotal width=%e GeV   Sum(br)=%f %%\n", GetParticleTotalWidthSum(m,id), 100.*sum);
}

int PDynamicData::PickDecayChannel(const int &id, const double &m) {
    // returns the index of a decay mode for particle pid=id of mass m (GeV/c**2)
    // selected randomly, consistent with the branching ratios
    
    if (!makeStaticData()->IsParticleValid(id)) {
	// pid out of range
	Warning("PickDecayChannel","id %i out of range", id);
	return -1;
    } else if (m<PData::LMass(id) || m>PData::UMass(id)) return -2; // mass out of range
    
    int n = makeStaticData()->
	GetParticleNChannels(id); // number of channels available
    
    if (!n) return -3;                        // stable particle
    double r = PUtils::sampleFlat(), br = 0.; // pick a random number
    double sum = 0.;
    Int_t key = makeDataBase()->GetEntryInt(pid_param, id);
    Int_t *didx;
    Int_t listkey = -1;

    while (makeDataBase()->MakeListIterator
	   (key, pnmodes_param, link_param, &listkey)) {	
	makeDataBase()->GetParamInt 
	    (listkey, didx_param , &didx); //small workaround -> should work on keys
	sum+=GetDecayBR(*didx,m)*makeStaticData()->GetEnhanceChannelBR(*didx); // normalize first branching ratios
	//cout << "BR is " << GetDecayBR(*didx,m) << " for " << didx[0] << endl;
    }

    if (sum <= 0.) {
	Warning("PickDecayChannel", "sum=%f\n", sum);
	return -4;
    }
    listkey = -1;
    while (makeDataBase()->MakeListIterator(key, pnmodes_param, link_param,  &listkey)) {
	if (!makeDataBase()->GetParamInt(listkey, didx_param , &didx)) {
	    Warning("PickDecayChannel", "didx not found for listkey %i", listkey);
	}
	br += GetDecayBR(*didx,m)*makeStaticData()->GetEnhanceChannelBR(*didx);    // normalize first branching ratios
	if (r < br/sum) {
	    return *didx; // return selected index
	}
    }
    
    Warning("PickDecayChannel", "id=%d sum=%f\n", id, sum);
    return -5;
}

int PDynamicData::PickDecayChannel(const int &id, const double &m, int *array) {
    // returns the number and pids of the decay products for the decay 
    // of particle pid=id of mass m (GeV/c**2), via a mode selected
    // randomly, consistent with the branching ratios
    // In addition, it does not hurt to return the index (IF)

    if (!array) {  // invalid address of array
	Warning("PickDecayChannel", "Invalid address of array");
	return -1;
    } else if (!makeStaticData()->IsParticleValid(id)) {            
	// pid out of range
	Warning("PickDecayChannel", "id %i out of range", id);
	return -1;
    }
    
    array[0] = 0;  // failed to select an index
    Int_t p  = PickDecayChannel(id, m);
    array[0] = 10; //max 10 particles -> for the Mode() BUGBUG: Size of array not checked
    if (p >= 0) makeStaticData()->GetDecayMode(p, array); 
    // return number of products and pids
    return p;
}

Double_t PDynamicData::GetParticleScalingFactor(Int_t didx) {
    if (! makeDataBase()->GetParamDouble (pid_param, didx, scfactor_param, &d_result)) {
	return 1.;
    }
    return *d_result;
}

void PDynamicData::SetParticleScalingFactor(Int_t didx, Double_t factor) {
    if (! makeDataBase()->GetParamDouble (pid_param, didx, scfactor_param, &d_result)) {
	makeDataBase()->SetParamDouble (makeDataBase()->GetEntryInt(pid_param, didx) , "scfactor", new Double_t(factor));
	return;
    }
    *d_result *= factor;
}


Double_t PDynamicData::GetDecaySCFactor(Int_t didx) {
    if (! makeDataBase()->GetParamDouble (didx_param, didx, scfactor_param, &d_result)) {
	return 1.;
    }
    return *d_result;
}

void PDynamicData::SetDecaySCFactor(Int_t didx, Double_t factor) {
    if (! makeDataBase()->GetParamDouble (didx_param, didx, scfactor_param, &d_result)) {
	Warning("SetDecaySCFactor", "factor not present");
	return;
    }
    *d_result *= factor;
}

bool PDynamicData::CheckSCAbort(Int_t didx) {
    //to stop endless loops
    if (! makeDataBase()->GetParamInt (didx_param, didx , sccount_param, &i_result)) {
	makeDataBase()->SetParamInt (makeDataBase()->GetEntryInt(didx_param, didx) , 
				     "sccount", new Int_t(10)); //TODO:MAX_TRIES
	return kTRUE;
    }
    (*i_result)--;
    if (*i_result <= 0) return kFALSE;
    return kTRUE;
}

PChannelModel *PDynamicData::GetDecayModel(Int_t didx) {
    //returns the primary decay model
    if (! makeDataBase()->GetParamTObj (didx_param, didx, model_param, &t_result)) {
	return NULL;
    }
    return (PChannelModel *) t_result;
}

PChannelModel *PDynamicData::GetDecayModelByKey(Int_t key) {
    //returns the primary decay model
    if (! makeDataBase()->GetParamTObj (key, model_param, &t_result)) {
	return NULL;
    }
    return (PChannelModel *) t_result;
}

PChannelModel *PDynamicData::GetDecayModelByKey(Int_t key, Int_t defkey) {
    //returns the secondary decay model
    
    Int_t listkey = makeStaticData()->GetSecondaryKey(key, defkey);
    if (listkey<0) return NULL;

    if (makeDataBase()->GetParamTObj (listkey, model_param, &t_result)) {
	if ((((PChannelModel *) t_result) -> GetDef())  == defkey)
	    return (PChannelModel *) t_result;
	else {
	    Warning("GetDecayModelByKey", "Consistency check failed");
	    return NULL;
	}
    }
    return NULL;
}

PChannelModel *PDynamicData::GetParticleModel(Int_t pid) {
    //returns the primary particle model

    if (! makeDataBase()->GetParamTObj (pid_param, pid, model_param, &t_result)) {
	return NULL;
    }
    return (PChannelModel *) t_result;
}

PChannelModel *PDynamicData::GetParticleSecondaryModel(const char *name, 
						       const char *modelname) {
    Int_t sec_key = makeStaticData()->MakeDirectoryEntry("modeldef", NMODEL_NAME, LMODEL_NAME, modelname);
    if (sec_key < 0) 
	return NULL;

    Int_t primary_key = makeStaticData()->GetParticleKey(name);
    Int_t listkey = makeStaticData()->GetSecondaryKey(primary_key, sec_key);
    if (listkey < 0) 
	return NULL;

    Int_t model_param = makeDataBase()->GetParamTObj("model");
    TObject *t_result = NULL;
    if (makeDataBase()->GetParamTObj (listkey, model_param, &t_result)) {
	if ((((PChannelModel *) t_result) -> GetDef())  == sec_key)
	    return (PChannelModel *) t_result;
	else {
	    Warning("GetSecondaryModel", "Consistency check failed");
	    return NULL;
	}
    }
    return NULL;
}

Double_t PDynamicData::GetParticleTotalWidth(Double_t mass, Int_t pid) {
    //returns the particle width if a models exists, if not the static
    //width
    PChannelModel *model = GetParticleModel(pid);
    Double_t width;
    if (model) {
	if (model->GetWidth(mass, &width))
	    return width;
    }
    return makeStaticData()->GetParticleTotalWidth(pid);
}

Double_t PDynamicData::GetParticleTotalWeight(Double_t mass, Int_t pid, Int_t didx) {
    //return the mass-dependent width if a model exists
    //no mode: use the fixed Breit-Wigner with the total width
    
    PChannelModel *model = GetParticleModel(pid);

    if (model) {
	Double_t w = model->GetWeight(&mass, &didx);	
	if (w > 0) 
	    return w;
	return 0;
    }
    
    return 0; //BUGBUG make fixed BW here
}


bool PDynamicData::SetDecayModel(Int_t didx, PChannelModel *model) {
    Int_t key = makeDataBase()->GetEntryInt("didx", didx);
    if (! makeDataBase()->SetParamTObj (key, "model", (TObject *)model)) {
	return kFALSE;
    }   
    return kTRUE;
}

bool PDynamicData::SetDecayModelByKey(Int_t didx, PChannelModel *model) {

    if (! makeDataBase()->SetParamTObj (didx, "model", (TObject *)model)) {
	return kFALSE;
    }   
    return kTRUE;
}

double PDynamicData:: GetParticleLife(const int &id, double m, int idx) {
    // mean life
    // Arguments: 1. id=particle id 
    //            2. m=mass (GeV/c**2)
    //            3. idx=decay-mode index (PPosition)
    
    //CALLED FROM: PParticle, PReaction
    const long double hbar = 6.582122e-25;// (s GeV/c**2)

    double w0 = 
	makeStaticData()->GetParticleTotalWidth(
	    makeStaticData()->IsParticleValid(id)); // static total width
    if (id == 50 || 
	makeStaticData()->IsParticle(id,"dilepton")) {  
	// dilepton = virtual particle!
	if (w0 > 0.0) return hbar/w0;
	else if (m > 0.0) return hbar/m;
	else return 0.0;
    }

    double tau0 = (w0>0.) ? hbar/w0 : 1.e16; 
    // static total mean life (width=0 means stable!)
  
    if (m>0. && w0>0.) {  // unstable particle with non-zero mass
	if (idx == -1) {  // request for total mass-dependent mean life
	    double w = GetParticleTotalWidth(m,id);     // total mass-dependent width
	    if (w > 0.) 
		return hbar/w;  
            // total mass-dependent mean life, if non zero width
	} else {     // request for partial mass-dependent mean life
	    double w1 = GetDecayPartialWidth(m,idx);     
	    // partial mass-dependent width for decay via channel idx
	    if (w1 > 0.) 
		return hbar/w1;      
	    // partial mass-dependent mean life, if non zero partial width
	}
    }
    return tau0;   // if none of the above return the static mean life
}

int PDynamicData::GetParticleDepth(const int &id, int flag) {
    // Returns the total number of embedded recursive decays 
    // (TDepth if flag=0) or the number of embedded recursive
    // hadronic decays (HDepth if flag=1).
    // The default value 0 means the index has not been accessed yet.
    // Zero depth corresponds to index -1.
  
    if (makeStaticData()->IsParticleValid(id) == 0) {
	Warning("GetParticleDepth", "Particle id %i out of range", id);
	return 0;
    } else if (makeStaticData()->GetTDepth(id)) {
	return (flag) ? 
	    ((makeStaticData()->GetHDepth(id)!=-1) ? 
	     makeStaticData()->GetHDepth(id) : 0) :
	    ((makeStaticData()->GetTDepth(id)!=-1) ? 
	     makeStaticData()->GetTDepth(id) : 0);
    }
    // Enters once on the first call;
    // It also turns off the full-width (TWidx) and partial-width
    // indices (PWidx) for particles and decay modes, respectively,
    // if the total and partial widths are not calculated. In the 
    // latter case the static width and branching ratio are used.

    int n = makeStaticData()->GetParticleNChannels(id);
    
    if (!n) {                             // no decay modes
	makeStaticData()->SetTWidx(id,  -1);      // turn off total-width flag
	makeStaticData()->SetTDepth(id, -1);      // turn off total depth index
	makeStaticData()->SetHDepth(id, -1);      // turn off hadronic depth index
    } else { 
	int iter = 0, 
	    iter2 = 0;
	
	//now loop over decay modes
	Int_t key = makeDataBase()->GetEntryInt("pid", id);
	Int_t listkey = -1;
	
	Int_t tid[11];
	while (makeDataBase()->MakeListIterator
	       (key, "pnmodes", "link", &listkey)) {
	    tid[0] = 10; 
	    makeStaticData()->GetDecayModeByKey(listkey, tid); // retrieve current mode info
	    int pos = makeStaticData()->GetDecayIdxByKey(listkey);
	    //np=tid[0];

	    //Get primary model, --> question shifted to local
	    PChannelModel *model = GetDecayModel(pos);
	    if (!model) {
		Warning("GetParticleDepth", "pwidx -1");
		makeStaticData()->SetPWidx(pos, -1); //switch off
	    } else {
		iter  = TMath::Max(iter,  model->GetDepth()+1);
		iter2 = TMath::Max(iter2, model->GetDepth(1)+1);
	    }
	}

	if (!iter && !iter2)
	    makeStaticData()->SetTWidx(id, -1);// do not compute total width
	makeStaticData()->SetTDepth(id, (iter)?iter:-1);          // store total depth
	makeStaticData()->SetHDepth(id, (iter2)?iter2:-1);        // store hadronic depth
    }
    return (flag) ? 
	((makeStaticData()->GetHDepth(id)!=-1) ? 
	 makeStaticData()->GetHDepth(id) : 0) :
	((makeStaticData()->GetTDepth(id)!=-1) ? 
	 makeStaticData()->GetTDepth(id) : 0);
}

void  PDynamicData::PrintParticle(int pid) {
    return PrintParticleByKey(makeDataBase()->GetEntryInt("pid", pid));
};

void  PDynamicData::PrintParticleByKey(int key) {
    makeDataBase()->ListEntries(key, 0, "name,pid");

    if (!makeStaticData()->GetParticleNChannelsByKey(key)) {
	cout << "This particle is stable" << endl;
	return;
    }

    PChannelModel *m = GetParticleModel(makeStaticData()->GetParticleIDByKey(key));

    if (m) m->Print();
    else cout << "<No particle model defined>" << endl;

    cout << "This particle decays via the following modes:" << endl;

    //now loop over decay modes
    Int_t listkey = -1;

    while (makeDataBase()->MakeListIterator(key, "pnmodes", "link", &listkey)) {
	PrintDecayByKey(listkey);
	m=GetDecayModelByKey(listkey);
	if (m) m->Print();
	    //m->Dump();
    }
};

void PDynamicData::PrintDecayByKey(int key) {
    makeDataBase()->ListEntries(key, 0, "name,didx");
};

PParticle *PDynamicData::GetBatchParticle(const char *name, Int_t make_val) {
    Int_t key_a = makeStaticData()->MakeDirectoryEntry("batch_objects", NBATCH_NAME, LBATCH_NAME, name);

    TObject *ret;
    Int_t batch_particle_param = makeDataBase()->GetParamTObj("batch_particle");
    if (batch_particle_param < 0) 
	batch_particle_param = makeDataBase()->MakeParamTObj("batch_particle", "PParticle storage for batch");

    if (!makeDataBase()->GetParamTObj(key_a ,batch_particle_param,&ret)) {
	if (make_val) {
	    PParticle *delme =  new PParticle("dummy", 0);
	    makeDataBase()->SetParamTObj(key_a, "batch_particle", delme);
	    return delme;
	} else return NULL;
    }
    return (PParticle *)ret;
};

TH1 *PDynamicData::GetBatchHistogram(const char *name) {
    Int_t key_a = makeStaticData()->MakeDirectoryEntry("batch_objects", NBATCH_NAME, LBATCH_NAME, name);

    TObject *ret;
    Int_t batch_histogram_param = makeDataBase()->GetParamTObj("batch_histogram");
    if (batch_histogram_param < 0) 
	batch_histogram_param = makeDataBase()->MakeParamTObj("batch_histogram", "Histogram storage for batch");

    if (!makeDataBase()->GetParamTObj(key_a, batch_histogram_param, &ret)) {
	return NULL;
    }
    return (TH1 *)ret;
};

Bool_t PDynamicData::SetBatchHistogram(const char *name, TH1 *histo) {
    Int_t key_a = makeStaticData()->MakeDirectoryEntry("batch_objects", NBATCH_NAME, LBATCH_NAME, name);
    
    Int_t batch_histogram_param = makeDataBase()->GetParamTObj("batch_histogram");
    if (batch_histogram_param < 0) 
	batch_histogram_param = makeDataBase()->MakeParamTObj("batch_histogram", "Histogram storage for batch");
   
    return makeDataBase()->SetParamTObj(key_a, "batch_histogram", histo);
};


ClassImp(PDynamicData)
 PDynamicData.cc:1
 PDynamicData.cc:2
 PDynamicData.cc:3
 PDynamicData.cc:4
 PDynamicData.cc:5
 PDynamicData.cc:6
 PDynamicData.cc:7
 PDynamicData.cc:8
 PDynamicData.cc:9
 PDynamicData.cc:10
 PDynamicData.cc:11
 PDynamicData.cc:12
 PDynamicData.cc:13
 PDynamicData.cc:14
 PDynamicData.cc:15
 PDynamicData.cc:16
 PDynamicData.cc:17
 PDynamicData.cc:18
 PDynamicData.cc:19
 PDynamicData.cc:20
 PDynamicData.cc:21
 PDynamicData.cc:22
 PDynamicData.cc:23
 PDynamicData.cc:24
 PDynamicData.cc:25
 PDynamicData.cc:26
 PDynamicData.cc:27
 PDynamicData.cc:28
 PDynamicData.cc:29
 PDynamicData.cc:30
 PDynamicData.cc:31
 PDynamicData.cc:32
 PDynamicData.cc:33
 PDynamicData.cc:34
 PDynamicData.cc:35
 PDynamicData.cc:36
 PDynamicData.cc:37
 PDynamicData.cc:38
 PDynamicData.cc:39
 PDynamicData.cc:40
 PDynamicData.cc:41
 PDynamicData.cc:42
 PDynamicData.cc:43
 PDynamicData.cc:44
 PDynamicData.cc:45
 PDynamicData.cc:46
 PDynamicData.cc:47
 PDynamicData.cc:48
 PDynamicData.cc:49
 PDynamicData.cc:50
 PDynamicData.cc:51
 PDynamicData.cc:52
 PDynamicData.cc:53
 PDynamicData.cc:54
 PDynamicData.cc:55
 PDynamicData.cc:56
 PDynamicData.cc:57
 PDynamicData.cc:58
 PDynamicData.cc:59
 PDynamicData.cc:60
 PDynamicData.cc:61
 PDynamicData.cc:62
 PDynamicData.cc:63
 PDynamicData.cc:64
 PDynamicData.cc:65
 PDynamicData.cc:66
 PDynamicData.cc:67
 PDynamicData.cc:68
 PDynamicData.cc:69
 PDynamicData.cc:70
 PDynamicData.cc:71
 PDynamicData.cc:72
 PDynamicData.cc:73
 PDynamicData.cc:74
 PDynamicData.cc:75
 PDynamicData.cc:76
 PDynamicData.cc:77
 PDynamicData.cc:78
 PDynamicData.cc:79
 PDynamicData.cc:80
 PDynamicData.cc:81
 PDynamicData.cc:82
 PDynamicData.cc:83
 PDynamicData.cc:84
 PDynamicData.cc:85
 PDynamicData.cc:86
 PDynamicData.cc:87
 PDynamicData.cc:88
 PDynamicData.cc:89
 PDynamicData.cc:90
 PDynamicData.cc:91
 PDynamicData.cc:92
 PDynamicData.cc:93
 PDynamicData.cc:94
 PDynamicData.cc:95
 PDynamicData.cc:96
 PDynamicData.cc:97
 PDynamicData.cc:98
 PDynamicData.cc:99
 PDynamicData.cc:100
 PDynamicData.cc:101
 PDynamicData.cc:102
 PDynamicData.cc:103
 PDynamicData.cc:104
 PDynamicData.cc:105
 PDynamicData.cc:106
 PDynamicData.cc:107
 PDynamicData.cc:108
 PDynamicData.cc:109
 PDynamicData.cc:110
 PDynamicData.cc:111
 PDynamicData.cc:112
 PDynamicData.cc:113
 PDynamicData.cc:114
 PDynamicData.cc:115
 PDynamicData.cc:116
 PDynamicData.cc:117
 PDynamicData.cc:118
 PDynamicData.cc:119
 PDynamicData.cc:120
 PDynamicData.cc:121
 PDynamicData.cc:122
 PDynamicData.cc:123
 PDynamicData.cc:124
 PDynamicData.cc:125
 PDynamicData.cc:126
 PDynamicData.cc:127
 PDynamicData.cc:128
 PDynamicData.cc:129
 PDynamicData.cc:130
 PDynamicData.cc:131
 PDynamicData.cc:132
 PDynamicData.cc:133
 PDynamicData.cc:134
 PDynamicData.cc:135
 PDynamicData.cc:136
 PDynamicData.cc:137
 PDynamicData.cc:138
 PDynamicData.cc:139
 PDynamicData.cc:140
 PDynamicData.cc:141
 PDynamicData.cc:142
 PDynamicData.cc:143
 PDynamicData.cc:144
 PDynamicData.cc:145
 PDynamicData.cc:146
 PDynamicData.cc:147
 PDynamicData.cc:148
 PDynamicData.cc:149
 PDynamicData.cc:150
 PDynamicData.cc:151
 PDynamicData.cc:152
 PDynamicData.cc:153
 PDynamicData.cc:154
 PDynamicData.cc:155
 PDynamicData.cc:156
 PDynamicData.cc:157
 PDynamicData.cc:158
 PDynamicData.cc:159
 PDynamicData.cc:160
 PDynamicData.cc:161
 PDynamicData.cc:162
 PDynamicData.cc:163
 PDynamicData.cc:164
 PDynamicData.cc:165
 PDynamicData.cc:166
 PDynamicData.cc:167
 PDynamicData.cc:168
 PDynamicData.cc:169
 PDynamicData.cc:170
 PDynamicData.cc:171
 PDynamicData.cc:172
 PDynamicData.cc:173
 PDynamicData.cc:174
 PDynamicData.cc:175
 PDynamicData.cc:176
 PDynamicData.cc:177
 PDynamicData.cc:178
 PDynamicData.cc:179
 PDynamicData.cc:180
 PDynamicData.cc:181
 PDynamicData.cc:182
 PDynamicData.cc:183
 PDynamicData.cc:184
 PDynamicData.cc:185
 PDynamicData.cc:186
 PDynamicData.cc:187
 PDynamicData.cc:188
 PDynamicData.cc:189
 PDynamicData.cc:190
 PDynamicData.cc:191
 PDynamicData.cc:192
 PDynamicData.cc:193
 PDynamicData.cc:194
 PDynamicData.cc:195
 PDynamicData.cc:196
 PDynamicData.cc:197
 PDynamicData.cc:198
 PDynamicData.cc:199
 PDynamicData.cc:200
 PDynamicData.cc:201
 PDynamicData.cc:202
 PDynamicData.cc:203
 PDynamicData.cc:204
 PDynamicData.cc:205
 PDynamicData.cc:206
 PDynamicData.cc:207
 PDynamicData.cc:208
 PDynamicData.cc:209
 PDynamicData.cc:210
 PDynamicData.cc:211
 PDynamicData.cc:212
 PDynamicData.cc:213
 PDynamicData.cc:214
 PDynamicData.cc:215
 PDynamicData.cc:216
 PDynamicData.cc:217
 PDynamicData.cc:218
 PDynamicData.cc:219
 PDynamicData.cc:220
 PDynamicData.cc:221
 PDynamicData.cc:222
 PDynamicData.cc:223
 PDynamicData.cc:224
 PDynamicData.cc:225
 PDynamicData.cc:226
 PDynamicData.cc:227
 PDynamicData.cc:228
 PDynamicData.cc:229
 PDynamicData.cc:230
 PDynamicData.cc:231
 PDynamicData.cc:232
 PDynamicData.cc:233
 PDynamicData.cc:234
 PDynamicData.cc:235
 PDynamicData.cc:236
 PDynamicData.cc:237
 PDynamicData.cc:238
 PDynamicData.cc:239
 PDynamicData.cc:240
 PDynamicData.cc:241
 PDynamicData.cc:242
 PDynamicData.cc:243
 PDynamicData.cc:244
 PDynamicData.cc:245
 PDynamicData.cc:246
 PDynamicData.cc:247
 PDynamicData.cc:248
 PDynamicData.cc:249
 PDynamicData.cc:250
 PDynamicData.cc:251
 PDynamicData.cc:252
 PDynamicData.cc:253
 PDynamicData.cc:254
 PDynamicData.cc:255
 PDynamicData.cc:256
 PDynamicData.cc:257
 PDynamicData.cc:258
 PDynamicData.cc:259
 PDynamicData.cc:260
 PDynamicData.cc:261
 PDynamicData.cc:262
 PDynamicData.cc:263
 PDynamicData.cc:264
 PDynamicData.cc:265
 PDynamicData.cc:266
 PDynamicData.cc:267
 PDynamicData.cc:268
 PDynamicData.cc:269
 PDynamicData.cc:270
 PDynamicData.cc:271
 PDynamicData.cc:272
 PDynamicData.cc:273
 PDynamicData.cc:274
 PDynamicData.cc:275
 PDynamicData.cc:276
 PDynamicData.cc:277
 PDynamicData.cc:278
 PDynamicData.cc:279
 PDynamicData.cc:280
 PDynamicData.cc:281
 PDynamicData.cc:282
 PDynamicData.cc:283
 PDynamicData.cc:284
 PDynamicData.cc:285
 PDynamicData.cc:286
 PDynamicData.cc:287
 PDynamicData.cc:288
 PDynamicData.cc:289
 PDynamicData.cc:290
 PDynamicData.cc:291
 PDynamicData.cc:292
 PDynamicData.cc:293
 PDynamicData.cc:294
 PDynamicData.cc:295
 PDynamicData.cc:296
 PDynamicData.cc:297
 PDynamicData.cc:298
 PDynamicData.cc:299
 PDynamicData.cc:300
 PDynamicData.cc:301
 PDynamicData.cc:302
 PDynamicData.cc:303
 PDynamicData.cc:304
 PDynamicData.cc:305
 PDynamicData.cc:306
 PDynamicData.cc:307
 PDynamicData.cc:308
 PDynamicData.cc:309
 PDynamicData.cc:310
 PDynamicData.cc:311
 PDynamicData.cc:312
 PDynamicData.cc:313
 PDynamicData.cc:314
 PDynamicData.cc:315
 PDynamicData.cc:316
 PDynamicData.cc:317
 PDynamicData.cc:318
 PDynamicData.cc:319
 PDynamicData.cc:320
 PDynamicData.cc:321
 PDynamicData.cc:322
 PDynamicData.cc:323
 PDynamicData.cc:324
 PDynamicData.cc:325
 PDynamicData.cc:326
 PDynamicData.cc:327
 PDynamicData.cc:328
 PDynamicData.cc:329
 PDynamicData.cc:330
 PDynamicData.cc:331
 PDynamicData.cc:332
 PDynamicData.cc:333
 PDynamicData.cc:334
 PDynamicData.cc:335
 PDynamicData.cc:336
 PDynamicData.cc:337
 PDynamicData.cc:338
 PDynamicData.cc:339
 PDynamicData.cc:340
 PDynamicData.cc:341
 PDynamicData.cc:342
 PDynamicData.cc:343
 PDynamicData.cc:344
 PDynamicData.cc:345
 PDynamicData.cc:346
 PDynamicData.cc:347
 PDynamicData.cc:348
 PDynamicData.cc:349
 PDynamicData.cc:350
 PDynamicData.cc:351
 PDynamicData.cc:352
 PDynamicData.cc:353
 PDynamicData.cc:354
 PDynamicData.cc:355
 PDynamicData.cc:356
 PDynamicData.cc:357
 PDynamicData.cc:358
 PDynamicData.cc:359
 PDynamicData.cc:360
 PDynamicData.cc:361
 PDynamicData.cc:362
 PDynamicData.cc:363
 PDynamicData.cc:364
 PDynamicData.cc:365
 PDynamicData.cc:366
 PDynamicData.cc:367
 PDynamicData.cc:368
 PDynamicData.cc:369
 PDynamicData.cc:370
 PDynamicData.cc:371
 PDynamicData.cc:372
 PDynamicData.cc:373
 PDynamicData.cc:374
 PDynamicData.cc:375
 PDynamicData.cc:376
 PDynamicData.cc:377
 PDynamicData.cc:378
 PDynamicData.cc:379
 PDynamicData.cc:380
 PDynamicData.cc:381
 PDynamicData.cc:382
 PDynamicData.cc:383
 PDynamicData.cc:384
 PDynamicData.cc:385
 PDynamicData.cc:386
 PDynamicData.cc:387
 PDynamicData.cc:388
 PDynamicData.cc:389
 PDynamicData.cc:390
 PDynamicData.cc:391
 PDynamicData.cc:392
 PDynamicData.cc:393
 PDynamicData.cc:394
 PDynamicData.cc:395
 PDynamicData.cc:396
 PDynamicData.cc:397
 PDynamicData.cc:398
 PDynamicData.cc:399
 PDynamicData.cc:400
 PDynamicData.cc:401
 PDynamicData.cc:402
 PDynamicData.cc:403
 PDynamicData.cc:404
 PDynamicData.cc:405
 PDynamicData.cc:406
 PDynamicData.cc:407
 PDynamicData.cc:408
 PDynamicData.cc:409
 PDynamicData.cc:410
 PDynamicData.cc:411
 PDynamicData.cc:412
 PDynamicData.cc:413
 PDynamicData.cc:414
 PDynamicData.cc:415
 PDynamicData.cc:416
 PDynamicData.cc:417
 PDynamicData.cc:418
 PDynamicData.cc:419
 PDynamicData.cc:420
 PDynamicData.cc:421
 PDynamicData.cc:422
 PDynamicData.cc:423
 PDynamicData.cc:424
 PDynamicData.cc:425
 PDynamicData.cc:426
 PDynamicData.cc:427
 PDynamicData.cc:428
 PDynamicData.cc:429
 PDynamicData.cc:430
 PDynamicData.cc:431
 PDynamicData.cc:432
 PDynamicData.cc:433
 PDynamicData.cc:434
 PDynamicData.cc:435
 PDynamicData.cc:436
 PDynamicData.cc:437
 PDynamicData.cc:438
 PDynamicData.cc:439
 PDynamicData.cc:440
 PDynamicData.cc:441
 PDynamicData.cc:442
 PDynamicData.cc:443
 PDynamicData.cc:444
 PDynamicData.cc:445
 PDynamicData.cc:446
 PDynamicData.cc:447
 PDynamicData.cc:448
 PDynamicData.cc:449
 PDynamicData.cc:450
 PDynamicData.cc:451
 PDynamicData.cc:452
 PDynamicData.cc:453
 PDynamicData.cc:454
 PDynamicData.cc:455
 PDynamicData.cc:456
 PDynamicData.cc:457
 PDynamicData.cc:458
 PDynamicData.cc:459
 PDynamicData.cc:460
 PDynamicData.cc:461
 PDynamicData.cc:462
 PDynamicData.cc:463
 PDynamicData.cc:464
 PDynamicData.cc:465
 PDynamicData.cc:466
 PDynamicData.cc:467
 PDynamicData.cc:468
 PDynamicData.cc:469
 PDynamicData.cc:470
 PDynamicData.cc:471
 PDynamicData.cc:472
 PDynamicData.cc:473
 PDynamicData.cc:474
 PDynamicData.cc:475
 PDynamicData.cc:476
 PDynamicData.cc:477
 PDynamicData.cc:478
 PDynamicData.cc:479
 PDynamicData.cc:480
 PDynamicData.cc:481
 PDynamicData.cc:482
 PDynamicData.cc:483
 PDynamicData.cc:484
 PDynamicData.cc:485
 PDynamicData.cc:486
 PDynamicData.cc:487
 PDynamicData.cc:488
 PDynamicData.cc:489
 PDynamicData.cc:490
 PDynamicData.cc:491
 PDynamicData.cc:492
 PDynamicData.cc:493
 PDynamicData.cc:494
 PDynamicData.cc:495
 PDynamicData.cc:496
 PDynamicData.cc:497
 PDynamicData.cc:498
 PDynamicData.cc:499
 PDynamicData.cc:500
 PDynamicData.cc:501
 PDynamicData.cc:502
 PDynamicData.cc:503
 PDynamicData.cc:504
 PDynamicData.cc:505
 PDynamicData.cc:506
 PDynamicData.cc:507
 PDynamicData.cc:508
 PDynamicData.cc:509
 PDynamicData.cc:510
 PDynamicData.cc:511
 PDynamicData.cc:512
 PDynamicData.cc:513
 PDynamicData.cc:514
 PDynamicData.cc:515
 PDynamicData.cc:516
 PDynamicData.cc:517
 PDynamicData.cc:518
 PDynamicData.cc:519
 PDynamicData.cc:520
 PDynamicData.cc:521
 PDynamicData.cc:522
 PDynamicData.cc:523
 PDynamicData.cc:524
 PDynamicData.cc:525
 PDynamicData.cc:526
 PDynamicData.cc:527
 PDynamicData.cc:528
 PDynamicData.cc:529
 PDynamicData.cc:530
 PDynamicData.cc:531
 PDynamicData.cc:532
 PDynamicData.cc:533
 PDynamicData.cc:534
 PDynamicData.cc:535
 PDynamicData.cc:536
 PDynamicData.cc:537
 PDynamicData.cc:538
 PDynamicData.cc:539
 PDynamicData.cc:540
 PDynamicData.cc:541
 PDynamicData.cc:542
 PDynamicData.cc:543
 PDynamicData.cc:544
 PDynamicData.cc:545
 PDynamicData.cc:546
 PDynamicData.cc:547
 PDynamicData.cc:548
 PDynamicData.cc:549
 PDynamicData.cc:550
 PDynamicData.cc:551
 PDynamicData.cc:552
 PDynamicData.cc:553
 PDynamicData.cc:554
 PDynamicData.cc:555
 PDynamicData.cc:556
 PDynamicData.cc:557
 PDynamicData.cc:558
 PDynamicData.cc:559
 PDynamicData.cc:560
 PDynamicData.cc:561
 PDynamicData.cc:562
 PDynamicData.cc:563
 PDynamicData.cc:564
 PDynamicData.cc:565
 PDynamicData.cc:566
 PDynamicData.cc:567
 PDynamicData.cc:568
 PDynamicData.cc:569
 PDynamicData.cc:570
 PDynamicData.cc:571
 PDynamicData.cc:572
 PDynamicData.cc:573
 PDynamicData.cc:574
 PDynamicData.cc:575
 PDynamicData.cc:576
 PDynamicData.cc:577
 PDynamicData.cc:578
 PDynamicData.cc:579
 PDynamicData.cc:580
 PDynamicData.cc:581
 PDynamicData.cc:582
 PDynamicData.cc:583
 PDynamicData.cc:584
 PDynamicData.cc:585
 PDynamicData.cc:586
 PDynamicData.cc:587
 PDynamicData.cc:588
 PDynamicData.cc:589
 PDynamicData.cc:590
 PDynamicData.cc:591
 PDynamicData.cc:592
 PDynamicData.cc:593
 PDynamicData.cc:594
 PDynamicData.cc:595
 PDynamicData.cc:596
 PDynamicData.cc:597
 PDynamicData.cc:598
 PDynamicData.cc:599
 PDynamicData.cc:600
 PDynamicData.cc:601
 PDynamicData.cc:602
 PDynamicData.cc:603
 PDynamicData.cc:604
 PDynamicData.cc:605
 PDynamicData.cc:606
 PDynamicData.cc:607
 PDynamicData.cc:608
 PDynamicData.cc:609
 PDynamicData.cc:610
 PDynamicData.cc:611
 PDynamicData.cc:612