bool DosLifetimeSpline::checkxsection(){ //check if the cross section component we are pointing to has still the same number //otherwise update the component number parameter Model* mymodel=geteelsmodelptr()->getmodel_nonconst(); const int cnr=mymodel->getcomponentindexbypointer(compptr); if (compptr==NULL){ return false; } Parameter* cnrptr= getparameter(degree+3); if ((cnr==-1)&&(compptr!=NULL)){ //component not found also kill ourselves... Saysomething mysay(0,"Error","DOS: the component we are pointing to seems to be not present"); delete(this); //it's over compptr=NULL; cnrptr->setchangeable(true); //unlock cnrptr->setvalue(-1); //update non-existing value cnrptr->setchangeable(false); //lock return false; } cnrptr->setchangeable(true); //unlock cnrptr->setvalue(cnr); //update to current value cnrptr->setchangeable(false); //lock return true; }
void Mscatter::updateLL(){ if (multiLLptr!=0){ //set the current spectrum of the LL to the same as the HL current spectrum const Model* mymodel=(geteelsmodelptr())->getmodel(); const Multispectrum* HLmulti=mymodel->getconstmultispectrumptr(); multiLLptr->setcurrentslice((HLmulti->getcurrentslice())); //and get the pointer to the current spectrum LLptr=multiLLptr->getcurrentspectrum(); } //get a copy of the LL spectrum if (LLptr!=0){ LLspectrum=(*LLptr);//copy the spectrum via the copy assignment defined in Spectrum class } else throw Componenterr::unable_to_create(); //check if the maximum of the spectrum is close to 0eV energy, otherwise callibration is wrong ZLindex=LLspectrum.getmaxindex(); double e0=LLspectrum.getenergy(ZLindex); if (fabs(e0)>10.0){ //Saysomething mysay(0,"warning","The position of the zero loss peak is more then 10eV (should be close to 0eV), I will correct this"); } //make sure the spectrum starts with y=0 and ends with y=0 //use linear interpolation between both end //this is required when CCD problems occured //normally this should not be nessecary // E X P E R I M E N T A L const double starty=LLspectrum.getcounts(0); const double estart=LLspectrum.getenergy(0); const int n=LLspectrum.getnpoints(); const double endy=LLspectrum.getcounts(n-1); const double eend=LLspectrum.getenergy(n-1); const double slope=(endy-starty)/(eend-estart); const double cliplimit=-20.0; for (int i=0;i<n;i++){ const double E=LLspectrum.getenergy(i); const double cts=LLspectrum.getcounts(i); //E X P E R I M E N T const double correction=starty+(E-estart)*slope; LLspectrum.setcounts(i,cts-correction); //clip off any remaining counts that are too negative if (cts-correction<cliplimit){ LLspectrum.setcounts(i,cliplimit); } } //show this spectrum as a test //Spectrum* myspec=new Spectrum(n); //copy because LLspectrum will die when out of scope //(*myspec)=LLspectrum; //myspec->display(0); //normalize the spectrum to 1 LLspectrum.normalize(); }
Eshift::Eshift(int n,double estart,double dispersion,std::vector<Parameter*>* parameterlistptr) :Component(n,estart,dispersion) { //add the required parameters Parameter* p1; if (parameterlistptr==0) { p1=new Parameter("delta E",0.0,1); p1->interactivevalue("enter energy shhift"); } else { p1=(*parameterlistptr)[0]; } this->addparameter(p1); //give a name and description this->setname("Eshift"); this->setdescription("energy shift by linear interpolation of model"); this->setcanconvolute(false); //convoluting this has no meaning this->setconvolutor(false); this->setshifter(true); //this is a special component which needs to be treated first in the model calculation sequence //because if an eshift occurs, all components are affected by this and need to be recalculated //get a const pointer to the HL spectrum (we don't want to change the HL) mymodel=(geteelsmodelptr())->getmodel_nonconst(); HLptr=0; HLptr=mymodel->getHLptr(); //pointer to the HL spectrum if (HLptr==0) throw Componenterr::unable_to_create(); }
void DosLifetimeSpline::orderchanged(){ //in case the order of the components changes, update the compnr const Model* mymodel=geteelsmodelptr()->getmodel(); const int cnr=mymodel->getcomponentindexbypointer(compptr); Parameter* cnrptr= getparameter(degree+3); cnrptr->setchangeable(true); //unlock cnrptr->setvalue(cnr); //update to current value cnrptr->setchangeable(false); //lock }
Fileopener::Fileopener(QWidget *parent, const char *name ,std::string fname) : QWidget(parent) { dirname=""; filter="*.*"; name="open file dialog"; caption="Choose a file"; filename=QString::fromStdString(fname); projfile=QString::fromStdString((geteelsmodelptr())->getprojectfilename()); QFileInfo fil=QFileInfo(projfile); //take only the path modelpath=fil.absolutePath(); //return absolute path of the file #ifdef FILEOPEN_DEBUG std::cout << "fileopener\n"; std::cout << "filename: " <<filename.toStdString()<<"\n"; std::cout << "projfile: " <<projfile.toStdString()<<"\n"; std::cout << "modelpath: " <<modelpath.toStdString()<<"\n"; #endif }
void Mscatter::calculate() { if (multiLLptr!=0){ //if a multispectrum, check if the current slice has changed //if so, do an updateLL to get a new, normalised LL spectrum try{ const Model* mymodel=(geteelsmodelptr())->getmodel(); const Multispectrum* HLmulti=mymodel->getconstmultispectrumptr(); if(multiLLptr->getcurrentslice()!=HLmulti->getcurrentslice()){ updateLL(); } } catch(...){ throw Componenterr::unable_to_calculate(); } } //do the matrix convolution double cts=0.0; int npoints=this->getnpoints(); for (int i=0;i<npoints;i++) { cts=0.0; for(int j=-ZLindex;((j<=i)&&(j<(npoints-ZLindex)));j++){ #ifdef MSCATTER_DEBUG if ((ZLindex+j)<0) { std::cout<<"ZLindex+j= negative! "<<(ZLindex+j)<<"\n"; } if ((i-j)<0) { std::cout<<"i-j= negative!"<<(i-j)<<"\n"; } if ((ZLindex+j)>=npoints) { std::cout<<"ZLindex+j>=npoints! "<<(ZLindex+j)<<"\n"; } //if ((i-j)>=npoints) {std::cout<<"i-j>= npoints!"<<i-j<<"\n";} #endif if ((i-j)<npoints){ cts+=LLspectrum.getcounts(ZLindex+j)*HLptr->getcounts(i-j); } } this->setcounts(i,cts); } }
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); }
void Equalizer::slot_sliderrelease() { //force a recalc and redisplay of the model geteelsmodelptr()->componentmaintenance_updatescreen(); }
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 }