2 # example local use (files will be downloaded from alien)
3 #./mergeMakeOCDB.byComponent.sh /alice/data/2012/LHC12g/000188362/cpass0/ 188362 local://./OCDB defaultOCDB=local:///cvmfs/alice.gsi.de/alice/data/2011/OCDB/ fileAccessMethod=tfilecp numberOfFilesInAbunch=30
6 # $1 = directory where to perform the find
13 if [[ $# -eq 0 ]]; then
15 echo " 1 - directory on which to look for the files to be merged or local file list"
17 echo " 3 - OCDB output path"
19 echo " optionally set any of these"
20 echo " runParallel={0,1} (1 to run parallel merging and downloading)"
21 echo " defaultOCDB=raw:// (or any other valid OCDB storage as input database)"
22 echo " fileAccessMethod={alien_cp,tfilecp,nocopy} (by default tfilecp)"
23 echo " \"alien_cp\" will use alien_cp to copy files from alien"
24 echo " \"tfilecp\" will copy the files first using TFile::Cp()"
25 echo " \"nocopy\" will access files over the network directly TFile::Open()"
26 echo " numberOfFilesInAbunch=50 (how many files get downloaded in one go)"
27 echo " maxChunksTPC=3000 (max number of chunks to be merged for TPC calibration)"
31 echo " ./mergeMakeOCDB.byComponent.sh /alice/data/2012/LHC12g/000188362/cpass1/ 188362 local://./OCDB runParallel=0 defaultOCDB=raw:// fileAccessMethod=alien_cp"
39 run=$(echo "$2" | sed 's/^0*//')
47 fileAccessMethod="tfilecp"
48 numberOfFilesInAbunch=50
50 [[ -n ${ALIEN_JDL_TTL} ]] && maxTimeToLive=$(( ${ALIEN_JDL_TTL}-2000 ))
54 #some sanity checks of option values
55 [[ ! $numberOfFilesInAbunch =~ ^[0-9]+$ ]] && numberOfFilesInAbunch=50
56 [[ "$fileAccessMethod" != "alien_cp" && "$fileAccessMethod" != "tfilecp" && "$fileAccessMethod" != "nocopy" ]] && fileAccessMethod="tfilecp" && echo "using default fileAccessMethod=tfilecp"
59 [[ -f $path ]] && filesAreLocal=1
61 [[ $filesAreLocal -eq 1 ]] && cleanup=0
62 [[ $filesAreLocal -eq 1 ]] && fileAccessMethod="nocopy"
64 # setup components to be merged
65 components="TOF MeanVertex T0 SDD TRD TPCCalib TPCCluster TPCAlign"
66 #components="TOF MeanVertex T0 SDD TRD TPCCalib"
68 # take Data Quality Flags from JDL
69 detectorBitsQualityFlag=${ALIEN_JDL_RUNQUALITY--1}
71 #################################################################
72 echo "" | tee -a merge.log
73 echo "$0 ${save_args[*]}" | tee -a merge.log
74 echo "" | tee -a merge.log
75 echo "***********************" | tee -a merge.log
76 echo mergeMakeOCDB.byComponent.sh started | tee -a merge.log
77 echo path = $path | tee -a merge.log
78 echo run = $run | tee -a merge.log
79 echo ocdb = $ocdb | tee -a merge.log
80 echo defaultOCDB = $defaultOCDB | tee -a merge.log
81 echo filesAreLocal = $filesAreLocal | tee -a merge.log
82 echo cleanup = $cleanup | tee -a merge.log
83 echo fileAccessMethod = $fileAccessMethod | tee -a merge.log
84 echo numberOfFilesInAbunch = $numberOfFilesInAbunch | tee -a merge.log
85 echo runParallel = $runParallel
86 echo detectorBitsQualityFlag = $detectorBitsQualityFlag
87 echo "***********************" | tee -a merge.log
89 alienFileList="alien.list"
90 localFileList="local.list"
91 filesProcessedTPClist="filesProcessedTPC.log"
92 rm -f $filesProcessedTPClist
93 touch $filesProcessedTPClist
94 partialLocalFileListPrefix=${localFileList}_
95 partialAlienFileListPrefix=${alienFileList}_
97 #first, make sure we have the scripts
98 copyScripts | tee -a copy.log
100 #with alien files copy them first to local
101 echo "***********************" 2>&1 | tee -a copy.log
102 echo copying files for run $run 2>&1 | tee -a copy.log
103 echo from $path 2>&1 | tee -a copy.log
104 echo "***********************" 2>&1 | tee -a copy.log
105 if [[ $filesAreLocal -eq 0 ]]; then
106 if [[ "$fileAccessMethod" == "alien_cp" ]]; then
107 echo "alien_find $path AliESDfriends_v1.root | egrep ^/ > $alienFileList" 2>&1 | tee -a copy.log
108 alien_find $path "AliESDfriends_v1.root" | egrep "^/" > $alienFileList
109 echo "alien_find done"
112 echo aliroot -b -q "mergeByComponent.C(\"MAKEALIENLIST\",\"$alienFileList\", \"$path\", \"AliESDfriends_v1.root\")" 2>&1 | tee -a copy.log
113 aliroot -b -q "mergeByComponent.C(\"MAKEALIENLIST\",\"$alienFileList\", \"$path\", \"AliESDfriends_v1.root\")" 2>&1 | tee -a copy.log
114 echo "MAKEALIENLIST done"
118 cp $path $alienFileList
121 #keep the first line intact (it is the largest file of the entire collection)
122 sed -n '1p' ${alienFileList} > ${alienFileList}.tmp
123 sed '1d' ${alienFileList} | while read x; do echo "${RANDOM} ${x}"; done|sort -n|cut -d" " -f2- >> ${alienFileList}.tmp
124 mv -f ${alienFileList}.tmp ${alienFileList}
126 #split into sublists, each to be processed separately
127 echo split --numeric-suffixes --suffix-length=6 --lines=$numberOfFilesInAbunch ${alienFileList} ${partialAlienFileListPrefix} | tee -a copy.log
128 #split --numeric-suffixes --suffix-length=6 --lines=$numberOfFilesInAbunch ${alienFileList} ${partialAlienFileListPrefix}
129 split -a 6 -l $numberOfFilesInAbunch ${alienFileList} ${partialAlienFileListPrefix}
131 for partialAlienFileList in ${partialAlienFileListPrefix}*
134 #if it takes too long, break
135 #[[ ${SECONDS} -gt ${maxTimeToLive} ]] && break
137 partialAlienFileListPostfix=${partialAlienFileList#$partialAlienFileListPrefix}
138 partialLocalFileList=${partialLocalFileListPrefix}${partialAlienFileListPostfix}
140 #copy the files if appropriate and make a list of files to use
141 rm -f $partialLocalFileList
142 if [[ "$fileAccessMethod" == "alien_cp" ]]; then
144 [[ $x != /* ]] && continue
145 localName=${x//"/"/_}
146 echo "alien_cp "alien://$x" $localName" 2>&1 | tee -a copy.log
147 alien_cp "alien://$x" $localName
148 echo $localName>>$partialLocalFileList
149 done<$partialAlienFileList
150 elif [[ "$fileAccessMethod" == "tfilecp" ]]; then
151 echo aliroot -b -q "mergeByComponent.C(\"COPY\",\"$partialAlienFileList\",\"noPath\",\"noPattern\",10,\"$partialLocalFileList\")" 2>&1 | tee -a copy.log
152 aliroot -b -q "mergeByComponent.C(\"COPY\",\"$partialAlienFileList\",\"noPath\",\"noPattern\",10,\"$partialLocalFileList\")" 2>&1 | tee -a copy.log
153 elif [[ "$fileAccessMethod" == "nocopy" ]]; then
155 [[ $filesAreLocal -eq 0 ]] && echo "alien://$x" >> $partialLocalFileList
156 [[ $filesAreLocal -eq 1 ]] && echo "$x" >> $partialLocalFileList
157 done<$partialAlienFileList
162 if [[ -f syswatch_copy.log ]]
164 sed '1d' syswatch.log >> syswatch_copy.log
167 [[ -f syswatch.log ]] && mv syswatch.log syswatch_copy.log
172 if [[ $runParallel -eq 1 ]]; then
173 mergeByComponent $partialLocalFileList $cleanup 2>&1 | tee -a merge.log &
175 mergeByComponent $partialLocalFileList $cleanup 2>&1 | tee -a merge.log
179 #merge all the subfiles into one, wait for the last one to complete
182 if [[ "$components" =~ ALL && -f CalibObjects_ALL.root ]]; then
183 mv -f CalibObjects_ALL.root CalibObjects.root
185 echo "***********************"
186 echo merging ALL data
187 echo "***********************"
188 finalCalibObjectsList="finalObjects.list"
189 ls -1 CalibObjects_*.root > $finalCalibObjectsList
190 echo aliroot -b -q "mergeByComponent.C(\"ALL\", \"$finalCalibObjectsList\")" | tee -a merge.log
191 aliroot -b -q "mergeByComponent.C(\"ALL\", \"$finalCalibObjectsList\")" 2>&1 | tee -a merge.log
192 mv -f syswatch.log syswatch_merge_ALL.log
195 if ! validateMerging "ALL"; then
196 echo final merging not validatet, exiting...
199 rm -f CalibObjects_*.root
202 rm -f ${partialAlienFileListPrefix}*
203 rm -f ${partialLocalFileListPrefix}*
208 echo "***********************" 2>&1 | tee -a ocdb.log
209 echo making ${det} OCDB 2>&1 | tee -a ocdb.log
210 echo "***********************" 2>&1 | tee -a ocdb.log
211 echo aliroot -b -q "makeOCDB.C($run, \"$ocdb\", \"$defaultOCDB\", $detectorBitsQualityFlag)" 2>&1 | tee -a ocdb.log
212 aliroot -b -q "makeOCDB.C($run, \"$ocdb\", \"$defaultOCDB\", $detectorBitsQualityFlag)" 2>&1 | tee -a ocdb.log
213 mv syswatch.log syswatch_makeOCDB.log
216 echo "***********************" 2>&1 | tee -a ocdb.log
217 echo SUMMARY 2>&1 | tee -a ocdb.log
218 echo "***********************" 2>&1 | tee -a ocdb.log
219 ls -altr CalibObjects.root *done 2>&1 | tee -a ocdb.log
224 # process by component
225 # first argument is the file list to process
227 # run inside a dedicated running directory
228 # whic means copy the file list to process and prefic each line with ../
229 # since the file names have no absolute paths!
230 runningDirectory="${1}.dir"
235 if [[ ! -f ${fileList} ]]; then
236 echo "${fileList} does not exist"
239 mkdir -p $runningDirectory
240 if [[ ! -d $runningDirectory ]]; then
241 echo "cannot create the running directory $runningDirectory"
245 #move the to be merged files to the running directory and make a list of available files
246 #handle the case of archives (x.zip#y.root) as well
249 if [[ $entry =~ ^.*\.root$ ]]; then
251 fileContent=${entry##*#}
252 [[ "${fileContent}" == "${file}" ]] && fileContent=""
253 [[ -n ${fileContent} ]] && fileContent="#${fileContent}"
254 if [[ -f ${file} ]]; then
256 if [[ -f "./${file}" ]]; then
257 echo "../${file}${fileContent}" >> "${runningDirectory}/${fileList}"
259 echo "${file}${fileContent}" >> "${runningDirectory}/${fileList}"
264 if [[ $nFiles -lt 1 ]]; then
265 echo "no new files in ${fileList}"
266 echo rm -rf $runningDirectory
267 rm -rf $runningDirectory
271 #copy the macro to the running directory
272 [[ -f mergeByComponent.C ]] && cp mergeByComponent.C $runningDirectory
274 #go to running directory
277 numberOfChunksTPC=$(cat ../$filesProcessedTPClist 2>/dev/null | wc -l )
279 for det in $components; do
282 echo "***********************"
283 echo merging ${det} data
284 echo "***********************"
286 #limit the number of chunks processed by TPC
287 if [[ "${det}" =~ TPC && $numberOfChunksTPC -ge $maxChunksTPC ]]; then
288 echo "Not merging TPC anymore, max number of chunks processed ($maxChunksTPC)"
292 #add the results of previous iteration to the BEGINNING of the list of files to be merged
293 [[ -f ../CalibObjects_${det}.root ]] && echo "../CalibObjects_${det}.root" > ${fileList}_${det}
294 cat ${fileList} >> ${fileList}_${det}
296 echo "processing following files from ${fileList}_${det}:"
297 cat ${fileList}_${det}
299 echo aliroot -b -q "mergeByComponent.C(\"${det}\", \"${fileList}_${det}\")"
300 aliroot -b -q "mergeByComponent.C(\"${det}\", \"${fileList}_${det}\")" 2>&1 | tee -a merge_${det}.log
301 if validateMerging ${det}; then
302 echo "### merge OK: mv CalibObjects.root ../CalibObjects_${det}.root"
303 mv -f CalibObjects.root ../CalibObjects_${det}.root
304 [[ "${det}" =~ TPCCalib ]] && cat ${fileList} >> ../$filesProcessedTPClist
306 echo "### merging not validated"
307 rm -f CalibObjects.root
309 mv syswatch.log syswatch_merge_${det}.log
314 #move stuff back to the parent dir and clean up
315 #merge the syswatch logs
316 for x in syswatch*log; do
317 [[ ! -f $x ]] && continue
320 echo "sed '1d' $x >> ../$x"
329 #merge the other logs
331 [[ ! -f $x ]] && continue
334 echo "cat $x >> ../$x"
343 #go to parent dir first to use the original fileList
344 #without ../CalibObjects.root
346 if [[ $cleanup -eq 1 ]]; then
347 echo "cleaning up merged files..."
353 rm -rf $runningDirectory
355 echo "***mergeByComponent() DONE"
357 echo "numberOfChunksTPC=$numberOfChunksTPC"
364 for opt in "${args[@]}"; do
365 [[ -z ${opt} ]] && continue
366 [[ -n ${encodedSpaces} ]] && opt="$(decSpaces ${opt})"
367 [[ "${opt}" =~ ^[[:space:]]*$ ]] && continue
368 if [[ ! "${opt}" =~ .*=.* ]]; then
369 echo "badly formatted option \"${opt}\" should be: option=value, stopping..."
372 local var="${opt%%=*}"
373 local value="${opt#*=}"
374 export ${var}="${value}"
383 [[ ! -f $1 ]] && break
393 [[ ! -f CalibObjects.root ]] && ((retCode++)) && echo "### no CalibObjects.root..."
394 [[ ! -f ${det}_merge_done ]] && ((retCode++)) && echo "### no ${det}_merge_done, job finished abnormally..."
395 error=$(grep -e "was a crash" *.log)
396 [[ -n $error ]] && ((retCode++)) && echo "### error: $error"
403 [[ ! -f mergeByComponent.C ]] && \
404 cp -f $ALICE_ROOT/PWGPP/CalibMacros/CPass1/mergeByComponent.C $PWD && \
405 echo "taking the default scripts from $ALICE_ROOT"
406 [[ ! -f makeOCDB.C ]] && \
407 cp -f $ALICE_ROOT/PWGPP/CalibMacros/CPass1/makeOCDB.C $PWD && \
408 echo "taking the default scripts from $ALICE_ROOT"
411 #these functions encode strings to and from a space-less form
412 #use when spaces are not well handled (e.g. in arguments to
413 #commands in makeflow files, etc.
414 encSpaces()(echo "${1// /@@@@}")
415 decSpaces()(echo "${1//@@@@/ }")