workflow_sketch.sh 15.8 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=camera:,mosaic,resolution:,fps:,transparency:,duration:,maxparticles:,minparticles:,numberofevents:,minavgpz:,minavgpt:,help,download,sample,url:,its,tpc,trd,emcal,blendersave,picpct:
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# -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"

52
53
54
##############################
# Parse Parameters           #
##############################
55
CAMERA=Overview
56
MOSAIC=false
57
58
DURATION=10
RESOLUTION=100
59
FPS=24
60
TRANSPARENCY=1
61
62
63
MAX_PARTICLES=1000
MIN_PARTICLES=0
N_OF_EVENTS=10
64
MIN_AVG_PZ=0
65
MIN_AVG_PT=0
66
67
HELP=false
DOWNLOAD=false
68
SAMPLE=false
69
URL=
70
71
72
73
ITS=1 # 1 means "build this detector", while 0 means "don't"
TPC=1
TRD=1
EMCAL=1
74
BLENDERSAVE=0
75
PICPCT=80
76
77
78
# now enjoy the options in order and nicely split until we see --
while true; do
    case "$1" in
79
80
81
82
83
      -h|--help)
          HELP=true
          shift
          break
          ;;
84
      -d|--download)
85
86
87
          DOWNLOAD=true
          shift
          ;;
88
      -a|--sample)
89
90
91
          SAMPLE=true
          shift
          ;;
92
93
      -u|--url)
          URL="$2"
94
95
            shift 2
            ;;
96
97
98
99
      -m|--maxparticles)
          MAX_PARTICLES="$2"
          shift 2
          ;;
100
101
102
103
104
105
106
107
      --minparticles)
          MIN_PARTICLES="$2"
          shift 2
          ;;
      -n|--numberofevents)
          N_OF_EVENTS="$2"
          shift 2
          ;;
108
109
110
111
      --minavgpz)
          MIN_AVG_PZ="$2"
          shift 2
          ;;
112
113
114
115
      --minavgpt)
          MIN_AVG_PT="$2"
          shift 2
          ;;
116
117
118
119
120
121
122
123
      -t|--duration)
          DURATION="$2"
          shift 2
          ;;
      -r|--resolution)
          RESOLUTION="$2"
          shift 2
          ;;
124
125
126
127
      --fps)
          FPS="$2"
          shift 2
          ;;
128
129
      --transparency)
          TRANSPARENCY="$2"
130
131
          shift 2
          ;;
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
132
      -c|--camera)
133
134
135
      	  CAMERA="$2"
      	  shift 2
      	  ;;
136
137
138
139
      --mosaic)
          MOSAIC=true
          shift
          ;;
140
141
142
143
      --picpct)
      	  PICPCT="$2"
      	  shift 2
      	  ;;
144
      --its)
145
146
147
          ITS=0
          shift
          ;;
148
      --tpc)
149
150
151
          TPC=0
          shift
          ;;
152
      --trd)
153
154
155
          TRD=0
          shift
          ;;
156
      --emcal)
157
158
159
          EMCAL=0
          shift
          ;;
160
161
162
163
      --blendersave)
          BLENDERSAVE=1
          shift
          ;;
164
165
166
167
168
        --)
            shift
            break
            ;;
        *)
169
            echo "Programming error $*"
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
            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.
192
   -m | --maxparticles VALUE
193
194
     Get only events for which its number of particles does not
     exceed VALUE.
195
   --minparticles VALUE
196
197
     Get only events for which its number of particles is greater than
     or equal to VALUE.
198
199
   -n | --numberofevents VALUE
     Set number of events to be animated inside chosen ESD file.
200
201
202
203
   --minavgpz VALUE
     Get only events for which its absolute value of average momentum in
     the z direction is greater than or equal to VALUE. Useful for animating
     events with 'boosts' of particles to the same side.
204
205
206
207
   --minavgpt VALUE
     Get only events for which its average transversal momentum is
     greater than or equal to VALUE. Useful for animating events with
     'boosts' of particles on the xy plane.
208
209
210
211
   -t | --duration VALUE
     Set the animation duration in seconds.
   -r | --resolution VALUE
     Set the animation resolution percentage.
212
213
   --fps VALUE
     Set number of frames per second in animation.
214
215
216
   --transparency VALUE
     Set detector transparency as a number greater than zero,
     where zero is full transparency and 1 is standard transparency
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
217
218
219
   -c | --camera VALUE
     Which camera to use for the animation, where VALUE
     is a comma-separated list (without spaces)
Breno Rilho Lemos's avatar
Breno Rilho Lemos committed
220
     Options: Barrel,Forward,Overview,AntiOverview (defaults to Overview)
221
222
223
224
   --mosaic
     Make animations in all four available cameras and combine them into
     a single 2x2 clip containing all perspectives, totalizing five generated
     .mp4 videos.
225
226
   --picpct VALUE
     Percentage of animation to take HD picture, saved along with the clip.
227
   -a | --sample
228
229
     Creates a sample Blender animation of Event 2 from URL
     http://opendata.cern.ch/record/1102/files/assets/alice/2010/LHC10h/000139038/ESD/0001/AliESDs.root
230
   --its
231
     Removes ITS detector from animation
232
   --tpc
233
     Removes TPC detector from animation
234
   --trd
235
     Removes TRD detector from animation
236
   --emcal
237
     Removes EMCal detector from animation
238
239
   --blendersave
     Saves Blender file along with animation clip
240
241
242
243
244
245
246

Example:
--------
$0 --url http://opendata.cern.ch/record/1103/files/assets/alice/2010/LHC10h/000139173/ESD/0004/AliESDs.root --download

END
}
247

Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
248
249
250
251
252
# Fix CAMERA to be accepted by the for loop
if [[ $CAMERA != "" ]]; then
    CAMERA=$(echo $CAMERA | sed -e 's#,#Camera #g' -e 's#$#Camera#')
fi

253
254
255
256
if [[ $MOSAIC == "true" ]]; then
    CAMERA=$(echo "OverviewCamera BarrelCamera AntiOverviewCamera ForwardCamera")
fi

257
258
259
260
261
262
263
if [[ $HELP = "true" ]]; then
    usage
    exit
else
    echo "-------- Parsed parameters --------"
    echo "URL: $URL"
    echo "Download: $DOWNLOAD"
264
    echo "Sample: $SAMPLE"
265
    echo "Transparency Parameter: $TRANSPARENCY"
266
267
    echo "Duration: $DURATION"
    echo "Resolution: $RESOLUTION"
268
    echo "FPS: $FPS"
269
    echo "Max particles: ${MAX_PARTICLES}"
270
271
    echo "Min particles: ${MIN_PARTICLES}"
    echo "Number of events: ${N_OF_EVENTS}"
272
    echo "Min Average Z Momentum: ${MIN_AVG_PZ}"
273
    echo "Min Average Transversal Momentum: ${MIN_AVG_PT}"
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
274
    echo "Camera: $CAMERA"
275
    echo "Mosaic: $MOSAIC"
276
    echo "Picture Percentage: ${PICPCT}%"
277
    echo "-----------------------------------"
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    echo "------------ Detectors ------------"
    if [[ $ITS = 1 ]]; then
      echo "Building ITS"
    fi
    if [[ $TPC = 1 ]]; then
      echo "Building TPC"
    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 "-----------------------------------"

296
297
fi

298
299
300
301
302
303
304
# 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

305
306
307
308
##############################
# Download Dataset           #
##############################
if [ "$DOWNLOAD" = "true" ]; then
309
    if [ -z $URL ]; then
310
        echo "Error. Must pass the dataset URL in order to download ESD file."
311
312
313
        usage
        exit
    fi
314
315
316
    echo "Downloading data."
    wget $URL

317
318
319
320
321
322
323
324
325
326
327
328
    ######################################
    # 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
329

330
##############################
331
# Sample synthetic animation#
332
##############################
333
if [ "$SAMPLE" = "true" ]; then
334
    ##############################
335
    # Phase 1: Blender animate   #
336
337
    ##############################
    pushd ${BLENDER_SCRIPT_DIR}
338
    for type in $CAMERA; do
339
      echo "Preparing sample animation with $type in Blender"
340
      blender -noaudio --background -P animate_particles.py -- -radius=0.05 -duration=${DURATION} -camera=${type} -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} -blendersave=${BLENDERSAVE} -picpct=5
341
    done
342
    popd
343
    BLENDER_OUTPUT=.
344
    mkdir --verbose -p ${BLENDER_OUTPUT}
345
    mv --verbose /tmp/alice_blender ${BLENDER_OUTPUT}
346
347
    echo "Done."

348
349
350
##############################
# Animation from file        #
##############################
351
elif [ "$SAMPLE" = "false" ]; then
352

353
  # Verify if AliESDs.root is here
354
355
356
  ALIESD_ROOT_FILE=$(pwd)/AliESDs.root
  if ! [[ -f "$ALIESD_ROOT_FILE" ]]
  then
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
357
358
      echo "AliESDs.root not found."
      exit
359
360
  fi

361
362
363
  ############################
  # Phase 1: aliroot extract #
  ############################
364
  eval $(alienv -w ${ALIENV_WORK_DIR} -a ${ALIENV_OS_SPEC} load ${ALIENV_ID})
365
  pushd ${ALIROOT_SCRIPT_DIR}
366
  # Remove existing symbolic link
367
  rm -f --verbose AliESDs.root
368
369
370
  # Create a symbolic link to the actual AliESDs.root
  ln --verbose -s ${ALIESD_ROOT_FILE} AliESDs.root
  # Run the extraction tool
371
  aliroot runAnalysis.C
372

373
374
375
376
377
378
379
380
381
382
383
384
385
386
  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

387
388
389
  #################################################
  # Phase 1: iteration for every event identifier #
  #################################################
390

391
392
393
  # Event counter for animating no more events than the informed amount
  EVENT_COUNTER=0

394
395
396
397
  # 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 | \
398
399
                 sed -e "s#esd_detail-event_##" \
                   -e "s#\.dat##")
400
401
      EVENT_UNIQUE_ID=${UNIQUEID}_${EVENT_ID}

Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
402
      if ! [[ -s $FILE_WITH_DATA ]]; then
403
          echo "File $FILE_WITH_DATA has zero size. Ignore and continue."
404
	        rm $FILE_WITH_DATA
405
          continue
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
406
      fi
407

408
409
410
      ##############################
      # Phase 2: blender animate   #
      ##############################
411
412
413

      LOCAL_FILE_WITH_DATA=${EVENT_UNIQUE_ID}.dat
      cp ${ALIROOT_SCRIPT_DIR}/$FILE_WITH_DATA \
414
415
       ${BLENDER_SCRIPT_DIR}/${LOCAL_FILE_WITH_DATA}

416
417
      rm $FILE_WITH_DATA

418
419
      NUMBER_OF_PARTICLES=$(wc -l ${BLENDER_SCRIPT_DIR}/$LOCAL_FILE_WITH_DATA | \
                        awk '{ print $1 }')
420

421
422
      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})

423
      AVERAGE_PT=$(awk 'BEGIN {ptsum=0;n=0} {ptsum+=$9;n++} END {print ptsum/n}' ${BLENDER_SCRIPT_DIR}/${LOCAL_FILE_WITH_DATA})
424

425
426
427
      echo "File $LOCAL_FILE_WITH_DATA has $NUMBER_OF_PARTICLES particles."
      echo "Average Z momentum: $AVERAGE_PZ"
      echo "Average transversal momentum $AVERAGE_PT"
428

429
430
431
      if (( $(echo "$AVERAGE_PT >= $MIN_AVG_PT" |bc -l) )); then
        if (( $(echo "$AVERAGE_PZ >= $MIN_AVG_PZ" |bc -l) )); then
          if [[ $NUMBER_OF_PARTICLES -le $MAX_PARTICLES && $NUMBER_OF_PARTICLES -ge $MIN_PARTICLES && $EVENT_COUNTER -lt $N_OF_EVENTS ]]; then
432

433
434
            # Increment event counter
            EVENT_COUNTER=$EVENT_COUNTER+1
435

436
            echo "Processing ${EVENT_UNIQUE_ID} ($NUMBER_OF_PARTICLES tracks) in Blender"
437

438
            pushd ${BLENDER_SCRIPT_DIR}
439

440
441
            for type in $CAMERA; do
                  echo "Processing ${EVENT_UNIQUE_ID} with $type in Blender"
442

443
                  blender -noaudio --background -P animate_particles.py -- -radius=0.05 -duration=${DURATION} -camera=${type} -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} -blendersave=${BLENDERSAVE} -picpct=${PICPCT}
444
445
                  echo "${type} for event ${EVENT_UNIQUE_ID} done."
            done
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
            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')

              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

              popd
              pushd ${BLENDER_SCRIPT_DIR}

            fi

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

471
472
            # Move processed file to final location
            mv $LOCAL_FILE_WITH_DATA ${BLENDER_OUTPUT}/$LOCAL_FILE_WITH_DATA
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
            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
492
          fi
493
494
        else
          echo "Average Z Momentum too low (minimum accepted is $MIN_AVG_PZ). Continue."
495

496
497
498
499
500
501
          # Remove non-processed files
          pushd ${BLENDER_SCRIPT_DIR}
          rm $LOCAL_FILE_WITH_DATA
          popd
        fi
      else
502
        echo "Average Transversal Momentum too low (minimum accepted is $MIN_AVG_PT). Continue."
503
504
505
506
507

        # Remove non-processed files
        pushd ${BLENDER_SCRIPT_DIR}
        rm $LOCAL_FILE_WITH_DATA
        popd
508
      fi
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
509
  done
510
  popd
511

512
fi