workflow_sketch.sh 13.2 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
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:,resolution:,fps:,transparency:,duration:,maxparticles:,minparticles:,numberofevents:,minavgpz:,help,download,sample,url:,its,tpc,trd,emcal
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 57
DURATION=10
RESOLUTION=100
58
FPS=24
59
TRANSPARENCY=1
60 61 62
MAX_PARTICLES=1000
MIN_PARTICLES=0
N_OF_EVENTS=10
63
MIN_AVG_PZ=0
64 65
HELP=false
DOWNLOAD=false
66
SAMPLE=false
67
URL=
68 69 70 71
ITS=1 # 1 means "build this detector", while 0 means "don't"
TPC=1
TRD=1
EMCAL=1
72 73 74
# now enjoy the options in order and nicely split until we see --
while true; do
    case "$1" in
75 76 77 78 79
      -h|--help)
          HELP=true
          shift
          break
          ;;
80
      -d|--download)
81 82 83
            DOWNLOAD=true
            shift
            ;;
84 85
      -a|--sample)
            SAMPLE=true
86 87
            shift
            ;;
88 89
      -u|--url)
          URL="$2"
90 91
            shift 2
            ;;
92 93 94 95
      -m|--maxparticles)
          MAX_PARTICLES="$2"
          shift 2
          ;;
96 97 98 99 100 101 102 103
      --minparticles)
          MIN_PARTICLES="$2"
          shift 2
          ;;
      -n|--numberofevents)
          N_OF_EVENTS="$2"
          shift 2
          ;;
104 105 106 107
      --minavgpz)
          MIN_AVG_PZ="$2"
          shift 2
          ;;
108 109 110 111 112 113 114 115
      -t|--duration)
          DURATION="$2"
          shift 2
          ;;
      -r|--resolution)
          RESOLUTION="$2"
          shift 2
          ;;
116 117 118 119
      --fps)
          FPS="$2"
          shift 2
          ;;
120 121
      --transparency)
          TRANSPARENCY="$2"
122 123
          shift 2
          ;;
124
      -c|--camera)
125 126 127
      	  CAMERA="$2"
      	  shift 2
      	  ;;
128
      --its)
129 130 131
          ITS=0
          shift
          ;;
132
      --tpc)
133 134 135
          TPC=0
          shift
          ;;
136
      --trd)
137 138 139
          TRD=0
          shift
          ;;
140
      --emcal)
141 142 143
          EMCAL=0
          shift
          ;;
144 145 146 147 148
        --)
            shift
            break
            ;;
        *)
149
            echo "Programming error $*"
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
            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.
172
   -m | --maxparticles VALUE
173 174
     Get only events for which its number of particles does not
     exceed VALUE.
175
   --minparticles VALUE
176 177
     Get only events for which its number of particles is greater than
     or equal to VALUE.
178 179
   -n | --numberofevents VALUE
     Set number of events to be animated inside chosen ESD file.
180 181 182 183
   --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.
184 185 186 187
   -t | --duration VALUE
     Set the animation duration in seconds.
   -r | --resolution VALUE
     Set the animation resolution percentage.
188 189
   --fps VALUE
     Set number of frames per second in animation.
190 191 192
   --transparency VALUE
     Set detector transparency as a number greater than zero,
     where zero is full transparency and 1 is standard transparency
193 194 195 196
   -c | --camera VALUE
     Which camera to use for the animation, where VALUE
     is a comma-separated list (without spaces)
     Options: Barrel,Forward,Overview (defaults to Barrel)
197
   -a | --sample
198 199
     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
200
   --its
201
     Removes ITS detector from animation
202
   --tpc
203
     Removes TPC detector from animation
204
   --trd
205
     Removes TRD detector from animation
206
   --emcal
207
     Removes EMCal detector from animation
208 209 210 211 212 213 214

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

END
}
215

216 217 218 219 220
# Fix CAMERA to be accepted by the for loop
if [[ $CAMERA != "" ]]; then
    CAMERA=$(echo $CAMERA | sed -e 's#,#Camera #g' -e 's#$#Camera#')
fi

221 222 223 224 225 226 227
if [[ $HELP = "true" ]]; then
    usage
    exit
else
    echo "-------- Parsed parameters --------"
    echo "URL: $URL"
    echo "Download: $DOWNLOAD"
228
    echo "Sample: $SAMPLE"
229
    echo "Transparency Parameter: $TRANSPARENCY"
230 231
    echo "Duration: $DURATION"
    echo "Resolution: $RESOLUTION"
232
    echo "FPS: $FPS"
233
    echo "Max particles: ${MAX_PARTICLES}"
234 235
    echo "Min particles: ${MIN_PARTICLES}"
    echo "Number of events: ${N_OF_EVENTS}"
236
    echo "Min Average Z Momentum: ${MIN_AVG_PZ}"
237
    echo "Camera: $CAMERA"
238
    echo "-----------------------------------"
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
    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 "-----------------------------------"

257 258
fi

259 260 261 262 263 264 265
# 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

266 267 268 269
##############################
# Download Dataset           #
##############################
if [ "$DOWNLOAD" = "true" ]; then
270
    if [ -z $URL ]; then
271
        echo "Error. Must pass the dataset URL in order to download ESD file."
272 273 274
        usage
        exit
    fi
275 276 277
    echo "Downloading data."
    wget $URL

278 279 280 281 282 283 284 285 286 287 288 289
    ######################################
    # 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
290

291
##############################
292
# Sample synthetic animation#
293
##############################
294
if [ "$SAMPLE" = "true" ]; then
295
    ##############################
296
    # Phase 1: Blender animate   #
297 298
    ##############################
    pushd ${BLENDER_SCRIPT_DIR}
299
    for type in $CAMERA; do
300
      echo "Preparing sample animation with $type in Blender"
301
      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}
302
    done
303
    popd
304
    BLENDER_OUTPUT=.
305 306 307 308
    mkdir --verbose -p ${BLENDER_OUTPUT}
    mv --verbose /tmp/blender ${BLENDER_OUTPUT}
    echo "Done."

309 310 311
##############################
# Animation from file        #
##############################
312
elif [ "$SAMPLE" = "false" ]; then
313

314
  # Verify if AliESDs.root is here
315 316 317
  ALIESD_ROOT_FILE=$(pwd)/AliESDs.root
  if ! [[ -f "$ALIESD_ROOT_FILE" ]]
  then
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
318 319
      echo "AliESDs.root not found."
      exit
320 321
  fi

322 323 324
  ############################
  # Phase 1: aliroot extract #
  ############################
325
  eval $(alienv -w ${ALIENV_WORK_DIR} -a ${ALIENV_OS_SPEC} load ${ALIENV_ID})
326
  pushd ${ALIROOT_SCRIPT_DIR}
327
  # Remove existing symbolic link
328
  rm -f --verbose AliESDs.root
329 330 331
  # Create a symbolic link to the actual AliESDs.root
  ln --verbose -s ${ALIESD_ROOT_FILE} AliESDs.root
  # Run the extraction tool
332
  aliroot runAnalysis.C
333

334 335 336 337 338 339 340 341 342 343 344 345 346 347
  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

348 349 350
  #################################################
  # Phase 1: iteration for every event identifier #
  #################################################
351

352 353 354
  # Event counter for animating no more events than the informed amount
  EVENT_COUNTER=0

355 356 357 358
  # 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 | \
359 360
                 sed -e "s#esd_detail-event_##" \
                   -e "s#\.dat##")
361 362
      EVENT_UNIQUE_ID=${UNIQUEID}_${EVENT_ID}

363
      if ! [[ -s $FILE_WITH_DATA ]]; then
364
          echo "File $FILE_WITH_DATA has zero size. Ignore and continue."
365
	        rm $FILE_WITH_DATA
366
          continue
367
      fi
368

369 370 371
      ##############################
      # Phase 2: blender animate   #
      ##############################
372 373 374

      LOCAL_FILE_WITH_DATA=${EVENT_UNIQUE_ID}.dat
      cp ${ALIROOT_SCRIPT_DIR}/$FILE_WITH_DATA \
375 376
       ${BLENDER_SCRIPT_DIR}/${LOCAL_FILE_WITH_DATA}

377 378
      rm $FILE_WITH_DATA

379 380
      NUMBER_OF_PARTICLES=$(wc -l ${BLENDER_SCRIPT_DIR}/$LOCAL_FILE_WITH_DATA | \
                        awk '{ print $1 }')
381

382 383 384 385
      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})

      echo "File $LOCAL_FILE_WITH_DATA has $NUMBER_OF_PARTICLES particles and average Z momentum $AVERAGE_PZ"

386 387
      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
388

389 390
          # Increment event counter
          EVENT_COUNTER=$EVENT_COUNTER+1
391

392
          echo "Processing ${EVENT_UNIQUE_ID} ($NUMBER_OF_PARTICLES tracks) in Blender"
393

394
          pushd ${BLENDER_SCRIPT_DIR}
395

396 397
          for type in $CAMERA; do
                echo "Processing ${EVENT_UNIQUE_ID} with $type in Blender"
398

399
                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}
400 401 402 403
                # Move generated file to final location
                mv /tmp/blender/* ${BLENDER_OUTPUT}
                echo "${type} for event ${EVENT_UNIQUE_ID} done."
          done
404

405 406
          # Move processed file to final location
          mv $LOCAL_FILE_WITH_DATA ${BLENDER_OUTPUT}/$LOCAL_FILE_WITH_DATA
407

408 409 410
          popd
          echo "EVENT ${EVENT_UNIQUE_ID} DONE with FILE $LOCAL_FILE_WITH_DATA."
        else
411

412 413 414 415 416 417 418
          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
419

420 421 422 423
          # Remove non-processed files
          pushd ${BLENDER_SCRIPT_DIR}
          rm $LOCAL_FILE_WITH_DATA
          popd
424

425 426 427 428
          continue
        fi
      else
        echo "Average Z Momentum too low (minimum accepted is $MIN_AVG_PZ). Continue."
429 430 431 432 433

        # Remove non-processed files
        pushd ${BLENDER_SCRIPT_DIR}
        rm $LOCAL_FILE_WITH_DATA
        popd
434
      fi
Lucas Mello Schnorr's avatar
Lucas Mello Schnorr committed
435
  done
436
  popd
437

438
fi