예제 #1
0
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
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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);
  }
}
예제 #7
0
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();
}
예제 #8
0
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);
}