Ejemplo n.º 1
0
/// Initialized the main CoMD data stucture, SimFlat, based on command
/// line input from the user.  Also performs certain sanity checks on
/// the input to screen out certain non-sensical inputs.
///
/// Simple data members such as the time step dt are initialized
/// directly, substructures such as the potential, the link cells, the
/// atoms, etc., are initialized by calling additional initialization
/// functions (initPotential(), initLinkCells(), initAtoms(), etc.).
/// Initialization order is set by the natural dependencies of the
/// substructure such as the atoms need the link cells so the link cells
/// must be initialized before the atoms.
SimFlat* initSimulation(Command cmd)
{
   SimFlat* sim = comdMalloc(sizeof(SimFlat));
   sim->nSteps = cmd.nSteps;
   sim->printRate = cmd.printRate;
   sim->dt = cmd.dt;
   sim->domain = NULL;
   sim->boxes = NULL;
   sim->atoms = NULL;
   sim->ePotential = 0.0;
   sim->eKinetic = 0.0;
   sim->atomExchange = NULL;

   sim->pot = initPotential(cmd.doeam, cmd.potDir, cmd.potName, cmd.potType);
   real_t latticeConstant = cmd.lat;
   if (cmd.lat < 0.0)
      latticeConstant = sim->pot->lat;

   // ensure input parameters make sense.
   sanityChecks(cmd, sim->pot->cutoff, latticeConstant, sim->pot->latticeType);

   sim->species = initSpecies(sim->pot);

   real3 globalExtent;
   globalExtent[0] = cmd.nx * latticeConstant;
   globalExtent[1] = cmd.ny * latticeConstant;
   globalExtent[2] = cmd.nz * latticeConstant;

   sim->domain = initDecomposition(
      cmd.xproc, cmd.yproc, cmd.zproc, globalExtent);

   sim->boxes = initLinkCells(sim->domain, sim->pot->cutoff);
   sim->atoms = initAtoms(sim->boxes);

   // create lattice with desired temperature and displacement.
   createFccLattice(cmd.nx, cmd.ny, cmd.nz, latticeConstant, sim);
   setTemperature(sim, cmd.temperature);
   randomDisplacements(sim, cmd.initialDelta);

   sim->atomExchange = initAtomHaloExchange(sim->domain, sim->boxes);

   // Forces must be computed before we call the time stepper.
   startTimer(redistributeTimer);
   redistributeAtoms(sim);
   stopTimer(redistributeTimer);

   startTimer(computeForceTimer);
   computeForce(sim);
   stopTimer(computeForceTimer);

   kineticEnergy(sim);

   return sim;
}
Ejemplo n.º 2
0
kalmanFilter::kalmanFilter(arma::vec state, arma::mat transistion, arma::mat meas, arma::mat mNoise, arma::mat pNoise) {
	stateEstimation = state;
	transistionMatrix = transistion;
	transistionMatrixT = transistion.i();
	measurementMatrix = meas;
	transistionMatrixT = meas.i();
	measNoise = mNoise;
	processNoise = pNoise;
	sanityChecks();

	std::cout << "Kalman filter object is created.\n";
}
Ejemplo n.º 3
0
static struct ir_remote * read_config_recursive(FILE *f, const char *name, int depth)
{
	char buf[LINE_LEN+1], *key, *val, *val2;
        int len,argc;
	struct ir_remote *top_rem=NULL,*rem=NULL;
        struct void_array codes_list,raw_codes,signals;
	struct ir_ncode raw_code={NULL,0,0,NULL};
	struct ir_ncode name_code={NULL,0,0,NULL};
	struct ir_ncode *code;
	int mode=ID_none;

	line=0;
	parse_error=0;
	LOGPRINTF(2, "parsing '%s'", name);

	while(fgets(buf,LINE_LEN,f)!=NULL)
	{
		line++;
		len=strlen(buf);
		if(len==LINE_LEN && buf[len-1]!='\n')
		{
			logprintf(LOG_ERR,"line %d too long in config file",
				  line);
			parse_error=1;
			break;
		}

		if(len>0)
		{
			len--;
			if(buf[len]=='\n') buf[len]=0;
		}
		if(len>0)
		{
			len--;
			if(buf[len]=='\r') buf[len]=0;
		}
                /* ignore comments */
                if(buf[0]=='#'){
			continue;
                }
		key=strtok(buf, whitespace);
		/* ignore empty lines */
		if(key==NULL) continue;
		val=strtok(NULL, whitespace);
		if(val!=NULL){
			val2=strtok(NULL, whitespace);
			LOGPRINTF(3,"\"%s\" \"%s\"",key,val);
			if (strcasecmp("include",key)==0){
                                FILE* childFile;
				const char *childName;
				const char *fullPath;
				char result[FILENAME_MAX+1];


				if (depth > MAX_INCLUDES) {
					logprintf(LOG_ERR,"error opening child file defined at %s:%d",name,line);
					logprintf(LOG_ERR,"too many files included");
					parse_error=-1;
					break;
				}

				childName = lirc_parse_include(val);
				if (!childName){
					logprintf(LOG_ERR,"error parsing child file value defined at line %d:",line);
					logprintf(LOG_ERR,"invalid quoting");
					parse_error=-1;
					break;
				}

				fullPath = lirc_parse_relative(result, sizeof(result), childName, name);
				if (!fullPath) {
					logprintf(LOG_ERR,"error composing relative file path defined at line %d:",line);
					logprintf(LOG_ERR,"resulting path too long");
					parse_error=-1;
					break;
				}

				childFile = fopen(fullPath, "r");
				if (childFile == NULL){
					logprintf(LOG_ERR,"error opening child file '%s' defined at line %d:",fullPath, line);
					logprintf(LOG_ERR,"ignoring this child file for now.");
				}
				else{
					int save_line = line;

					if (!top_rem){
						/* create first remote */
						LOGPRINTF(2,"creating first remote");
						rem = read_config_recursive(childFile, fullPath, depth + 1);
						if(rem != (void *) -1 && rem != NULL) {
							top_rem = rem;
						} else {
							rem = NULL;
						}
					}else{
						/* create new remote */
						LOGPRINTF(2,"creating next remote");
						rem->next=read_config_recursive(childFile, fullPath, depth + 1);
						if(rem->next != (void *) -1 && rem->next != NULL) {
							rem=rem->next;
						} else {
							rem->next = NULL;
						}
					}
					fclose(childFile);
					line = save_line;
				}
			}else if (strcasecmp("begin",key)==0){
				if (strcasecmp("codes", val)==0){
                                        /* init codes mode */
					LOGPRINTF(2,"    begin codes");
					if (!checkMode(mode, ID_remote,
						       "begin codes")) break;
					if (rem->codes){
						logprintf(LOG_ERR,"error in configfile line %d:",line);
						logprintf(LOG_ERR,"codes are already defined");
						parse_error=1;
						break;
					}

                                        init_void_array(&codes_list,30, sizeof(struct ir_ncode));
                                        mode=ID_codes;
                                }else if(strcasecmp("raw_codes",val)==0){
                                        /* init raw_codes mode */
					LOGPRINTF(2,"    begin raw_codes");
					if(!checkMode(mode, ID_remote,
						  "begin raw_codes")) break;
					if (rem->codes){
						logprintf(LOG_ERR,"error in configfile line %d:",line);
						logprintf(LOG_ERR,"codes are already defined");
						parse_error=1;
						break;
					}
					set_protocol(rem, RAW_CODES);
					raw_code.code=0;
                                        init_void_array(&raw_codes,30, sizeof(struct ir_ncode));
                                        mode=ID_raw_codes;
                                }else if(strcasecmp("remote",val)==0){
					/* create new remote */
					LOGPRINTF(1,"parsing remote");
					if(!checkMode(mode, ID_none,
						  "begin remote")) break;
                                        mode=ID_remote;
                                        if (!top_rem){
                                                /* create first remote */
						LOGPRINTF(2,"creating first remote");
                                                rem=top_rem=s_malloc(sizeof(struct ir_remote));
                                        }else{
                                                /* create new remote */
						LOGPRINTF(2,"creating next remote");
                                                rem->next=s_malloc(sizeof(struct ir_remote));;
                                                rem=rem->next;
                                        }
				}else if(mode==ID_codes){
					code=defineCode(key, val, &name_code);
					while(!parse_error && val2!=NULL)
					{
						struct ir_code_node *node;

						if(val2[0]=='#') break; /* comment */
						node=defineNode(code, val2);
						val2=strtok(NULL, whitespace);
					}
					code->current=NULL;
					add_void_array(&codes_list, code);
                                }else{
                                        logprintf(LOG_ERR,"error in configfile line %d:",line);
					logprintf(LOG_ERR,"unknown section \"%s\"",val);
                                        parse_error=1;
                                }
				if(!parse_error && val2!=NULL)
				{
					logprintf(LOG_WARNING,"garbage after "
						  "'%s' token in line %d ignored",
						  val,line);
				}
                        }else if (strcasecmp("end",key)==0){

				if (strcasecmp("codes", val)==0){
					/* end Codes mode */
					LOGPRINTF(2,"    end codes");
                                        if (!checkMode(mode, ID_codes,
						       "end codes")) break;
                                        rem->codes=get_void_array(&codes_list);
                                        mode=ID_remote;     /* switch back */

                                }else if(strcasecmp("raw_codes",val)==0){
                                        /* end raw codes mode */
					LOGPRINTF(2,"    end raw_codes");

					if(mode==ID_raw_name){
						raw_code.signals=get_void_array(&signals);
						raw_code.length=signals.nr_items;
						if(raw_code.length%2==0)
						{
							logprintf(LOG_ERR,"error in configfile line %d:",line);
							logprintf(LOG_ERR,"bad signal length");
							parse_error=1;
						}
						if(!add_void_array(&raw_codes, &raw_code))
							break;
						mode=ID_raw_codes;
					}
                                        if(!checkMode(mode,ID_raw_codes,
						      "end raw_codes")) break;
					rem->codes=get_void_array(&raw_codes);
					mode=ID_remote;     /* switch back */
                                }else if(strcasecmp("remote",val)==0){
                                        /* end remote mode */
					LOGPRINTF(2,"end remote");
					/* print_remote(rem); */
                                        if (!checkMode(mode,ID_remote,
                                                  "end remote")) break;
					if(!sanityChecks(rem)) {
                                                parse_error=1;
                                                break;
					}

#                                       ifdef DYNCODES
					if(rem->dyncodes_name==NULL)
					{
						rem->dyncodes_name=s_strdup("unknown");
					}
					rem->dyncodes[0].name=rem->dyncodes_name;
					rem->dyncodes[1].name=rem->dyncodes_name;
#                                       endif
					/* not really necessary because we
					   clear the alloced memory */
                                        rem->next=NULL;
					rem->last_code=NULL;
                                        mode=ID_none;     /* switch back */
				}else if(mode==ID_codes){
					code=defineCode(key, val, &name_code);
					while(!parse_error && val2!=NULL)
					{
						struct ir_code_node *node;

						if(val2[0]=='#') break; /* comment */
						node=defineNode(code, val2);
						val2=strtok(NULL, whitespace);
					}
					code->current=NULL;
					add_void_array(&codes_list, code);
                                }else{
                                        logprintf(LOG_ERR,"error in configfile line %d:",line);
					logprintf(LOG_ERR,"unknown section %s",val);
                                        parse_error=1;
                                }
				if(!parse_error && val2!=NULL)
				{
					logprintf(LOG_WARNING,"garbage after '%s'"
						  " token in line %d ignored",
						  val,line);
				}
                        } else {
				switch (mode){
				case ID_remote:
					argc=defineRemote(key, val, val2, rem);
					if(!parse_error && ((argc==1 && val2!=NULL) || 
					   (argc==2 && val2!=NULL && strtok(NULL, whitespace)!=NULL)))
					{
						logprintf(LOG_WARNING,"garbage after '%s'"
							  " token in line %d ignored",
							  key,line);
					}
					break;
				case ID_codes:
					code=defineCode(key, val, &name_code);
					while(!parse_error && val2!=NULL)
					{
						struct ir_code_node *node;

						if(val2[0]=='#') break; /* comment */
						node=defineNode(code, val2);
						val2=strtok(NULL, whitespace);
					}
					code->current=NULL;
					add_void_array(&codes_list, code);
					break;
				case ID_raw_codes:
				case ID_raw_name:
					if(strcasecmp("name",key)==0){
						LOGPRINTF(3,"Button: \"%s\"",val);
						if(mode==ID_raw_name)
						{
                                                        raw_code.signals=get_void_array(&signals);
							raw_code.length=signals.nr_items;
							if(raw_code.length%2==0)
							{
								logprintf(LOG_ERR,"error in configfile line %d:",line);
								logprintf(LOG_ERR,"bad signal length");
								parse_error=1;
							}
							if(!add_void_array(&raw_codes, &raw_code))
								break;
						}
						if(!(raw_code.name=s_strdup(val))){
							break;
						}
						raw_code.code++;
						init_void_array(&signals,50,sizeof(lirc_t));
						mode=ID_raw_name;
						if(!parse_error && val2!=NULL)
						{
							logprintf(LOG_WARNING,"garbage after '%s'"
								  " token in line %d ignored",
								  key,line);
						}
					}else{
						if(mode==ID_raw_codes)
						{
							logprintf(LOG_ERR,"no name for signal defined at line %d",line);
							parse_error=1;
							break;
						}
						if(!addSignal(&signals, key)) break;
						if(!addSignal(&signals, val)) break;
						if (val2){
							if (!addSignal(&signals, val2)){
								break;
							}
						}
						while ((val=strtok(NULL, whitespace))){
							if (!addSignal(&signals, val)) break;
						}
					}
					break;
				}
			}
		}else if(mode==ID_raw_name){
                        if(!addSignal(&signals, key)){
				break;
			}
		}else{
                        logprintf(LOG_ERR,"error in configfile line %d", line);
			parse_error=1;
			break;
                }
                if (parse_error){
                        break;
                }
        }
	if(mode!=ID_none)
	{
		switch(mode)
		{
		case ID_raw_name:
			if(raw_code.name!=NULL)
			{
				free(raw_code.name);
				if(get_void_array(&signals)!=NULL)
					free(get_void_array(&signals));
			}
		case ID_raw_codes:
			rem->codes=get_void_array(&raw_codes);
			break;
		case ID_codes:
			rem->codes=get_void_array(&codes_list);
			break;
		}
		if(!parse_error)
		{
			logprintf(LOG_ERR,"unexpected end of file");
			parse_error=1;
		}
	}
        if (parse_error){
		static int print_error = 1;

		if(print_error) {
			logprintf(LOG_ERR, "reading of file '%s' failed",
				  name);
			print_error = 0;
		}
		free_config(top_rem);
		if(depth == 0) print_error = 1;
                return((void *) -1);
        }
	/* kick reverse flag */
	/* handle RC6 flag to be backwards compatible: previous RC-6
	   config files did not set rc6_mask */
	rem=top_rem;
	while(rem!=NULL)
	{
		if((!is_raw(rem)) && rem->flags&REVERSE)
		{
			struct ir_ncode *codes;

			if(has_pre(rem))
			{
				rem->pre_data=reverse(rem->pre_data,
						      rem->pre_data_bits);
			}
			if(has_post(rem))
			{
				rem->post_data=reverse(rem->post_data,
						       rem->post_data_bits);
			}
			codes=rem->codes;
			while(codes->name!=NULL)
			{
				codes->code=reverse(codes->code,rem->bits);
				codes++;
			}
			 rem->flags=rem->flags&(~REVERSE);
			 rem->flags=rem->flags|COMPAT_REVERSE;
			/* don't delete the flag because we still need
			   it to remain compatible with older versions
			*/
		}
		if(rem->flags&RC6 && rem->rc6_mask==0 && rem->toggle_bit>0)
		{
			int all_bits=bit_count(rem);

			rem->rc6_mask=((ir_code) 1)<<(all_bits-rem->toggle_bit);
		}
		if(rem->toggle_bit > 0)
		{
			int all_bits=bit_count(rem);

			if(has_toggle_bit_mask(rem))
			{
				logprintf(LOG_WARNING,
					  "%s uses both toggle_bit and "
					  "toggle_bit_mask", rem->name);
			}
			else
			{
				rem->toggle_bit_mask=((ir_code) 1)<<(all_bits-rem->toggle_bit);
			}
			rem->toggle_bit = 0;
		}
		if(has_toggle_bit_mask(rem))
		{
			if(!is_raw(rem) && rem->codes)
			{
				rem->toggle_bit_mask_state = (rem->codes->code & rem->toggle_bit_mask);
				if(rem->toggle_bit_mask_state)
				{
					/* start with state set to 0 for backwards compatibility */
					rem->toggle_bit_mask_state ^= rem->toggle_bit_mask;
				}
			}
		}
		if(is_serial(rem))
		{
			lirc_t base;

			if(rem->baud>0)
			{
				base=1000000/rem->baud;
				if(rem->pzero==0 && rem->szero==0)
				{
					rem->pzero=base;
				}
				if(rem->pone==0 && rem->sone==0)
				{
					rem->sone=base;
				}
			}
			if(rem->bits_in_byte==0)
			{
				rem->bits_in_byte=8;
			}
		}
		if(rem->min_code_repeat>0)
		{
			if(!has_repeat(rem) ||
			   rem->min_code_repeat>rem->min_repeat)
			{
				logprintf(LOG_WARNING,
					  "invalid min_code_repeat value");
				rem->min_code_repeat = 0;
			}
		}
		calculate_signal_lengths(rem);
		rem=rem->next;
	}

	top_rem = sort_by_bit_count(top_rem);
#       if defined(DEBUG) && !defined(DAEMONIZE)
        /*fprint_remotes(stderr, top_rem);*/
#       endif
        return (top_rem);
}
Ejemplo n.º 4
0
SimFlat* initSimulation(Command cmd)
{
   SimFlat* sim = comdMalloc(sizeof(SimFlat));
   sim->nSteps = cmd.nSteps;
   sim->printRate = cmd.printRate;
   sim->dt = cmd.dt;
   sim->domain = NULL;
   sim->boxes = NULL;
   sim->atoms = NULL;
   sim->ePotential = 0.0;
   sim->eKinetic = 0.0;
   sim->atomExchange = NULL;

   sim->pot = initPotential(cmd.doeam, cmd.potDir, cmd.potName, cmd.potType);
   real_t latticeConstant = cmd.lat;
   
   if (cmd.lat < 0.0)
      latticeConstant = sim->pot->lat;

   // ensure input parameters make sense.
   sanityChecks(cmd, sim->pot->cutoff, latticeConstant, sim->pot->latticeType);

   sim->species = initSpecies(sim->pot);

   real3 globalExtent;
   globalExtent[0] = cmd.nx * latticeConstant;
   globalExtent[1] = cmd.ny * latticeConstant;
   globalExtent[2] = cmd.nz * latticeConstant;

   sim->domain = initDecomposition(cmd.xproc, cmd.yproc, cmd.zproc, globalExtent);

   sim->boxes = initLinkCells(sim->domain, sim->pot->cutoff);
   sim->atoms = initAtoms(sim->boxes);

   sim->defInfo = initDeformation(sim, cmd.defGrad);

   //printf("Got to here\n");

   // create lattice with desired temperature and displacement.
   createFccLattice(cmd.nx, cmd.ny, cmd.nz, latticeConstant, sim);

  
   setTemperature(sim,0.0);
   randomDisplacements(sim, cmd.initialDelta);

   sim->atomExchange = initAtomHaloExchange(sim->domain, sim->boxes);

   forwardDeformation(sim);
   
   //eamForce(sim);
   // Procedure for energy density passing from the macrosolver to CoMD 
   //setTemperature(sim,((cmd.energy*latticeVolume*cmd.nx*cmd.ny*cmd.nz-sim->ePotential)/sim->atoms->nGlobal)/(kB_eV * 1.5));
   //randomDisplacements(sim, cmd.initialDelta);


   // Forces must be computed before we call the time stepper.
   startTimer(redistributeTimer);
   redistributeAtoms(sim);
   stopTimer(redistributeTimer);

   startTimer(computeForceTimer);
   computeForce(sim);
   stopTimer(computeForceTimer);
   
   double cohmmEnergy=cmd.energy*sim->defInfo->globalVolume;
   double temperatureFromEnergyDensity=((cohmmEnergy-sim->ePotential)/sim->atoms->nGlobal)/(kB_eV*1.5);

   setTemperature(sim,temperatureFromEnergyDensity); //uncomment to set temperature according to hmm energy density
   //setTemperature(sim,cmd.temperature); //uncomment to directly input temperature
   kineticEnergy(sim);



   return sim;
}
// Working at 2D scan by first copying the original ProbScan
int MethodDatasetsProbScan::scan2d()
{
    if ( arg->debug ) cout << "MethodDatasetsProbScan::scan2d() : starting ..." << endl;
    nScansDone++;
    sanityChecks();
    if ( startPars ) delete startPars;

    // Define whether the 2d contours in hCL are "1D sigma" (ndof=1) or "2D sigma" (ndof=2).
    // Titus: Change this to 2, since there is no reason to do wrong hCL contours.
    int ndof = 2;

    // Set up storage for fit results of this particular
    // scan. This is used for the drag start parameters.
    // We cannot use the curveResults2d member because that
    // only holds better results.
    vector<vector<RooSlimFitResult*> > mycurveResults2d;
    for ( int i=0; i<nPoints2dx; i++ ){
        vector<RooSlimFitResult*> tmp;
        for ( int j=0; j<nPoints2dy; j++ ) tmp.push_back(0);
        mycurveResults2d.push_back(tmp);
    }

    // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // // Titus: Saving is done via saveSolutions2d() in the combination, but maybe we need it inline for now \todo: implement a saving function
    // // Define outputfile
    // system("mkdir -p root");
    // TString probResName = Form("root/scan1dDatasetsProb_" + this->pdf->getName() + "_%ip" + "_" + scanVar1 + ".root", arg->npoints1d);
    // TFile* outputFile = new TFile(probResName, "RECREATE");

    // // Set up toy root tree
    // this->probScanTree = new ToyTree(this->pdf, arg);
    // this->probScanTree->init();
    // this->probScanTree->nrun = -999; //\todo: why does this branch even exist in the output tree of the prob scan?
    // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // store start parameters so we can reset them later
    startPars = new RooDataSet("startPars", "startPars", *w->set(parsName));
    startPars->add(*w->set(parsName));

    // // start scan from global minimum (not always a good idea as we need to set from other places as well)
    // setParameters(w, parsName, globalMin);

    // Define scan parameters and scan range:
    RooRealVar *par1 = w->var(scanVar1);
    RooRealVar *par2 = w->var(scanVar2);

    // Set limit to all parameters.
    this->loadParameterLimits();

    // fix scan parameters
    par1->setConstant(true);
    par2->setConstant(true);

    // Report on the smallest new minimum we come across while scanning.
    // Sometimes the scan doesn't find the minimum
    // that was found before. Warn if this happens.
    double bestMinOld = chi2minGlobal;
    double bestMinFoundInScan = 100.;

    // for the status bar
    int nSteps = 0;
    float nTotalSteps = nPoints2dx*nPoints2dy;
    float printFreq = nTotalSteps>100 && !arg->probforce ? 100 : nTotalSteps; ///< number of messages

    // initialize some control plots
    gStyle->SetOptTitle(1);
    TCanvas *cDbg = newNoWarnTCanvas(getUniqueRootName(), Form("DeltaChi2 for 2D scan %i",nScansDone));
    cDbg->SetMargin(0.1,0.15,0.1,0.1);
    float hChi2min2dMin = hChi2min2d->GetMinimum();
    bool firstScanDone = hChi2min2dMin<1e5;
    TH2F *hDbgChi2min2d = histHardCopy(hChi2min2d, firstScanDone);
    hDbgChi2min2d->SetTitle(Form("#Delta#chi^{2} for scan %i, %s",nScansDone,title.Data()));
    if ( firstScanDone ) hDbgChi2min2d->GetZaxis()->SetRangeUser(hChi2min2dMin,hChi2min2dMin+25);
    hDbgChi2min2d->GetXaxis()->SetTitle(par1->GetTitle());
    hDbgChi2min2d->GetYaxis()->SetTitle(par2->GetTitle());
    hDbgChi2min2d->GetZaxis()->SetTitle("#Delta#chi^{2}");
    TH2F *hDbgStart = histHardCopy(hChi2min2d, false);


    // start coordinates //Titus: start at the global minimum
    // don't allow the under/overflow bins
    int iStart = min(hCL2d->GetXaxis()->FindBin(par1->getVal()), hCL2d->GetNbinsX());
    int jStart = min(hCL2d->GetYaxis()->FindBin(par2->getVal()), hCL2d->GetNbinsY());
    iStart = max(iStart, 1);
    jStart = max(jStart, 1);
    hDbgStart->SetBinContent(iStart, jStart, 500.);
    TMarker *startpointmark = new TMarker(par1->getVal(),par2->getVal(),3);

    // timer
    TStopwatch tFit;
    TStopwatch tSlimResult;
    TStopwatch tScan;
    TStopwatch tMemory;

    // set up the scan spiral
    int X = 2*nPoints2dx;
    int Y = 2*nPoints2dy;
    int x,y,dx,dy;
    x = y = dx = 0;
    dy = -1;
    int t = std::max(X,Y);
    int maxI = t*t;

    for ( int spiralstep=0; spiralstep<maxI; spiralstep++ )
    {
        if ((-X/2 <= x) && (x <= X/2) && (-Y/2 <= y) && (y <= Y/2))
        {
            int i = x+iStart;
            int j = y+jStart;
            if ( i>0 && i<=nPoints2dx && j>0 && j<=nPoints2dy )
            {
                tScan.Start(false);

                // status bar
                if (((int)nSteps % (int)(nTotalSteps/printFreq)) == 0){
                    cout << Form("MethodDatasetsProbScan::scan2d() : scanning %3.0f%%", (float)nSteps/(float)nTotalSteps*100.)
                                                             << "       \r" << flush;
                }
                nSteps++;

                // status histogram
                if ( spiralstep>0 ) hDbgStart->SetBinContent(i, j, 500./*firstScan ? 1. : hChi2min2dMin+36*/);

                // set start parameters from inner turn of the spiral
                int xStartPars, yStartPars;
                computeInnerTurnCoords(iStart, jStart, i, j, xStartPars, yStartPars, 1);
                RooSlimFitResult *rStartPars = mycurveResults2d[xStartPars-1][yStartPars-1];
                if ( rStartPars ) setParameters(w, parsName, rStartPars);

                // memory management:
                tMemory.Start(false);
                // delete old, inner fit results, that we don't need for start parameters anymore
                // for this we take the second-inner-most turn.
                int iOld, jOld;
                bool innerTurnExists = computeInnerTurnCoords(iStart, jStart, i, j, iOld, jOld, 2);
                if ( innerTurnExists ){
                    deleteIfNotInCurveResults2d(mycurveResults2d[iOld-1][jOld-1]);
                    mycurveResults2d[iOld-1][jOld-1] = 0;
                }
                tMemory.Stop();

                // alternative choice for start parameters: always from what we found at function call
                // setParameters(w, parsName, startPars->get(0));

                // set scan point
                float scanvalue1 = hCL2d->GetXaxis()->GetBinCenter(i);
                float scanvalue2 = hCL2d->GetYaxis()->GetBinCenter(j);
                par1->setVal(scanvalue1);
                par2->setVal(scanvalue2);

                // fit!
                tFit.Start(false);
                RooFitResult *fr;
                // if ( !arg->probforce ) fr = fitToMinBringBackAngles(w->pdf(pdfName), false, -1);
                // else                   fr = fitToMinForce(w, combiner->getPdfName());

                fr = this->loadAndFit(this->pdf);   //Titus: change fitting strategy to the one from the datasets \todo: should be possible to use the fittominforce etc methods
                // double chi2minScan = 2 * fr->minNll(); //Titus: take 2*minNll vs. minNll? Where is the squared in the main gammacombo?
                double chi2minScan = 2 * pdf->getMinNll();
                tFit.Stop();
                tSlimResult.Start(false);
                RooSlimFitResult *r = new RooSlimFitResult(fr); // try to save memory by using the slim fit result
                tSlimResult.Stop();
                delete fr;
                allResults.push_back(r);
                bestMinFoundInScan = TMath::Min((double)chi2minScan, (double)bestMinFoundInScan);
                mycurveResults2d[i-1][j-1] = r;

                // If we find a new global minumum, this means that all
                // previous 1-CL values are too high. We'll save the new possible solution, adjust the global
                // minimum, return a status code, and stop.
                // if ( chi2minScan > -500 && chi2minScan<chi2minGlobal ){      //Titus: the hard coded minimum chi2 to avoid ridiculous minima (e.g. at boundaries) only sensible when using the Utils::fitToMin, since the chi2 of the best fit with that fitting method is nominally 0.
                if ( chi2minScan<chi2minGlobal ){
                    // warn only if there was a significant improvement
                    if ( arg->debug || chi2minScan<chi2minGlobal-1e-2 ){
                        if ( arg->verbose ) cout << "MethodDatasetsProbScan::scan2d() : WARNING : '" << title << "' new global minimum found! chi2minGlobal="
                                                            << chi2minGlobal << " chi2minScan=" << chi2minScan << endl;
                    }
                    chi2minGlobal = chi2minScan;
                    // recompute previous 1-CL values
                    for ( int k=1; k<=hCL2d->GetNbinsX(); k++ )
                        for ( int l=1; l<=hCL2d->GetNbinsY(); l++ ){
                            hCL2d->SetBinContent(k, l, TMath::Prob(hChi2min2d->GetBinContent(k,l)-chi2minGlobal, ndof));
                            hCLs2d->SetBinContent(k, l, TMath::Prob(hChi2min2d->GetBinContent(k,l)-chi2minBkg, ndof));
                        }
                }

                double deltaChi2 = chi2minScan - chi2minGlobal;
                double oneMinusCL = TMath::Prob(deltaChi2, ndof);
                // if ( arg->debug ) {
                //     cout << "chi2minScan: " << chi2minScan << endl;
                //     cout << "chi2minGlobal: " << chi2minGlobal << endl;
                //     cout << "deltaChi2: " << deltaChi2 << endl;
                //     cout << "ndof: " << ndof << endl;
                //     cout << "oneMinusCL: " << oneMinusCL << endl << endl;
                // }


                // Save the 1-CL value. But only if better than before!
                if ( hCL2d->GetBinContent(i, j) < oneMinusCL ){
                    hCL2d->SetBinContent(i, j, oneMinusCL);
                    double cls_pval = chi2minScan > chi2minBkg ? chi2minScan - chi2minBkg : 0.;
                    hCLs2d->SetBinContent(i, j, TMath::Prob(cls_pval, ndof));
                    hChi2min2d->SetBinContent(i, j, chi2minScan);
                    hDbgChi2min2d->SetBinContent(i, j, chi2minScan);
                    curveResults2d[i-1][j-1] = r;
                }

                // draw/update histograms - doing only every 10th update saves
                // a lot of time for small combinations
                if ( ( arg->interactive && ((int)nSteps % 10 == 0) ) || nSteps==nTotalSteps ){
                    hDbgChi2min2d->Draw("colz");
                    hDbgStart->Draw("boxsame");
                    startpointmark->Draw();
                    cDbg->Update();
                }
                tScan.Stop();
            }
        }
        // spiral stuff:
        if( (x == y) || ((x < 0) && (x == -y)) || ((x > 0) && (x == 1-y)))
        {
            t = dx;
            dx = -dy;
            dy = t;
        }
        x += dx;
        y += dy;
    }
    cout << "MethodDatasetsProbScan::scan2d() : scan done.            " << endl;
    if ( arg->debug ){
        cout << "MethodDatasetsProbScan::scan2d() : full scan time:             "; tScan.Print();
        cout << "MethodDatasetsProbScan::scan2d() : - fitting:                  "; tFit.Print();
        cout << "MethodDatasetsProbScan::scan2d() : - create RooSlimFitResults: "; tSlimResult.Print();
        cout << "MethodDatasetsProbScan::scan2d() : - memory management:        "; tMemory.Print();
    }
    setParameters(w, parsName, startPars->get(0));

    saveSolutions2d();
    if ( arg->debug ) printLocalMinima();
    // confirmSolutions(); //Titus: Leave this out for now, since using it requires compatibility to Utils:fitToMin(), which is not achieved yet

    // clean all fit results that didn't make it into the final result
    for ( int i=0; i<allResults.size(); i++ ){
        deleteIfNotInCurveResults2d(allResults[i]);
    }

    if ( bestMinFoundInScan-bestMinOld > 0.1 )
    {
        cout << "MethodDatasetsProbScan::scan2d() : WARNING: Scan didn't find minimum that was found before!" << endl;
        cout << "MethodDatasetsProbScan::scan2d() :          Are you using too strict parameter limits?" << endl;
        cout << "MethodDatasetsProbScan::scan2d() :          min chi2 found in scan: " << bestMinFoundInScan << ", old min chi2: " << bestMinOld << endl;
        return 1;
    }
    return 0;
}