workflow_sketch.sh 16.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
#!/bin/bash

##############################
# Configurations             #
##############################
# Put aliBuild in the PATH env var
export PATH="/mnt/SSD/schnorr/python/bin:$PATH"
# Directory where runAnalysis.C is placed
export ALIROOT_SCRIPT_DIR=$(pwd)/aliRoot/
10
# Directory where Blender scripts are
11
12
export BLENDER_SCRIPT_DIR=$(pwd)/animate/
# alienv working directory
Breno Rilho Lemos's avatar
Breno Rilho Lemos committed
13
14
export ALIENV_WORK_DIR=/home/breno/alice/sw
export ALIENV_OS_SPEC=ubuntu1804_x86-64
15
export ALIENV_ID=AliPhysics/latest-aliroot5-user
16
# Put Blender 2.79b in the PATH env var
17
18
19
export PATH="/home/schnorr/install/blender-2.79-linux-glibc219-x86_64/:$PATH"

##############################
20
# Command-line options       #
21
##############################
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# See the following link to understand the code below
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash

# saner programming env: these switches turn some bugs into errors
set -o errexit -o pipefail -o noclobber -o nounset

# -allow a command to fail with !’s side effect on errexit
# -use return value from ${PIPESTATUS[0]}, because ! hosed $?
! getopt --test > /dev/null
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
    echo 'I’m sorry, `getopt --test` failed in this environment.'
    exit 1
fi

36
OPTIONS=c:hdau:m:n:t:r:
37
LONGOPTS=cameras:,mosaic,resolution:,fps:,transparency:,duration:,maxparticles:,\
38
minparticles:,numberofevents:,minavgpz:,minavgpt:,help,download,sample,url:,its,\
39
tpc,detailedtpc,trd,emcal,blendersave,picpct:
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# -regarding ! and PIPESTATUS see above
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out “--options”)
# -pass arguments only via   -- "$@"   to separate them correctly
! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@")
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
    # e.g. return value is 1
    #  then getopt has complained about wrong arguments to stdout
    exit 2
fi
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"

54
55
56
##############################
# Parse Parameters           #
##############################
57
CAMERAS=Overview
58
MOSAIC=false
59
60
DURATION=10
RESOLUTION=100
61
FPS=24
62
TRANSPARENCY=1
63
64
65
MAX_PARTICLES=1000
MIN_PARTICLES=0
N_OF_EVENTS=10
66
MIN_AVG_PZ=0
67
MIN_AVG_PT=0
68
69
HELP=false
DOWNLOAD=false
70
SAMPLE=false
71
URL=
72
73
ITS=1 # 1 means "build this detector", while 0 means "don't"
TPC=1
74
DETAILED_TPC=0
75
76
TRD=1
EMCAL=1
77
BLENDERSAVE=0
78
PICPCT=80
79
80
81
# now enjoy the options in order and nicely split until we see --
while true; do
    case "$1" in
82
83
84
85
86
      -h|--help)
          HELP=true
          shift
          break
          ;;
87
      -d|--download)
88
89
90
          DOWNLOAD=true
          shift
          ;;
91
      -a|--sample)
92
93
94
          SAMPLE=true
          shift
          ;;
95
96
      -u|--url)
          URL="$2"
97
98
            shift 2
            ;;
99
100
101
102
      -m|--maxparticles)
          MAX_PARTICLES="$2"
          shift 2
          ;;
103
104
105
106
107
108
109
110
      --minparticles)
          MIN_PARTICLES="$2"
          shift 2
          ;;
      -n|--numberofevents)
          N_OF_EVENTS="$2"
          shift 2
          ;;
111
112
113
114
      --minavgpz)
          MIN_AVG_PZ="$2"
          shift 2
          ;;
115
116
117
118
      --minavgpt)
          MIN_AVG_PT="$2"
          shift 2
          ;;
119
120
121
122
123
124
125
126
      -t|--duration)
          DURATION="$2"
          shift 2
          ;;
      -r|--resolution)
          RESOLUTION="$2"
          shift 2
          ;;
127
128
129
130
      --fps)
          FPS="$2"
          shift 2
          ;;
131
132
      --transparency)
          TRANSPARENCY="$2"
133
134
          shift 2
          ;;
135
136
      -c|--cameras)
      	  CAMERAS="$2"
137
138
      	  shift 2
      	  ;;
139
140
141
142
      --mosaic)
          MOSAIC=true
          shift
          ;;
143
144
145
146
      --picpct)
      	  PICPCT="$2"
      	  shift 2
      	  ;;
147
      --its)
148
149
150
          ITS=0
          shift
          ;;
151
      --tpc)
152
153
154
          TPC=0
          shift
          ;;
155
156
157
158
      --detailedtpc)
          DETAILED_TPC=1
          shift
          ;;
159
      --trd)
160
161
162
          TRD=0
          shift
          ;;
163
      --emcal)
164
165
166
          EMCAL=0
          shift
          ;;
167
168
169
170
      --blendersave)
          BLENDERSAVE=1
          shift
          ;;
171
172
173
174
175
        --)
            shift
            break
            ;;
        *)
176
            echo "Programming error $*"
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
            exit 3
            ;;
    esac
done

##############################
# Usage                      #
##############################
function usage()
{
    # Using a here doc with standard out.
    cat <<-END
Usage:
------
   -h | --help
     Display this help
   -d | --download
     Download the AliESDs.root file using the provided URL
   -u | --url URL
     Provide the URL to uniquely identify a AliESDs.root dataset.
     This should be in the format provided by http://opendata.cern.ch.
     See example below.
199
   -m | --maxparticles VALUE
200
201
     Get only events for which its number of particles does not
     exceed VALUE.
202
   --minparticles VALUE
203
204
     Get only events for which its number of particles is greater than
     or equal to VALUE.
205
   -n | --numberofevents VALUE
206
     Set number of events to be animated inside chosen ESD file (defaults to 10)
207
208
   --minavgpz VALUE
     Get only events for which its absolute value of average momentum in
209
210
     the z direction is greater than or equal to VALUE, in GeV/c. Useful
     for animating events with 'boosts' of particles to the same side.
211
212
   --minavgpt VALUE
     Get only events for which its average transversal momentum is
213
214
     greater than or equal to VALUE, in GeV/c. Useful for animating
     events with 'boosts' of particles on the xy plane.
215
216
217
   -t | --duration VALUE
     Set the animation duration in seconds.
   -r | --resolution VALUE
218
219
     Set the animation resolution percentage, where
     VALUE must be an integer from 1 to 100.
220
221
   --fps VALUE
     Set number of frames per second in animation.
222
223
224
   --transparency VALUE
     Set detector transparency as a number greater than zero,
     where zero is full transparency and 1 is standard transparency
225
226
   -c | --cameras VALUE
     Which cameras to use for the animation, where VALUE
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
227
     is a comma-separated list (without spaces)
228
     Options: Barrel,Side,Forward,Overview (defaults to Overview)
229
230
231
232
   --mosaic
     Make animations in all four available cameras and combine them into
     a single 2x2 clip containing all perspectives, totalizing five generated
     .mp4 videos.
233
   --picpct VALUE
234
235
     Percentage of animation to take HD picture, saved along with the clip,
     where VALUE must be an integer
236
   -a | --sample
237
     Creates a sample Blender animation of Event 2 from URL
238
239
     http://opendata.cern.ch/record/1102/files/assets/alice/2010/LHC10h/000139\
038/ESD/0001/AliESDs.root
240
   --its
241
     Removes ITS detector from animation
242
243
   --detailedtpc
     Includes more detailed version of TPC in animation
244
   --tpc
245
     Removes TPC detector from animation
246
   --trd
247
     Removes TRD detector from animation
248
   --emcal
249
     Removes EMCal detector from animation
250
251
   --blendersave
     Saves Blender file along with animation clip
252
253
254

Example:
--------
255
256
$0 --url http://opendata.cern.ch/record/1103/files/assets/alice/2010/LHC10h/000\
139173/ESD/0004/AliESDs.root --download
257
258
259

END
}
260

Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
261
# Fix CAMERA to be accepted by the for loop
262
263
if [[ $CAMERAS != "" ]]; then
    CAMERAS=$(echo $CAMERAS | sed -e 's#,#Camera #g' -e 's#$#Camera#')
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
264
265
fi

266
if [[ $MOSAIC == "true" ]]; then
267
    CAMERAS=$(echo "OverviewCamera BarrelCamera SideCamera ForwardCamera")
268
269
fi

270
271
272
273
274
275
276
if [[ $HELP = "true" ]]; then
    usage
    exit
else
    echo "-------- Parsed parameters --------"
    echo "URL: $URL"
    echo "Download: $DOWNLOAD"
277
    echo "Sample: $SAMPLE"
278
    echo "Transparency Parameter: $TRANSPARENCY"
279
280
    echo "Duration: $DURATION"
    echo "Resolution: $RESOLUTION"
281
    echo "FPS: $FPS"
282
    echo "Max particles: ${MAX_PARTICLES}"
283
284
    echo "Min particles: ${MIN_PARTICLES}"
    echo "Number of events: ${N_OF_EVENTS}"
285
    echo "Min Average Z Momentum: ${MIN_AVG_PZ}"
286
    echo "Min Average Transversal Momentum: ${MIN_AVG_PT}"
287
    echo "Cameras: $CAMERAS"
288
    echo "Mosaic: $MOSAIC"
289
    echo "Picture Percentage: ${PICPCT}%"
290
    echo "-----------------------------------"
291
292
293
294
    echo "------------ Detectors ------------"
    if [[ $ITS = 1 ]]; then
      echo "Building ITS"
    fi
295
296
297
298
299
300
    if [[ $DETAILED_TPC = 1 ]]; then
      echo "Building detailed TPC"
    else
      if [[ $TPC = 1 ]]; then
        echo "Building TPC"
      fi
301
302
303
304
305
306
307
308
309
310
311
312
    fi
    if [[ $TRD = 1 ]]; then
      echo "Building TRD"
    fi
    if [[ $EMCAL = 1 ]]; then
      echo "Building EMCAL"
    fi
    if [[ $TPC = 0 && $TPC = 0 && $TRD = 0 && $EMCAL = 0 ]]; then
      echo "Not building any detectors"
    fi
    echo "-----------------------------------"

313
314
fi

315
316
317
318
319
320
321
# handle non-option arguments
if [[ $# -ne 0 ]]; then
    echo "$0: non-option arguments ($#, $*) are ignored."
    echo "Remove them manually as indicated between parenthesis."
    exit
fi

322
323
324
325
##############################
# Download Dataset           #
##############################
if [ "$DOWNLOAD" = "true" ]; then
326
    if [ -z $URL ]; then
327
        echo "Error. Must pass the dataset URL in order to download ESD file."
328
329
330
        usage
        exit
    fi
331
332
333
    echo "Downloading data."
    wget $URL

334
335
336
337
338
339
340
341
342
343
344
345
    ######################################
    # Established Unique ID based on URL #
    ######################################
    UNIQUEID=$(echo $URL | sed \
                         -e "s#http://opendata.cern.ch/##" \
                         -e "s#/AliESDs.root##" \
                         -e "s#files/assets/##" \
                         -e "s#/#_#g")

    echo "The unique ID is $UNIQUEID."

fi
346

347
##############################
348
# Sample synthetic animation#
349
##############################
350
if [ "$SAMPLE" = "true" ]; then
351
    ##############################
352
    # Phase 1: Blender animate   #
353
354
    ##############################
    pushd ${BLENDER_SCRIPT_DIR}
355
356
357
358
359
360
361
362
363
    echo "Preparing sample animation in Blender"

    blender -noaudio --background -P animate_particles.py -- -radius=0.05 \
    -duration=${DURATION} -cameras="${CAMERAS}" -datafile="d-esd-detail.dat" -simulated_t=0.03\
    -fps=${FPS} -resolution=${RESOLUTION} -transparency=${TRANSPARENCY} -stamp_note=\
    "opendata.cern.ch_record_1102_alice_2010_LHC10h_000139038_ESD_0001_2" -its=${ITS} \
    -tpc=${TPC} -trd=${TRD} -emcal=${EMCAL} -detailed_tpc=${DETAILED_TPC} \
    -blendersave=${BLENDERSAVE} -picpct=${PICPCT} -tpc_blender_path=${BLENDER_SCRIPT_DIR}

364
    popd
365
    BLENDER_OUTPUT=.
366
    mkdir --verbose -p ${BLENDER_OUTPUT}
367
    mv --verbose /tmp/alice_blender ${BLENDER_OUTPUT}
368
369
    echo "Done."

370
371
372
##############################
# Animation from file        #
##############################
373
elif [ "$SAMPLE" = "false" ]; then
374

375
  # Verify if AliESDs.root is here
376
377
378
  ALIESD_ROOT_FILE=$(pwd)/AliESDs.root
  if ! [[ -f "$ALIESD_ROOT_FILE" ]]
  then
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
379
380
      echo "AliESDs.root not found."
      exit
381
382
  fi

383
384
385
  ############################
  # Phase 1: aliroot extract #
  ############################
386
  eval $(alienv -w ${ALIENV_WORK_DIR} -a ${ALIENV_OS_SPEC} load ${ALIENV_ID})
387
  pushd ${ALIROOT_SCRIPT_DIR}
388
  # Remove existing symbolic link
389
  rm -f --verbose AliESDs.root
390
391
392
  # Create a symbolic link to the actual AliESDs.root
  ln --verbose -s ${ALIESD_ROOT_FILE} AliESDs.root
  # Run the extraction tool
393
  aliroot runAnalysis.C
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
  if [ "$DOWNLOAD" = "false" ]; then

    UNIQUEID=$(more uniqueid.txt)
    echo "The unique ID is $UNIQUEID."
    rm uniqueid.txt

  fi

  # Create directory where animations will be saved
  popd
  BLENDER_OUTPUT=$(pwd)/$UNIQUEID
  mkdir --verbose -p ${BLENDER_OUTPUT}
  pushd ${ALIROOT_SCRIPT_DIR} # push back to aliroot directory

409
410
411
  #################################################
  # Phase 1: iteration for every event identifier #
  #################################################
412

413
414
415
  # Event counter for animating no more events than the informed amount
  EVENT_COUNTER=0

416
417
418
419
  # Get all extracted files
  EXTRACTED_FILES=$(ls -1 esd_detail-event_*.dat | sort --version-sort)
  for FILE_WITH_DATA in $EXTRACTED_FILES; do
      EVENT_ID=$(echo $FILE_WITH_DATA | \
420
421
                 sed -e "s#esd_detail-event_##" \
                   -e "s#\.dat##")
422
423
      EVENT_UNIQUE_ID=${UNIQUEID}_${EVENT_ID}

Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
424
      if ! [[ -s $FILE_WITH_DATA ]]; then
425
          echo "File $FILE_WITH_DATA has zero size. Ignore and continue."
426
	        rm $FILE_WITH_DATA
427
          continue
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
428
      fi
429

430
431
432
      ##############################
      # Phase 2: blender animate   #
      ##############################
433
434
435

      LOCAL_FILE_WITH_DATA=${EVENT_UNIQUE_ID}.dat
      cp ${ALIROOT_SCRIPT_DIR}/$FILE_WITH_DATA \
436
437
       ${BLENDER_SCRIPT_DIR}/${LOCAL_FILE_WITH_DATA}

438
439
      rm $FILE_WITH_DATA

440
441
      NUMBER_OF_PARTICLES=$(wc -l ${BLENDER_SCRIPT_DIR}/$LOCAL_FILE_WITH_DATA | \
                        awk '{ print $1 }')
442

443
444
      AVERAGE_PZ=$(awk 'BEGIN {pzsum=0;n=0} {pzsum+=$8;n++} END {print sqrt(pzsum*pzsum/n/n)}'\
      ${BLENDER_SCRIPT_DIR}/${LOCAL_FILE_WITH_DATA})
445

446
447
      AVERAGE_PT=$(awk 'BEGIN {ptsum=0;n=0} {ptsum+=$9;n++} END {print ptsum/n}' \
      ${BLENDER_SCRIPT_DIR}/${LOCAL_FILE_WITH_DATA})
448

449
450
451
      echo "File $LOCAL_FILE_WITH_DATA has $NUMBER_OF_PARTICLES particles."
      echo "Average Z momentum: $AVERAGE_PZ"
      echo "Average transversal momentum $AVERAGE_PT"
452

453
454
      if (( $(echo "$AVERAGE_PT >= $MIN_AVG_PT" |bc -l) )); then
        if (( $(echo "$AVERAGE_PZ >= $MIN_AVG_PZ" |bc -l) )); then
455
456
          if [[ $NUMBER_OF_PARTICLES -le $MAX_PARTICLES && $NUMBER_OF_PARTICLES \
-ge $MIN_PARTICLES && $EVENT_COUNTER -lt $N_OF_EVENTS ]]; then
457

458
459
            # Increment event counter
            EVENT_COUNTER=$EVENT_COUNTER+1
460

461
            echo "Processing ${EVENT_UNIQUE_ID} ($NUMBER_OF_PARTICLES tracks) in Blender"
462

463
            pushd ${BLENDER_SCRIPT_DIR}
464

465
466
467
468
469
470
471
472
473
474
475

            echo "Processing ${EVENT_UNIQUE_ID} in Blender"

            blender -noaudio --background -P animate_particles.py -- -radius=0.05 \
            -duration=${DURATION} -cameras="${CAMERAS}" -datafile="${LOCAL_FILE_WITH_DATA}"\
             -n_event=${EVENT_ID} -simulated_t=0.03 -fps=${FPS} -resolution=${RESOLUTION}\
             -transparency=${TRANSPARENCY} -stamp_note="${EVENT_UNIQUE_ID}" -its=${ITS}\
             -tpc=${TPC} -trd=${TRD} -emcal=${EMCAL} -detailed_tpc=${DETAILED_TPC} \
            -blendersave=${BLENDERSAVE} -picpct=${PICPCT} -tpc_blender_path=${BLENDER_SCRIPT_DIR}
            echo "Event ${EVENT_UNIQUE_ID} done."

476

477
478
479
480
481
482
483
484
485
486
487
488
489
490
            if [ "$MOSAIC" = "true" ]; then

              popd
              pushd /tmp/alice_blender

              # Move animation images to final location
              mv /tmp/alice_blender/*.png ${BLENDER_OUTPUT}

              # Setting input names for clips in order to make mosaic clip
              INPUT_ONE=$(ls | awk 'NR==1')
              INPUT_TWO=$(ls | awk 'NR==2')
              INPUT_THREE=$(ls | awk 'NR==3')
              INPUT_FOUR=$(ls | awk 'NR==4')

491
492
493
              ffmpeg -i ${INPUT_FOUR} -i ${INPUT_TWO} -i ${INPUT_THREE} -i ${INPUT_ONE} -filter_complex\
               "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2[v]"\
               -map "[v]" ${EVENT_UNIQUE_ID}_Mosaic.mp4
494
495
496
497
498
499
500
501
502

              popd
              pushd ${BLENDER_SCRIPT_DIR}

            fi

            # Move generated clips to final location
            mv /tmp/alice_blender/* ${BLENDER_OUTPUT}

503
504
            # Move processed file to final location
            mv $LOCAL_FILE_WITH_DATA ${BLENDER_OUTPUT}/$LOCAL_FILE_WITH_DATA
505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
            popd
            echo "EVENT ${EVENT_UNIQUE_ID} DONE with FILE $LOCAL_FILE_WITH_DATA."
          else

            if [[ $NUMBER_OF_PARTICLES -lt $MIN_PARTICLES ]]; then
              echo "Too little particles (minimum accepted is $MIN_PARTICLES). Continue."
            elif [[ $NUMBER_OF_PARTICLES -gt $MAX_PARTICLES ]]; then
              echo "Too many particles (maximum accepted is $MAX_PARTICLES). Continue."
            elif [[ $EVENT_COUNTER -ge $N_OF_EVENTS ]]; then
              echo "Numbers of events set to be animated has already been reached. Continue."
            fi

            # Remove non-processed files
            pushd ${BLENDER_SCRIPT_DIR}
            rm $LOCAL_FILE_WITH_DATA
            popd

            continue
524
          fi
525
526
        else
          echo "Average Z Momentum too low (minimum accepted is $MIN_AVG_PZ). Continue."
527

528
529
530
531
532
533
          # Remove non-processed files
          pushd ${BLENDER_SCRIPT_DIR}
          rm $LOCAL_FILE_WITH_DATA
          popd
        fi
      else
534
        echo "Average Transversal Momentum too low (minimum accepted is $MIN_AVG_PT). Continue."
535
536
537
538
539

        # Remove non-processed files
        pushd ${BLENDER_SCRIPT_DIR}
        rm $LOCAL_FILE_WITH_DATA
        popd
540
      fi
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
541
  done
542
  popd
543

544
fi