PearsonIV::PearsonIV() :Component() { this->setname("Pearson IV"); this->setdescription("Pearson IV peak (model for ZL peak)"); setshifter(false); }
Lorentz::Lorentz() :Component() { this->setname("Lorentz"); this->setdescription("Lorentz peak with given height,position and FWHM"); setshifter(false); }
Mscatter::Mscatter() :Component(),LLspectrum() { this->setname("Multiple scattering (matrix convolution)"); this->setdescription("Convolution of the HL spectrum with LL using matrix convolution.\nThis simulates the effect of multiple scattering\nwhich is an important effect in experimental spectra "); this->setcanconvolute(false); //meaningless in this case this->setconvolutor(true); //makes this a special component! setshifter(false); }
Plasmon::Plasmon() //create a dummy version :Component() { this->setname("Plasmon model"); this->setdescription("A model of a lorentzian ZL peak and a set of lorentzian plasmon peaks"); nrofplasmons=0; setcanconvolute(true); setshifter(false); }
DosLifetimeSpline::DosLifetimeSpline() //create a dummy version :Component(),Evector(),Yvector(),b(),c(),d() { dummy=0; compptr=0; this->setname("Fine Structure (DOS) with lifetime (cubic spline)"); this->setdescription("Fine Structure used in combination with a normal cross-section using Lifetime broadening as an extra prior knowledge"); degree=0; setcanconvolute(true); setshifter(false); set_ismultiplier(true); acc=0; sp=0; Plotspec=0; }
Lorentz::Lorentz(int n,double estart,double dispersion,std::vector<Parameter*>* parameterlistptr) :Component(n,estart,dispersion) { //add the required parameters Parameter* p1; Parameter* p2; Parameter* p3; if (parameterlistptr==0) { p1=new Parameter("Emax",estart,1); p1->interactivevalue("enter position"); p2=new Parameter("FWHM",10*dispersion,1); p2->interactivevalue("enter FWHM"); p3=new Parameter("Height",1.0e3,1); p3->interactivevalue("enter height"); } else { p1=(*parameterlistptr)[0]; p2=(*parameterlistptr)[1]; p3=(*parameterlistptr)[2]; } //Height is a linear parameter p3->setlinear(true); this->addparameter(p1); this->addparameter(p2); this->addparameter(p3); //give a name and description this->setname("Lorentz"); this->setdescription("Lorentz peak with given height,position and FWHM"); this->setcanconvolute(true); //all three parameters have an analytical gradient this->sethasgradient(0,true); this->sethasgradient(1,true); this->sethasgradient(2,true); setshifter(false); //seems to be really important here }
Lorentz::Lorentz(int n,double estart,double dispersion,double epeak,double fwhm,double height) :Component(n,estart,dispersion) { //add the required parameters Parameter* p1; Parameter* p2; Parameter* p3; p1=new Parameter("Emax",epeak,1); p2=new Parameter("FWHM",fwhm,1); p3=new Parameter("Height",height,1); this->addparameter(p1); this->addparameter(p2); this->addparameter(p3); //give a name and description this->setname("Lorentz"); this->setdescription("Lorentz peak with given height,position and FWHM"); this->setcanconvolute(true); //all three parameters have an analytical gradient this->sethasgradient(0,true); this->sethasgradient(1,true); this->sethasgradient(2,true); setshifter(false); }
DosLifetimeSpline::DosLifetimeSpline(int n,double estart,double dispersion,std::vector<Parameter*>* parameterlistptr) :Component(n,estart,dispersion),Evector(),Yvector(),b(),c(),d() { broadeningtype=QUADRATIC; //offset=2; offset=2; //create spectrum with same energy scale as this dummy=new Spectrum(n,estart,dispersion); Plotspec=0; compptr=0; if (parameterlistptr==0){ //ask for the degree of the polynomial between 1 and 100 const int min=1; const int max=1024; int d=10; Integerinput myinput(0,"","enter number of points",d,min,max); degree=size_t(d); //enter Estart and Estop Parameter* p1=new Parameter("Estart",estart,1); p1->interactivevalue("Enter Estart"); p1->setchangeable(false); this->addparameter(p1); Parameter* p2=new Parameter("Estop",estart,1); p2->interactivevalue("Enter Estop"); p2->setchangeable(false); this->addparameter(p2); //atomic to calculate the lifetime broadening Parameter* p3=new Parameter("a",0.4,1); //choose between different types of broadening int broadtype=0; Integerinput* myask=new Integerinput(0, "Lifetime broadening selector","1=Lin.,2=Quadr.,3=Egert.",broadtype,1,3); (void) myask; switch(broadtype){ case 1: p3->setname("Linear coefficient"); break; case 2: p3->setname("Quadratic coefficient"); break; case 3: p3->setname("Egerton Broadening atomic distance [nm]"); break; default: break; } p3->setboundaries(0,10.0); p3->interactivevalue("Enter broadening coefficient (0.0 for linear scale)"); p3->setchangeable(false); this->addparameter(p3); //do we want linear or lifetime optimised energy points linear=false; if ((p3->getvalue())==0.0){ //only for linear scale we need Estop //for lieftime broadening Estop is calculated by initenergy linear=true; } for (size_t i=0;i<degree;i++){ std::string name; std::ostringstream s; if ((s << "a"<< i)){ //converting an int to a string in c++ style rather than unsafe c-style // conversion worked name=s.str(); } //store parameters to hold the strengths of the basis set L Parameter* p=new Parameter(name,1.0,1); p->setboundaries(-1.0,10.0); //copy this parameter this->addparameter(p); } //now link this to a cross section which needs to be multiplied Model* mymodel=geteelsmodelptr()->getmodel_nonconst(); int cnr=0; //create a componentselector here Componentselector myinput2(0,"","Select the component you want to multiply with",cnr); //get a pointer to this component and tell it that we are his multiplier compptr=mymodel->getcomponent(cnr); set_ismultiplier(true);//important do it here, otherwise multiplierptr is not accepted if (compptr!=0){ compptr->setmultiplierptr(this); } else{ //something went wrong Saysomething mysay(0,"Error","the component didn't appear to be valid"); throw Componenterr::unable_to_create(); } //save this number in a parameter Parameter* p5=new Parameter("compnr",cnr,1); p5->setchangeable(false); this->addparameter(p5); } else{ //get parameters from a list for (size_t i=0;i<(parameterlistptr->size());i++){ Parameter* p=(*parameterlistptr)[i]; this->addparameter(p); } degree=(parameterlistptr->size())-4;//there are 4 other parameters //tell the component that we multiply that we are here Parameter* p5=(*parameterlistptr)[parameterlistptr->size()-1]; Model* mymodel=geteelsmodelptr()->getmodel_nonconst(); const int cnr=int(p5->getvalue()); //get a pointer to this component and tell it that we are his multiplier compptr=mymodel->getcomponent(cnr); set_ismultiplier(true);//important do it here, otherwise multiplierptr is not accepted if (compptr!=0) { compptr->setmultiplierptr(this); } #ifdef COMPONENT_DEBUG std::cout <<"After linking to the cross section\n"; #endif } //end of else #ifdef COMPONENT_DEBUG std::cout <<"Setting the names etc\n"; #endif //give a name and description setname("Fine Structure (DOS) with lifetime (cubic spline)"); setdescription("Fine Structure used in combination with a normal cross-section using Lifetime broadening as an extra prior knowledge"); setcanconvolute(true); setshifter(false); set_ismultiplier(true); /* for (size_t i=0;i<degree;i++){ //tell that we have a gradient for each point a_i this->sethasgradient(i+3,true); } */ InitEnergy(); //prepare the energy points that are linked to the paramters gslinit(); //setup the memory for the gsl fitter calculate(); setvisible(true); Plotspec=new Spectrum(Evector.size()); initplotspec(); (this->getgraphptr())->addgraph(Plotspec); (this->getgraphptr())->setstyle(1,2); //set style of this plot to dots instead of lines //show the current DOS //make a new spectrum containing Evector,Yvector //show an equaliser this->showequalizer(); }
Mscatter::Mscatter(int n,double estart,double dispersion,std::vector<Parameter*>* parameterlistptr) :Component(n,estart,dispersion),LLspectrum(n,estart,dispersion) { Parameter* p; //give a name and description this->setpppc(1.0); //test this->setname("Multiple scattering (matrix convolution)"); this->setdescription("Convolution of the HL spectrum with LL using matrix convolution.\nThis simulates the effect of multiple scattering\nwhich is an important effect in experimental spectra "); this->setcanconvolute(false); //meaningless in this case this->setconvolutor(true); //makes this a special component! setshifter(false); //get a const pointer to the HL spectrum (we don't want to change the spectrum) const Model* mymodel=(geteelsmodelptr())->getmodel(); HLptr=0; HLptr=mymodel->getconstspectrumptr(); //pointer to the calculated model spectrum if (HLptr==0) throw Componenterr::unable_to_create(); LLptr=0; multiLLptr=0; //get a pointer to a low loss spectrum (MULTI or normal) //in case no parameter list is given (=a new component) if (parameterlistptr==0){ //get a pointer to a LL spectrum QWorkspace* myworkspace= getworkspaceptr(); Getgraphptr* LLgetptr=new Getgraphptr(myworkspace,"","Make sure the LL spectrum is frontmost"); if (LLgetptr==0){ //stop creating this component Saysomething mysay(0,"Error","the LL spectrum didn't appear to be valid"); throw Componenterr::unable_to_create(); } LLgetptr->show(); if ( LLgetptr->exec() == QDialog::Accepted ) { if (LLgetptr->ismulti()){ multiLLptr=LLgetptr->getmultipointer(); if (multiLLptr==0) throw Componenterr::unable_to_create(); //check if both are same size if (multiLLptr->getnpoints()!=HLptr->getnpoints()){ Saysomething mysay(0,"Error","Both spectra should be of the same size"); throw Componenterr::unable_to_create(); } } else{ //convoluting with a singe LL spectrum LLptr=LLgetptr->getpointer(); if (LLptr==0){ Saysomething mysay(0,"Error","The topmost window was not a spectrum"); throw Componenterr::unable_to_create(); } } }else{ //the dialog got closed in another way throw Componenterr::unable_to_create(); } delete LLgetptr; if (multiLLptr==0){ p=new Parameter(LLptr->getfilename(),0.0,false);//store the filename in a dummy parameter } else{ std::string fname=multiLLptr->getfilename(); //Saysomething mysay(0,"Error",QString::fromStdString(fname)); p=new Parameter(fname,0.0,false);//store the filename in a dummy parameter } } //in case a parameterlist is given, load the spectrum file and fill in the parameters else{//get the parameter from the list p=(*parameterlistptr)[0]; //let spectrum take care of finding the spectrum if the filename is wrong //the finale filename can be retrieved from the spectrum //get the edge file via the filename //first check wether this file can be found //Fileopener f(0,0,filename); //filename=f.open(); //filename is now an updated name //if (filename=="") throw Componenterr::unable_to_create();//cancelled by user //p.setname(filename); //store this new name in the parameter //assume that if model is multispectrum also LL will be a multispectrum if (!mymodel->ismulti()){ loadmsa l; LLptr = new Spectrum(l,p->getname()); //the filename is stored in the name of p if (LLptr==0) throw Componenterr::unable_to_create(); } else{ //ask eelsmodel to load a multispectrum multiLLptr=(geteelsmodelptr())->openDM(p->getname(),true); //open but silent if (multiLLptr==0) { //maybe it was a single spectrum after all... loadmsa l; LLptr = new Spectrum(l,p->getname()); //the filename is stored in the name of p if (LLptr==0) throw Componenterr::unable_to_create();} } } updateLL(); //set the LLptr to the right current spectrum, copy it and and normalise p->setname(LLptr->getfilename()); //update p to the real filename that was used this->addparameter(p); }
Plasmon::Plasmon(int n,double estart,double dispersion,std::vector<Parameter*>* parameterlistptr) :Component(n,estart,dispersion) { //ask for number of plasmons to calculate const int min=1; const int max=10; nrofplasmons=2; Integerinput myinput(0,"","enter degree the number of plasmons",nrofplasmons,min,max); //create the lorentz peaks for ZL and plasmons peaklist.resize(0); const double EZL=0.0; //the zl position const double fwhmZL=1.0; //the fwhm of the ZL peak const double heightZL=1.0e3; //the height of the ZL peak //create the ZL peak Lorentz* ZL=new Lorentz(n,estart,dispersion,EZL,fwhmZL,heightZL); peaklist.push_back(ZL); //create the plasmon peaks const double EP=15.0; //the zl position const double fwhmP=10.0; //the fwhm of the ZL peak const double tlambda=0.3; //the t/lambda thickness factor for (int i=1;i<=nrofplasmons;i++){ //a poisson related height for the ith plasmon double height=heightZL*poissonfraction(tlambda,i); Lorentz* plasmon=new Lorentz(n,estart,dispersion,i*EP,fwhmP,height); peaklist.push_back(plasmon); } //add the required parameters if (parameterlistptr==0){ //we have to create a new set of parameters //position of the ZL Parameter* p1=new Parameter("EZL",EZL,1); p1->interactivevalue("enter the ZL position"); this->addparameter(p1); //fwhm ZL Parameter* p2=new Parameter("fwhmZL",fwhmZL,1); p2->interactivevalue("enter fwhm of the ZL"); this->addparameter(p2); //ZL height Parameter* p3=new Parameter("heightZL",heightZL,1); p3->interactivevalue("enter height of the ZL"); this->addparameter(p3); //plasmon energy Parameter* p4=new Parameter("EP",EP,1); p4->interactivevalue("enter plasmon energy"); this->addparameter(p4); //plasmon fwhm Parameter* p5=new Parameter("fwhmP",fwhmP,1); p5->interactivevalue("enter plasmon fwhm"); this->addparameter(p5); //t/lambda Parameter* p6=new Parameter("tlambda",tlambda,1); p6->interactivevalue("enter plasmon fwhm"); this->addparameter(p6); //darknoise double dnoise=0.0; Parameter* p7=new Parameter("dnoise",dnoise,1); p7->interactivevalue("enter darknoise value"); this->addparameter(p7); } else{ //get parameters from a list Parameter* p1=(*parameterlistptr)[0]; this->addparameter(p1); Parameter* p2=(*parameterlistptr)[1]; this->addparameter(p2); Parameter* p3=(*parameterlistptr)[2]; this->addparameter(p3); Parameter* p4=(*parameterlistptr)[3]; this->addparameter(p4); Parameter* p5=(*parameterlistptr)[4]; this->addparameter(p5); Parameter* p6=(*parameterlistptr)[5]; this->addparameter(p6); Parameter* p7=(*parameterlistptr)[6]; this->addparameter(p7); } //give a name and description setname("Plasmon model"); setdescription("A model of a lorentzian ZL peak and a set of lorentzian plasmon peaks"); setcanconvolute(true); setshifter(false); }
PearsonIV::PearsonIV(int n,double estart,double dispersion,std::vector<Parameter*>* parameterlistptr) :Component(n,estart,dispersion) { //add the required parameters Parameter* p1; Parameter* p2; Parameter* p3; Parameter* p4; Parameter* p5; if (parameterlistptr==0){ p1=new Parameter("Emax",0.0,1); p1->interactivevalue("enter position"); p2=new Parameter("m",1.0,1); p2->setboundaries(0.5,1e5); p2->interactivevalue("m value (m=1 Cauchy,m=2 Lorentz, m=inf Gauss)"); p3=new Parameter("nu",1.0,1); p3->interactivevalue("nu"); p4=new Parameter("a",1.0,1); p4->setboundaries(0.0,1e10); //convention, let nu take the negative part since transform a:-a and nu:-nu leave function unchanged p4->interactivevalue("a"); const Model* mymodel=geteelsmodelptr()->getmodel(); const double maxval=mymodel->getHLptr()->getmax(); p5=new Parameter("Height",maxval,1); p5->interactivevalue("enter height"); } else{ p1=(*parameterlistptr)[0]; p2=(*parameterlistptr)[1]; p3=(*parameterlistptr)[2]; p4=(*parameterlistptr)[3]; p5=(*parameterlistptr)[4]; } //Height is a linear parameter p5->setlinear(true); this->addparameter(p1); this->addparameter(p2); this->addparameter(p3); this->addparameter(p4); this->addparameter(p5); //give a name and description this->setname("Pearson IV"); this->setdescription("Pearson IV peak (model for ZL peak)"); this->setcanconvolute(true); //all three parameters have an analytical gradient //TODO add numerical derivatives this->sethasgradient(0,false); this->sethasgradient(1,false); this->sethasgradient(2,false); this->sethasgradient(3,false); this->sethasgradient(4,true); setshifter(false); //seems to be really important here }