bool DetectorChooser::Readfile(QStringList& list, std::vector<double>& gainlist, std::vector<double>& corrfactorlist){ //open file for reading std::ifstream detfile("detectors.txt",std::ios_base::binary); if (!detfile) { //complain that file can not be opened Saysomething mysay(0,"Error","The file detectors.txt could not be opened \n make sure it is in the executable directory"); return false; } std::string detname; std::string gainstring; std::string corrfactorstring; //read line by line const char eol=(char)10; const char tab='\t'; while (std::getline(detfile,detname,tab)){ #ifdef COMPONENT_DEBUG std::cout <<"detname:"<<detname<<"\n"; #endif if (detname.find("%")==std::string::npos){ //a line without % sign found //split myline in tree parts according to name gain and corrfactor if (!std::getline(detfile,gainstring,tab)){ //error reading gain Saysomething mysay(0,"Error","Error reading gain factor"); break; } if(!std::getline(detfile,corrfactorstring,eol)){ Saysomething mysay(0,"Error","Error reading correlation factor"); //error reading corrfactor break; } //add these values to the list #ifdef COMPONENT_DEBUG std::cout <<"detname:"<<detname<<"gainstring"<<gainstring<<"corrfactorstring"<<corrfactorstring<<"\n"; #endif char* end; const double corrfactor=std::strtod( corrfactorstring.c_str(), &end); const double gainfactor=std::strtod( gainstring.c_str(), &end); list.append(QString::fromStdString (detname)); gainlist.push_back(gainfactor); corrfactorlist.push_back(corrfactor); #ifdef COMPONENT_DEBUG std::cout <<"detname:"<<detname<<"gain (double)"<<gainfactor<<"corrfactor (double)"<<corrfactor<<"\n"; #endif } else{ //a % line was read skip rest of line std::getline(detfile,corrfactorstring,eol); } } detfile.close(); return true; //succes }
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; }
double MLFitterGSL::iteration(){ //do one itteration //lock the model so user can not add or remove components during itteration modelptr->setlocked(true); //if the model has changed (a new or removed component eg.) create a new solver if (modelptr->has_changed()){ createmodelinfo(); //this automaticaly calls initfitter() via created_modelinfo() } //do an itteration step try{ const int status=gsl_multifit_fdfsolver_iterate(solver); #ifdef FITTER_DEBUG std::cout <<"solver status: "<<gsl_strerror(status)<<"\n"; std::cout <<"chi square/dof: "<<gsl_blas_dnrm2(solver->f)<<"\n"; #endif this->setstatus(gsl_strerror(status)); //update status info of fitter convertxtoparam(solver->x); } catch(...){ Saysomething mysay(0,"Error","Problem with call to gsl_multifit_fdfsolver_iterate, exit MLFitterGSL",true); delete(this); } //unlock the model so user can add or remove components modelptr->setlocked(false); //put the goodness in the goodnessqueue to check for convergence const double newgoodness= goodness_of_fit(); addgoodness(newgoodness); return newgoodness; }
DetectorChooser::DetectorChooser(QWidget *parent, const char *name,Model* mymodel) : QWidget(parent) { QStringList list; std::vector<double> gainlist; std::vector<double> corrfactorlist; this->Readfile(list,gainlist,corrfactorlist); bool ok=false; QString result=QInputDialog::getItem (this,"Detector Chooser","Choose a detector type to use",list,0,false,&ok); if ( ok ){ //find out which number in the list //go trough the name list QStringList::Iterator it; int i=0; for (it = list.begin(); it != list.end(); ++it ) { if (result==*it){ //found! update the gainfactor and the correlation factor std::string detname=(*it).toStdString () ; #ifdef COMPONENT_DEBUG std::cout <<"selected the detector with name:"<<detname<<" occurence number i="<<i<<" gain="<<gainlist[i]<<" corrfactor:"<<corrfactorlist[i]<<"\n"; #endif if (mymodel==0){ Saysomething mysay(0,"Error","No valid model present, can not set detector without model"); return; } mymodel->setdetectorname(detname); mymodel->setdetectorgain(gainlist[i]); mymodel->setdetectorcorrfactor(corrfactorlist[i]); return; } i++; } if (it==list.end()){ //nothing found Saysomething mysay(0,"Error","Something went wrong in selecting detector...you can only select existing entries in the detectors.txt file"); return; } } else // user pressed Cancel return; }
Spectrum* Gettopspectrum::getpointer(){ Spectrum* specptr=0; //determine the top window QApplication * myapp=qApp; //myapp->flush(); //repaint everything so the previous window is active //myapp->flushX(); //repaint everything so the previous window is active myapp->processEvents(); QObject* topw=myapp->activeWindow(); Graph* topgraph=0; //check if that window is a Graph if ((topgraph=(dynamic_cast<Graph*>(topw)))){ //ask the graph for a pointer to its spectrum specptr= topgraph->getspectrumptr(); } else{ Saysomething mysay(0,"Error","The front window is not a spectrum graph"); specptr=0; } return specptr; }
void MLFitterGSL::initfitter(){ //do first whatever the fitter wants to do here Fitter::initfitter(); #ifdef FITTER_DEBUG std::cout <<"mlfitter_gsl::initfitter called\n"; #endif //createmodelinfo(); //update number of free parameters etc if a model has changed const int n=modelptr->getnpoints(); try{ //delete old solver and create new one if (solver!=0) gsl_multifit_fdfsolver_free (solver); const gsl_multifit_fdfsolver_type * T = gsl_multifit_fdfsolver_lmsder; //Scaled Levenberg Marquardt solver= gsl_multifit_fdfsolver_alloc (T,n,modelptr->getnroffreeparameters()); //reallocate memory for parameter vector x and covariance matrix covar if (initialparameters!=0) gsl_vector_free (initialparameters); if (covar!=0) gsl_matrix_free (covar); initialparameters=gsl_vector_calloc (modelptr->getnroffreeparameters()); //allocate space for vector x, containing param values covar=gsl_matrix_calloc (modelptr->getnroffreeparameters(), modelptr->getnroffreeparameters()); //init the link with the function to be fitted initfdf(); //load the current parameters in the x vector initparameters(); //reinit the solver gsl_multifit_fdfsolver_set(solver,&f,initialparameters); } catch(...){ //problems with memory? -> kill this Saysomething mysay(0,"Error","Unable to allocate memory, exit MLFitterGSL",true); delete(this); } }
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); }