ChristopherMayes / lume-astra

Python wrapper for Astra (A Space Charge Tracking Algorithm, DESY) for eventual use in LUME https://christophermayes.github.io/lume-astra/
https://christophermayes.github.io/lume-astra/
Apache License 2.0
14 stars 9 forks source link

Questions about scanning #8

Open hayg25 opened 3 years ago

hayg25 commented 3 years ago

Dear All,

I would like to perform scan over some variables, for example maxb(1) or Phi(1) etc. I don't understand the use of DISTGEN ? Is it necessary to use Yaml file to perform a scan ? could you provide an example where you perform a scan for example on you tws example ?

thanks for your help

ChristopherMayes commented 3 years ago

@hayg25 Look at: https://github.com/ChristopherMayes/lume-astra/blob/master/examples/scan_example.ipynb

distgen is to create initial particles. You do not need that if your are providing particles.

hayg25 commented 3 years ago

@ChristopherMayes , thanks ! but it uses that function which calls DISTGEN_IN

return evaluate_astra_with_distgen(s, astra_input_file=ASTRA_IN,
                          distgen_input_file=DISTGEN_IN)

How should I proceed If I don't use DISTGEN_IN ?

Thanks again !

ChristopherMayes commented 3 years ago

@hayg25 All look at: https://github.com/ChristopherMayes/lume-astra/blob/master/examples/functional_astra_run.ipynb

There are evaluate_astra and evaluate_astra_with_generator functions.

Alternatively, you can always make a simple function:

def run1(x):
    A = Astra('astra.in')
    A.input['solenoid']['maxb(1)'] = x
    A.run()
    return A

and then loop over some settings:

xlist = np.linspace(0, 0.01, 10)
Alist = [run1(x) for x in xlist]

I can try to make a better example of this.

hayg25 commented 3 years ago

@ChristopherMayes,

Thanks I will try that.

hayg25 commented 3 years ago

Hi @ChristopherMayes, so using you example I got some errors using the tws example :

def run1(x):
    A = Astra(input_file=ASTRA_IN, astra_bin=MY_ASTRA_BIN)
    A.input['solenoid']['maxb(1)'] = x
    A.run()
    return A

xlist = np.linspace(0, 0.01, 10)
Alist = [run1(x) for x in xlist]

output error :

Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []
Run Aborted Stat keys do not all have the same length: []

thanks for the feedback

ChristopherMayes commented 3 years ago

Hi @hayg25, you'll need to make sure that a single run without modifying anything works first.

hayg25 commented 3 years ago

@ChristopherMayes , ok it works fine by using:

def run_phiG(x):
    A = Astra(input_file=ASTRA_IN, initial_particles = P0, astra_bin=MY_ASTRA_BIN, verbose=True)
    A.input['cavity']['phi(1)'] = x
    A.run()
    return A

I don't quite understand the use of :

# Make a robust evaluate
def evaluate(b):
    try:
        s = settings0.copy()
        s['maxb(1)'] = b
        output = evaluate_astra_with_distgen(s, astra_input_file=ASTRA_IN,
                              distgen_input_file=DISTGEN_IN, archive_path=SCRATCH.name)
        # Add the input
        output['maxb(1)'] = b
        output['Exception'] = False
    except:
        output = {}
        output['maxb(1)'] = b
        output['Exception'] = True

    return output 

Is it something which would help when performing scans ? btw how should I proceed to perform scan on 2 or more variables for example. I know It could take time but would something like this work ?

def run_2var(x, y):
    A = Astra(input_file=ASTRA_IN, initial_particles = P0, astra_bin=MY_ASTRA_BIN, verbose=True)
    A.input['cavity']['phi(1)'] = x
    A.input['cavity']['phi(2)'] = y
    A.run()
    return A

Thanks !

ChristopherMayes commented 3 years ago

@hayg25 Ah, your previous ASTRA_IN file didn't have the particles defined. I could probably do some better checking to give you a more informative message.

The reason for the try: except: block is that some of the values you send may crash Astra, and raise and Exception. We don't want that to also crash the scan. Returning some info like output['Exception'] = True helps filter those out in post-processing.

Yes, your second function should work fine.

hayg25 commented 3 years ago

@ChristopherMayes , ok thanks but if I use my 2 variables function how should I run it ? like this ?

results_phiG  =  executor.map(run_phiG_L, phiG_list, phiL_List)

and concerning the try: except: Astra has no output['Exception'] key ...

ChristopherMayes commented 3 years ago

@hayg25 Sorry, I just noticed this reply. You have to pass flat lists/arrays for executor.map. Experiment with it with simple Python functions first.